Commit Graph

91 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
jnjpng
85c242077e feat: strict tool calling setting (#8810)
base
2026-01-19 15:54:42 -08:00
cthomas
487bb42231 fix: summarization causing desync for conversations [LET-7014] (#8734) 2026-01-19 15:54:41 -08:00
Sarah Wooders
97cdfb4225 Revert "feat: add strict tool calling setting [LET-6902]" (#8720)
Revert "feat: add strict tool calling setting [LET-6902] (#8577)"

This reverts commit 697c9d0dee6af73ec4d5d98780e2ca7632a69173.
2026-01-19 15:54:39 -08:00
Sarah Wooders
b888c4c17a feat: allow for conversation-level isolation of blocks (#8684)
* 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>

* feat: add isolated blocks support for conversations

Allows conversations to have their own copies of specific memory blocks (e.g., todo_list) that override agent defaults, enabling conversation-specific state isolation.

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

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

* undo

* update apis

* test

* cleanup

* fix tests

* simplify

* move override logic

* patch

---------

Co-authored-by: Letta <noreply@letta.com>
2026-01-19 15:54:39 -08:00
Sarah Wooders
bdede5f90c feat: add strict tool calling setting [LET-6902] (#8577) 2026-01-19 15:54:38 -08:00
Sarah Wooders
87d920782f feat: add conversation and conversation_messages tables for concurrent messaging (#8182) 2026-01-12 10:57:48 -08:00
Sarah Wooders
2d84af11c3 fix: override with client-side tools is overlapping (#8232) 2026-01-12 10:57:48 -08:00
Charles Packer
3cdee2e78f fix: include client_tools in streaming requires_approval_tools (#8230)
When streaming, the LLM adapter needs to know which tools require
approval so it can emit ApprovalRequestMessage instead of ToolCallMessage.
Client-side tools were being passed to the agent but not included in
the requires_approval_tools list passed to the streaming interface.

This caused the streaming interface to emit tool_call_message for
client tools, but the stop_reason was still requires_approval,
resulting in empty approvals arrays on the client side.

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

Co-authored-by: Letta <noreply@letta.com>
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
0722877423 fix: validate parallel tool calls with tool rules at create/update time (#8060)
* fix: validate parallel tool calls with tool rules at create/update time

Move validation from runtime to agent create/update time for better UX.
Add client-side enforcement to truncate parallel tool calls when disabled
(handles providers like Gemini that ignore the setting).

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

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

* update apis

* undo

---------

Co-authored-by: Letta <noreply@letta.com>
2026-01-12 10:57:47 -08:00
Sarah Wooders
6bf5c50f42 fix: fix summarization for claude max plans (#8020)
Co-authored-by: Letta Bot <jinjpeng@gmail.com>
2026-01-12 10:57:44 -08:00
Sarah Wooders
a7639a53eb fix: fix summary message return for compaction (#7402) 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
Sarah Wooders
ae4490c5b3 fix: filter out stop reason from response streaming (#7332) 2025-12-17 17:31:03 -08:00
Sooty
6f48d4bd48 Correct provider name for openai-proxy in LLMConfig (#3097) 2025-12-16 19:37:54 -08:00
Sarah Wooders
bd9f3aca9b fix: fix prompt_acknowledgement usage and update summarization prompts (#7012) 2025-12-15 12:03:09 -08:00
Sarah Wooders
a731e01e88 fix: use model instead of model_settings (#6834) 2025-12-15 12:03:09 -08:00
Kevin Lin
4b9485a484 feat: Add max tokens exceeded to stop reasons [LET-6480] (#6576) 2025-12-15 12:03:09 -08:00
Sarah Wooders
c9ad2fd7c4 chore: move things to debug logging (#6610) 2025-12-15 12:03:09 -08:00
cthomas
bffb9064b8 fix: step logging error (#6755) 2025-12-15 12:03:08 -08:00
Sarah Wooders
7ea297231a feat: add compaction_settings to agents (#6625)
* initial commit

* Add database migration for compaction_settings field

This migration adds the compaction_settings column to the agents table
to support customized summarization configuration for each agent.

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

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

* fix

* rename

* update apis

* fix tests

* update web test

---------

Co-authored-by: Letta <noreply@letta.com>
Co-authored-by: Kian Jones <kian@letta.com>
2025-12-15 12:02:34 -08:00
Sarah Wooders
a2dfa5af17 fix: reorder summarization (#6606) 2025-12-15 12:02:34 -08:00
Sarah Wooders
70c57c5072 fix: various patches to summarizer (#6597) 2025-12-15 12:02:34 -08:00
Sarah Wooders
bbd52e291c feat: refactor summarization and message persistence code [LET-6464] (#6561) 2025-12-15 12:02:34 -08:00
cthomas
2116a07706 fix: incorrect stop reasons (#6539) 2025-12-15 12:02:34 -08:00
cthomas
77d1c3365e fix: granular cancellation check (#6540) 2025-12-15 12:02:34 -08:00
cthomas
b67347dff2 fix: remove redundant letta message conversion (#6538) 2025-12-15 12:02:33 -08:00
cthomas
4916d281ce fix: dont let message ids diverge in memory vs db (#6537) 2025-12-15 12:02:33 -08:00
Sarah Wooders
3569721fd4 fix: avoid infinite summarization loops (#6506) 2025-12-15 12:02:33 -08:00
Sarah Wooders
bd97b23025 feat: fallback to all mode for summarizer if error (#6465) 2025-12-15 12:02:19 -08:00
Sarah Wooders
7fa141273d fix: dont run summarizer if pending approval (#6464) 2025-12-15 12:02:19 -08:00
Sarah Wooders
91e3dd8b3e feat: fix new summarizer code and add more tests (#6461) 2025-12-15 12:02:19 -08:00
Sarah Wooders
f417e53638 fix: fix cancellation issues without making too many changes to message_ids persistence (#6442) 2025-12-15 12:02:19 -08:00
Charles Packer
1f7165afc4 fix: patch counting of tokens for anthropic (#6458)
* fix: patch counting of tokens for anthropic

* fix: patch ui to be simpler

* fix: patch undercounting bug in anthropic when caching is on
2025-12-15 12:02:19 -08:00
Sarah Wooders
1939a9d185 feat: patch summarizer without changes to AgentState (#6450) 2025-12-15 12:02:19 -08:00
cthomas
db534836e4 feat: allow follow up user message for approvals LET-6272 (#6392)
* feat: allow follow up user message for approvals

* add tests
2025-11-26 14:39:40 -08:00
jnjpng
32e4caf0d2 fix: stream return sending full message after yielding chunks (#6295)
base

Co-authored-by: Letta Bot <noreply@letta.com>
2025-11-24 19:10:26 -08:00
cthomas
1be2f61f05 feat: add new letta error message stream response type (#6192) 2025-11-24 19:10:11 -08:00
cthomas
1d71468ab2 feat: don't yield tool return message back in hitl [LET-6012] (#6219)
feat: don't yield tool return message back in hitl
2025-11-24 19:10:11 -08:00
jnjpng
52c9abf39b fix: v1 agent message content for anthropic and usage stats tracking [LET-6199] (#6249)
base

Co-authored-by: Letta Bot <noreply@letta.com>
2025-11-24 19:09:33 -08:00
jnjpng
9ffbfa6d67 feat: base letta v1 agent on temporal (#6208)
* base

* another

* parallel

* update

* rename

* naming

---------

Co-authored-by: Letta Bot <noreply@letta.com>
2025-11-24 19:09:33 -08:00
cthomas
41392cdb8a test: make hitl testing pass (#6188) 2025-11-24 19:09:32 -08:00
Charles Packer
2e721ddc62 fix: various hardening to prevent stale state on background mode runs (#6072)
fix: various hardening to prevent stale state on backgroun
d mode runs
2025-11-13 15:36:56 -08:00
Charles Packer
363a5c1f92 fix: fix poison state from bad approval response (#5979)
* fix: detect and fail on malformed approval responses

* fix: guard against None approvals in utils.py

* fix: add extra warning

* fix: stop silent drops in deserialize_approvals

* fix: patch v3 stream error handling to prevent sending end_turn after an error occurs, and ensures stop_reason is always set when an error occurs

* fix: Prevents infinite client hangs by ensuring a terminal event is ALWAYS sent

* fix:  Ensures terminal events are sent even if inner stream generator fails to
  send them
2025-11-13 15:36:55 -08:00
Sarah Wooders
5b9cac08b6 fix: populate stop_reason [LET-6040] (#5955)
fix: populate stop_reason
2025-11-13 15:36:55 -08:00
Charles Packer
52ff51755c fix: move persistence on message_ids to prevent desync [LET-6011] (#5908)
fix: move persistence on message_ids to prevent desync
2025-11-13 15:36:39 -08:00
Charles Packer
468b47bef5 fix(core): patch sse streaming errors (#5906)
* fix: patch sse streaming errors

* fix: don't re-raise, but log explicitly with sentry

* chore: cleanup comments

* fix: revert change from #5907, also make sure to write out a [DONE] to close the stream
2025-11-13 15:36:39 -08:00
Sarah Wooders
ac599145bb fix: various fixes for runs (#5907)
* Fix agent loop continuing after cancellation in letta_agent_v3

Bug: When a run is cancelled, _check_run_cancellation() sets
self.should_continue=False and returns early from _step(), but the outer
for loop (line 245) continues to the next iteration, executing subsequent
steps even though cancellation was requested.

Symptom: User hits cancel during step 1, backend marks run as cancelled,
but agent continues executing steps 2, 3, etc.

Root cause: After the 'async for chunk in response' loop completes (line 255),
there was no check of self.should_continue before continuing to the next
iteration of the outer step loop.

Fix: Added 'if not self.should_continue: break' check after the inner loop
to exit the outer step loop when cancellation is detected. This makes v3
consistent with v2 which already had this check (line 306-307).

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

Co-authored-by: Letta <noreply@letta.com>

* add integration tests

* passing tests

* fix: minor patches

* undo

---------

Co-authored-by: cpacker <packercharles@gmail.com>
Co-authored-by: Letta <noreply@letta.com>
2025-11-13 15:36:39 -08:00
Charles Packer
a6077f3927 fix(core): Fix agent loop continuing after cancellation in letta_agent_v3 [LET-6006] (#5905)
* Fix agent loop continuing after cancellation in letta_agent_v3

Bug: When a run is cancelled, _check_run_cancellation() sets
self.should_continue=False and returns early from _step(), but the outer
for loop (line 245) continues to the next iteration, executing subsequent
steps even though cancellation was requested.

Symptom: User hits cancel during step 1, backend marks run as cancelled,
but agent continues executing steps 2, 3, etc.

Root cause: After the 'async for chunk in response' loop completes (line 255),
there was no check of self.should_continue before continuing to the next
iteration of the outer step loop.

Fix: Added 'if not self.should_continue: break' check after the inner loop
to exit the outer step loop when cancellation is detected. This makes v3
consistent with v2 which already had this check (line 306-307).

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

Co-authored-by: Letta <noreply@letta.com>

* add integration tests

* fix: misc fixes required to get cancellations to work on letta code localhost

---------

Co-authored-by: Letta <noreply@letta.com>
Co-authored-by: Sarah Wooders <sarahwooders@gmail.com>
2025-11-13 15:36:39 -08:00