Commit Graph

1314 Commits

Author SHA1 Message Date
Kian Jones
a92e868ee6 feat: centralize telemetry logging at LLM client level (#8815)
* feat: centralize telemetry logging at LLM client level

Moves telemetry logging from individual adapters to LLMClientBase:
- Add TelemetryStreamWrapper for streaming telemetry on stream close
- Add request_async_with_telemetry() for non-streaming requests
- Add stream_async_with_telemetry() for streaming requests
- Add set_telemetry_context() to configure agent_id, run_id, step_id

Updates adapters and agents to use new pattern:
- LettaLLMAdapter now accepts agent_id/run_id in constructor
- Adapters call set_telemetry_context() before LLM requests
- Removes duplicate telemetry logging from adapters
- Enriches traces with agent_id, run_id, call_type metadata

🐙 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* fix: accumulate streaming response content for telemetry

TelemetryStreamWrapper now extracts actual response data from chunks:
- Content text (concatenated from deltas)
- Tool calls (id, name, arguments)
- Model name, finish reason, usage stats

🐙 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* refactor: move streaming telemetry to caller (option 3)

- Remove TelemetryStreamWrapper class
- Add log_provider_trace_async() helper to LLMClientBase
- stream_async_with_telemetry() now just returns raw stream
- Callers log telemetry after processing with rich interface data

Updated callers:
- summarizer.py: logs content + usage after stream processing
- letta_agent.py: logs tool_call, reasoning, model, usage

🐙 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* fix: pass agent_id and run_id to parent adapter class

LettaLLMStreamAdapter was not passing agent_id/run_id to parent,
causing "unexpected keyword argument" errors.

🐙 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

---------

Co-authored-by: Letta <noreply@letta.com>
2026-01-19 15:54:43 -08:00
Kian Jones
9418ab9815 feat: add provider trace backend abstraction for multi-backend telemetry (#8814)
* feat: add provider trace backend abstraction for multi-backend telemetry

Introduces a pluggable backend system for provider traces:
- Base class with async/sync create and read interfaces
- PostgreSQL backend (existing behavior)
- ClickHouse backend (via OTEL instrumentation)
- Socket backend (writes to Unix socket for crouton sidecar)
- Factory for instantiating backends from config

Refactors TelemetryManager to use backends with support for:
- Multi-backend writes (concurrent via asyncio.gather)
- Primary backend for reads (first in config list)
- Graceful error handling per backend

Config: LETTA_TELEMETRY_PROVIDER_TRACE_BACKEND (comma-separated)
Example: "postgres,socket" for dual-write to Postgres and crouton

🐙 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* feat: add protocol version to socket backend records

Adds PROTOCOL_VERSION constant to socket backend:
- Included in every telemetry record sent to crouton
- Must match ProtocolVersion in apps/crouton/main.go
- Enables crouton to detect and reject incompatible messages

🐙 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* fix: remove organization_id from ProviderTraceCreate calls

The organization_id is now handled via the actor parameter in the
telemetry manager, not through ProviderTraceCreate schema. This fixes
validation errors after changing ProviderTraceCreate to inherit from
BaseProviderTrace which forbids extra fields.

🐙 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* consolidate provider trace

* add clickhouse-connect to fix bug on main lmao

* auto generated sdk changes, and deployment details, and clikchouse prefix bug and added fields to runs trace return api

* auto generated sdk changes, and deployment details, and clikchouse prefix bug and added fields to runs trace return api

* consolidate provider trace

* consolidate provider trace bug fix

---------

Co-authored-by: Letta <noreply@letta.com>
2026-01-19 15:54:43 -08:00
Sarah Wooders
5c7bed7743 feat: add conversation_id to export export and compact (#8792) 2026-01-19 15:54:43 -08:00
jnjpng
5017cb1d12 feat: add chatgpt oauth client for codex routing (#8774)
* base

* refresh

* use default model fallback

* patch

* streaming

* generate
2026-01-19 15:54:42 -08:00
Ari Webb
193c0e4b74 feat: add override_model to message endpoints (#8763)
* feat: add override_model to message endpoints

* add tests back

* remove from ci
2026-01-19 15:54:42 -08:00
Kian Jones
d2c3350a7e feat(runs): add run ID filter to runs page (#8726)
feat(core): add run_id filter to internal runs endpoint

Adds the ability to filter runs by a specific run ID in the
internal runs list endpoint.

🐛 Generated with [Letta Code](https://letta.com)

Co-authored-by: Letta <noreply@letta.com>
2026-01-19 15:54:42 -08:00
Charles Packer
97f7e95d1d feat: add PATCH route for updating conversation summary (#8322) 2026-01-19 15:54:41 -08:00
Sarah Wooders
f91e77d971 fix: add cancel for conversations to SDK (#8742) 2026-01-19 15:54:41 -08:00
jnjpng
58a5375c19 fix: test sdk client due to message batch route ordering (#8733)
* base

* generate
2026-01-19 15:54:40 -08:00
Sarah Wooders
aabd58628e feat: add conversation cancellation endpoint (#8729) 2026-01-19 15:54:40 -08:00
jnjpng
037c20ae1b feat: query param parity for conversation messages (#8730)
* base

* add tests

* generate
2026-01-19 15:54:40 -08:00
Sarah Wooders
9aac2abdfe chore: deprecate identities/groups APIs and remove from SDK (#8580)
* chore: deprecate identities/groups APIs and remove from SDK

- Mark all /v1/identities/* endpoints as deprecated
- Mark all /v1/groups/* endpoints as deprecated
- Remove identities, groups, and batches resources from stainless.yml
- Batch API remains active but hidden from SDK

👾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* chore: update autogenerated SDK files

* chore: regenerate SDK and OpenAPI spec

Run `just stage-api` and `just publish-api` to sync generated files.

👾 Generated with [Letta Code](https://letta.com)

Co-authored-by: Sarah Wooders <sarahwooders@users.noreply.github.com>

* chore: remove schedule API from stainless SDK

Remove schedule subresource from stainless.yml to hide scheduled messages
endpoints from the SDK generation.

👾 Generated with [Letta Code](https://letta.com)

Co-authored-by: Sarah Wooders <sarahwooders@users.noreply.github.com>

---------

Co-authored-by: Letta <noreply@letta.com>
Co-authored-by: letta-code <248085862+letta-code@users.noreply.github.com>
Co-authored-by: Sarah Wooders <sarahwooders@users.noreply.github.com>
2026-01-19 15:54:40 -08:00
jnjpng
e3e758a8c0 feat: add retrieve message endpoint and to client sdk (#8719)
* base

* generate openapi

* try again

* now
2026-01-19 15:54:40 -08:00
Kian Jones
3eae81cf62 feat: add /v1/runs/{run_id}/trace endpoint for OTEL traces (#8682)
* feat: add /v1/runs/{run_id}/trace endpoint for OTEL traces

- Add new endpoint to retrieve filtered OTEL spans for a run
- Filter to only return UI-relevant spans (agent_step, tool executions, root span, TTFT)
- Skip Postgres writes when ClickHouse is enabled for provider traces
- Add USE_CLICKHOUSE_FOR_PROVIDER_TRACES env var to helm/justfile
- Move typecheck CI to self-hosted runners

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* fix: add missing clickhouse_provider_traces.py

The telemetry_manager.py imports ClickhouseProviderTraceReader from
this module, but the file was not included when splitting the PR.

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* autogen

* fix: add trace.retrieve to stainless.yml for SDK generation

Adds the runs.trace.retrieve method mapping so Stainless generates
the useRunsServiceRetrieveTraceForRun hook.

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

---------

Co-authored-by: Letta <noreply@letta.com>
2026-01-19 15:54:39 -08:00
Sarah Wooders
9c4f191755 feat: add conversation_id parameter to context endpoint [LET-6989] (#8678)
* feat: add conversation_id parameter to context endpoint [LET-6989]

Add optional conversation_id query parameter to retrieve_agent_context_window.
When provided, the endpoint uses messages from the specific conversation
instead of the agent's default message_ids.

👾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* chore: regenerate SDK after context endpoint update [LET-6989]

👾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

---------

Co-authored-by: Letta <noreply@letta.com>
2026-01-19 15:54:39 -08:00
jnjpng
979062114c chore: fix typo and improve MCP OAuth comments (#8629)
- Fix typo "upate" -> "update" in TODO comments (mcp_manager.py, mcp_server_manager.py)
- Improve comments in OAuth callback handler to explain why MCPOAuthSession
  is used directly (callback is unauthenticated, manager requires actor)
- Clean up variable naming in callback handler

🐾 Generated with [Letta Code](https://letta.com)

Co-authored-by: Letta <noreply@letta.com>
2026-01-19 15:54:38 -08:00
cthomas
ab4ccfca31 feat: add tags support to blocks (#8474)
* feat: add tags support to blocks

* fix: add timestamps and org scoping to blocks_tags

Addresses PR feedback:

1. Migration: Added timestamps (created_at, updated_at), soft delete
   (is_deleted), audit fields (_created_by_id, _last_updated_by_id),
   and organization_id to blocks_tags table for filtering support.
   Follows SQLite baseline pattern (composite PK of block_id+tag, no
   separate id column) to avoid insert failures.

2. ORM: Relationship already correct with lazy="raise" to prevent
   implicit joins and passive_deletes=True for efficient CASCADE deletes.

3. Schema: Changed normalize_tags() from Any to dict for type safety.

4. SQLite: Added blocks_tags to SQLite baseline schema to prevent
   table-not-found errors.

5. Code: Updated all tag row inserts to include organization_id.

🐾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* fix: add ORM columns and update SQLite baseline for blocks_tags

Fixes test failures (CompileError: Unconsumed column names: organization_id):

1. ORM: Added organization_id, timestamps, audit fields to BlocksTags
   ORM model to match database schema from migrations.

2. SQLite baseline: Added full column set to blocks_tags (organization_id,
   timestamps, audit fields) to match PostgreSQL schema.

3. Test: Added 'tags' to expected Block schema fields.

This ensures SQLite and PostgreSQL have matching schemas and the ORM
can consume all columns that the code inserts.

🐾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* revert change to existing alembic migration

* fix: remove passive_deletes and SQLite support for blocks_tags

1. Removed passive_deletes=True from Block.tags relationship to match
   AgentsTags pattern (neither have ondelete CASCADE in DB schema).

2. Removed SQLite branch from _replace_block_pivot_rows_async since
   blocks_tags table is PostgreSQL-only (migration skips SQLite).

🐾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* api sync

---------

Co-authored-by: Letta <noreply@letta.com>
2026-01-19 15:54:38 -08:00
jnjpng
c550457b60 feat: static redirect callback for mcp server oauth (#8611)
* base

* base

* more

* final

* remove

* pass
2026-01-19 15:54:38 -08:00
Sarah Wooders
b8a6496acb feat: add runs_metrics table (#5169) 2026-01-19 15:51:30 -08:00
cthomas
03a64993cf fix: make file reads async (#8513) 2026-01-12 10:57:49 -08:00
jnjpng
87e939deda feat: add fastmcp v2 client (#8457)
* base

* testing code

* update

* nit
2026-01-12 10:57:49 -08:00
Christina Tong
318498bde3 feat: filter internal runs endpoint by conversation id [LET-6886] (#8437) 2026-01-12 10:57:49 -08:00
Ari Webb
754e750cc5 feat: add conversation_id filter to list runs [LET-6865] (#8404)
feat: add conversation_id filter to list runs
2026-01-12 10:57:48 -08:00
Charles Packer
ed6284cedb feat: Add conversation_id filtering to message endpoints (#8324)
* feat: Add conversation_id filtering to message list and search endpoints

Add optional conversation_id parameter to filter messages by conversation:
- client.agents.messages.list
- client.messages.list
- client.messages.search

Changes:
- Added conversation_id field to MessageSearchRequest and SearchAllMessagesRequest schemas
- Added conversation_id filtering to list_messages in message_manager.py
- Updated get_agent_recall_async and get_all_messages_recall_async in server.py
- Added conversation_id query parameter to router endpoints
- Updated Turbopuffer client to support conversation_id filtering in searches

Fixes #8320

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Charles Packer <cpacker@users.noreply.github.com>

* add conversation_id to message and tpuf

* default messages filter for backward compatibility

* add test and auto gen

* fix integration test

* fix test

* update test

---------

Co-authored-by: letta-code <248085862+letta-code@users.noreply.github.com>
Co-authored-by: Charles Packer <cpacker@users.noreply.github.com>
Co-authored-by: christinatong01 <christina@letta.com>
2026-01-12 10:57:48 -08:00
cthomas
5857b97c7f fix: unbound local variable (#8346) 2026-01-12 10:57:48 -08:00
Sarah Wooders
18a1a16bf4 Revert "feat: add message_types filter to list messages endpoint" (#8314)
Revert "feat: add message_types filter to list messages endpoint (#8280)"

This reverts commit e7ac5df721ec4b3e663dd30239f590ee16bb8630.
2026-01-12 10:57:48 -08:00
Ari Webb
02f3e3f3b9 fix: fix providers and models persistence (#8302) 2026-01-12 10:57:48 -08:00
Charles Packer
e57adc0a6e chore: mark agent.messages.stream endpoint as deprecated (#8227) 2026-01-12 10:57:48 -08:00
Cameron
7c44375cce feat: add message_types filter to list messages endpoint (#8280)
* feat: add message_types filter to list messages endpoint

Add the ability to filter messages by type when listing message history
via GET /v1/agents/{agent_id}/messages. This brings parity with the
create message endpoint which already supports include_return_message_types.

Changes:
- Add message_types query parameter to list_messages endpoint in agents.py
- Add message_types parameter to get_agent_recall_async in server.py
- Filter messages by message_type after LettaMessage conversion
- Add test for message_types filtering

Closes #8277

Written by Cameron ◯ Letta Code

> "Simplicity is the ultimate sophistication." - Leonardo da Vinci

🐙 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* chore: regenerate OpenAPI spec and SDK for message_types filter

🐧 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

Written by Cameron ◯ Letta Code

"The only way to do great work is to love what you do." - Steve Jobs

---------

Co-authored-by: Letta <noreply@letta.com>
2026-01-12 10:57:48 -08:00
Sarah Wooders
87d920782f feat: add conversation and conversation_messages tables for concurrent messaging (#8182) 2026-01-12 10:57:48 -08:00
cthomas
cfde955313 feat: prevent unbounded file queries (#8285) 2026-01-12 10:57:48 -08:00
Charles Packer
64a1a8b14e feat: expose agent_id to the messages search api endpoint (#8252) 2026-01-12 10:57:48 -08:00
Sarah Wooders
7669896184 feat: allow client-side tools to be specified in request (#8220)
* feat: allow client-side tools to be specified in request

Add `client_tools` field to LettaRequest to allow passing tool schemas
at message creation time without requiring server-side registration.
When the agent calls a client-side tool, execution pauses with
stop_reason=requires_approval for the client to provide tool returns.

- Add ClientToolSchema class for request-level tool schemas
- Merge client tools with agent tools in _get_valid_tools()
- Treat client-side tool calls as requiring approval
- Add integration tests for client-side tools flow

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* test: add comprehensive end-to-end test for client-side tools

Update integration test to verify the complete flow:
- Agent calls client-side tool and pauses
- Client provides tool return with secret code
- Agent processes and responds
- User asks about the code, agent recalls it
- Validate full conversation history makes sense

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* update apis

* fix: client-side tools schema format and test assertions

- Use flat schema format for client tools (matching t.json_schema)
- Support both object and dict access for client tools
- Fix stop_reason assertions to access .stop_reason attribute

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* refactor: simplify client_tools access pattern

ClientToolSchema objects always have .name attribute

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* fix: add client_tools parameter to LettaAgentV2 for API compatibility

V2 agent doesn't use client_tools but needs the parameter
to match the base class signature.

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* revert: remove client_tools from LettaRequestConfig

Client-side tools don't work with background jobs since
there's no client present to provide tool returns.

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* fix: add client_tools parameter to SleeptimeMultiAgent classes

Add client_tools to step() and stream() methods in:
- SleeptimeMultiAgentV3
- SleeptimeMultiAgentV4

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* chore: regenerate API specs for client_tools support

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

---------

Co-authored-by: Letta <noreply@letta.com>
2026-01-12 10:57:48 -08:00
Sarah Wooders
6eccd2025d fix: dont return 500 from cancellation endpoint (#8004) 2026-01-12 10:57:20 -08:00
Ari Webb
cd45212acb feat: add zai provider support (#7626)
* feat: add zai provider support

* add zai_api_key secret to deploy-core

* add to justfile

* add testing, provider integration skill

* enable zai key

* fix zai test

* clean up skill a little

* small changes
2026-01-12 10:57:19 -08:00
Ari Webb
cb283373b7 feat: add retrieve_file endpoint to get file content [LET-6188] (#7485)
* feat: add retrieve_file endpoint to get file content

* Restore package-lock.json to main
2026-01-12 10:57:19 -08:00
Sarah Wooders
c675c289ef feat: add more summary logging (#7405) 2026-01-12 10:57:19 -08:00
Sarah Wooders
a7639a53eb fix: fix summary message return for compaction (#7402) 2026-01-12 10:57:19 -08:00
Sarah Wooders
3f3e54d937 feat: add compaction response (#7389) 2026-01-12 10:57:19 -08:00
Sarah Wooders
f9f1b1e82d feat: allow for configuration compaction and return message delta (#7378) 2026-01-12 10:57:19 -08:00
cthomas
7dfdbc5a80 feat: enable agent override for proxy (#7231) 2025-12-17 17:31:03 -08:00
jnjpng
350f3a751c fix: update more plaintext non async callsites (#7223)
* bae

* update

* fix

* clean up

* last
2025-12-17 17:31:02 -08:00
jnjpng
25d75d6528 fix: update aysnc get plaintext callsites (#7069)
* base

* resolve

* fix

* fix
2025-12-17 17:31:02 -08:00
cthomas
9bc872a350 fix: add gen tool error handling (#7209) 2025-12-17 17:31:02 -08:00
cthomas
6de4f0f437 feat: filter out policy system messages for proxy (#7205) 2025-12-17 17:31:02 -08:00
Sarah Wooders
a721a00899 feat: add agent_id to search results (#6867) 2025-12-15 12:03:09 -08:00
cthomas
efac48e9ea feat: add zai proxy LET-6543 (#6836)
feat: add zai proxy
2025-12-15 12:03:09 -08:00
cthomas
22b9ed254a feat: skip persisting redundant messages for proxy (#6819) 2025-12-15 12:03:09 -08:00
cthomas
fd8e471b2e chore: improve logging for proxy (#6754) 2025-12-15 12:03:08 -08:00
cthomas
2dac75a223 fix: remove project id before proxying (#6750) 2025-12-15 12:03:08 -08:00