Commit Graph

255 Commits

Author SHA1 Message Date
jnjpng
a98bc31bf3 fix: refactor enable strict mode for structured output (#8840)
* base

* test
2026-01-19 15:54:42 -08:00
jnjpng
85c242077e feat: strict tool calling setting (#8810)
base
2026-01-19 15:54:42 -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
ea36633cd5 fix: make sure structured outputs turned on for openai (#8669) 2026-01-19 15:54:38 -08:00
Sarah Wooders
bdede5f90c feat: add strict tool calling setting [LET-6902] (#8577) 2026-01-19 15:54:38 -08:00
cthomas
870c5955d9 fix: wrap tpuf operations in thread pool (#8615)
* fix: wrap turbopuffer vector writes in thread pool

Turbopuffer library does CPU-intensive base64 encoding of vectors
synchronously in async functions (_async_transform_recursive →
b64encode_vector), blocking the event loop during file uploads.

Solution: Created _run_turbopuffer_write_in_thread() helper that runs
turbopuffer writes in an isolated event loop within a worker thread.

Applied to all vector write operations:
- insert_tools()
- insert_archival_memories()
- insert_messages()
- insert_file_passages()

This prevents pybase64.b64encode_as_string() from blocking the main
event loop during vector encoding.

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

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

* fix: wrap all turbopuffer operations in thread pool

Extended the thread pool wrapping to ALL turbopuffer write operations,
including delete operations, for complete isolation from the main event loop.

All turbopuffer namespace.write() calls now run in isolated event loops
within worker threads, preventing any potential CPU work from blocking.

🐾 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:37 -08:00
Ari Webb
cdca1a564f fix: conversation id not found in tpuf (#8469)
* fix: conversation id not found in tpuf

* add tests
2026-01-12 10:57:49 -08:00
jnjpng
28839f5180 fix: import cryptography default backend at top level (#8444)
* base

* comment
2026-01-12 10:57:49 -08:00
Sarah Wooders
6fddcc0c57 fix: fix agent loop (#8401) 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
jnjpng
d55fd69b7b chore: add comment and test for changing PBKDF2 iteration count (#8366)
base
2026-01-12 10:57:48 -08:00
jnjpng
b68e4e74f9 fix: replace cryptography with hashlib for encryption key derivation (#8364)
base
2026-01-12 10:57:48 -08:00
cthomas
a54513c343 feat: move decryption outside db session (#8323)
* feat: move decryption outside db session

* fix pydantic error
2026-01-12 10:57:48 -08:00
jnjpng
7e8088adc5 chore: add tracing for request middleware (#8142)
* base

* update

* more
2026-01-12 10:57:47 -08:00
cthomas
a7b3f469ac fix: more user friendly error for tpuf namespace not found [LET-6707] (#8141)
fix: more user friendly error for tpuf namespace not found
2026-01-12 10:57:47 -08:00
cthomas
39dc1d9736 fix: image fetching timeouts [LET-6700] (#8140)
fix: image fetching timeouts
2026-01-12 10:57:47 -08:00
jnjpng
700409d943 fix: sanitize null bytes test (#8135)
base
2026-01-12 10:57:47 -08:00
jnjpng
fa9a98351d fix: add redis tracing (#8132)
base
2026-01-12 10:57:47 -08:00
github-actions[bot]
dbdd1a40e4 fix: sanitize null bytes to prevent PostgreSQL CharacterNotInRepertoireError (#8015)
This fixes the asyncpg.exceptions.CharacterNotInRepertoireError that occurs
when tool returns contain null bytes (0x00), which PostgreSQL TEXT columns
reject in UTF-8 encoding.

Changes:
- Add sanitize_null_bytes() function to recursively remove null bytes from strings
- Update json_dumps() to sanitize data before serialization
- Apply sanitization in converters.py for tool_calls, tool_returns, approvals, and message_content
- Add comprehensive unit tests

Fixes #8014

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

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Letta <noreply@letta.com>
Co-authored-by: Kian Jones <11655409+kianjones9@users.noreply.github.com>
2026-01-12 10:57:47 -08:00
Kian Jones
bce1749408 fix: run PBKDF2 in thread pool to prevent event loop freeze (#6763)
* fix: run PBKDF2 in thread pool to prevent event loop freeze

Problem: Event loop freezes for 100-500ms during secret decryption, blocking
all HTTP requests and async operations. The diagnostic monitor detected the
main thread stuck in PBKDF2 HMAC SHA256 computation at:
  apps/core/letta/helpers/crypto_utils.py:51 (_derive_key)
  apps/core/letta/schemas/secret.py:161 (get_plaintext)

Root cause: PBKDF2 with 100k iterations is intentionally CPU-intensive for
security, but running it synchronously on the main thread blocks the event loop.

Stack trace showed:
  Thread 1 (Main): PBKDF2HMAC -> SHA256_Final -> sha256_block_data_order_avx2
  Event loop watchdog: Detected freeze at 01:11:44 (request started 01:12:03)

Solution:
1. Run PBKDF2 in ThreadPoolExecutor to avoid blocking event loop
2. Add async versions of encrypt/decrypt methods
3. Add LRU cache for derived keys (deterministic results)
4. Add async get_plaintext_async() method to Secret class

Changes:
- apps/core/letta/helpers/crypto_utils.py:
  - Added ThreadPoolExecutor for crypto operations
  - Added @lru_cache(maxsize=256) to _derive_key_cached()
  - Added _derive_key_async() using loop.run_in_executor()
  - Added encrypt_async() and decrypt_async() methods
  - Added warnings to sync methods about blocking behavior

- apps/core/letta/schemas/secret.py:
  - Added get_plaintext_async() method
  - Added warnings to get_plaintext() about blocking behavior

Benefits:
- Event loop no longer freezes during secret decryption
- HTTP requests continue processing while crypto runs in background
- Derived keys are cached, reducing CPU usage for repeated operations
- Backward compatible - sync methods still work for non-async code

Performance impact:
- Before: 100-500ms event loop block per decryption
- After: 100-500ms in thread pool (non-blocking) + LRU cache hits ~0.1ms

Next steps (follow-up PRs):
- Migrate all async callsites to use get_plaintext_async()
- Add metrics to track sync vs async usage
- Consider reducing PBKDF2 iterations if security allows

* update

* test

---------

Co-authored-by: Letta Bot <jinjpeng@gmail.com>
2025-12-15 12:03:09 -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
jnjpng
17a90538ca fix: exclude common API key prefixes from encryption detection (#6624)
* fix: exclude common API key prefixes from encryption detection

Add a list of known API key prefixes (OpenAI, Anthropic, GitHub, AWS,
Slack, etc.) to prevent is_encrypted() from incorrectly identifying
plaintext credentials as encrypted values.

* update

* test
2025-12-15 12:02:34 -08:00
Christina Tong
972c61d0b8 chore: fallback to timestamp retrieval for message search [LET-6429] (#6510) 2025-12-15 12:02:33 -08:00
Ari Webb
4d5be22d14 fix: utc for message/passage search tpuf [LET-6109] (#6429)
fix: utc for message/passage search tpuf

Co-authored-by: Ari Webb <ari@letta.com>
2025-12-15 12:02:18 -08:00
Ari Webb
3e02f12dfd feat: add tool embedding and search [LET-6333] (#6398)
* feat: add tool embedding and search

* fix ci

* add env variable for embedding tools

---------

Co-authored-by: Ari Webb <ari@letta.com>
2025-11-26 14:39:40 -08:00
cthomas
29e38a2a42 feat: pass in user-agent to prevent 403 forbidden http error [LET-6305] (#6348)
feat: pass in user-agent to prevent 403 forbidden http error
2025-11-24 19:10:27 -08:00
cthomas
345ea42630 feat: offload all file i/o in server endpoints LET-6252 (#6300)
feat: offload all file i/o in server endpoints
2025-11-24 19:10:26 -08:00
cthomas
4bb116f17c fix: sync api call in message path (#6291)
* fix: sync api call in message path

* remove unused function

* add new error type
2025-11-24 19:10:26 -08:00
cthomas
1b05ecb842 fix: invalid role error in agent step (#6288) 2025-11-24 19:10:26 -08:00
cthomas
6f810d95d8 feat: add semaphore to limit embeddings creation (#6261) 2025-11-24 19:10:11 -08:00
Christina Tong
04611b981c feat: filter messages search endpoint by agent id [LET-6229] (#6246)
* feat: filter messages search endpoint by agent id [LET-6229]

* add autogenerated schema/types
2025-11-24 19:09:33 -08:00
cthomas
209debeb09 feat: remove multiple pinecone client inits from startup (#6128)
feat: remove multiple pinecone client inits
2025-11-13 15:36:56 -08:00
Sarah Wooders
5730f69ecf feat: modal tool execution - NO FEATURE FLAGS USES MODAL [LET-4357] (#5120)
* initial commit

* add delay to deploy

* fix tests

* add tests

* passing tests

* cleanup

* and use modal

* working on modal

* gate on tool metadata

* agent state

* cleanup

---------

Co-authored-by: Letta Bot <noreply@letta.com>
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
jnjpng
05b359b7f5 chore: add local base 64 url image for send message integration (#5969)
* base

* update

* clean up

* update

---------

Co-authored-by: Letta Bot <noreply@letta.com>
2025-11-13 15:36:55 -08:00
Ari Webb
c7c0d7507c feat: add new mcp_servers routes [LET-4321] (#5675)
---------

Co-authored-by: Ari Webb <ari@letta.com>
Co-authored-by: Sarah Wooders <sarahwooders@gmail.com>
2025-10-24 15:14:21 -07:00
cthomas
73dcc0d4b7 feat: latest hitl + parallel tool call changes (#5565) 2025-10-24 15:12:49 -07:00
Kian Jones
4bbd760204 feat: add validation to fastapi routes for agent IDs (#5454)
* change my PR to match Caren's

* add path parameter validation for agent id first

* remove old import

* remove old agent_id_pattern pattern

* add example and fix max/min calculation to include hyphen

* fix regex string interpolation

* example deprecated in favour of examples

* openapi autogen

* change template test to expect 422

* fix 422 swallow

* expect 422 or 400

* rewrite  error codes

* fix hallucinated uuid

* tweaked error message test

* print docker logs on failure
2025-10-24 15:12:11 -07:00
Kian Jones
158546414d fix: better error message for llm on agent failure (#5402)
* better error message for llm on agent failure

* raise NoResultFoundError instead of value error and do it outside async db registry
2025-10-24 15:11:31 -07:00
jnjpng
7cac9a1a3e chore: update encryption key log line [LET-5474] (#5393)
update log

Co-authored-by: Letta Bot <noreply@letta.com>
2025-10-24 15:11:31 -07:00
cthomas
6fd6232992 feat: add discriminator type to message return objects (#5318) 2025-10-24 15:11:31 -07:00
cthomas
207ef28fd9 fix: serialized approvals (#5312) 2025-10-24 15:11:31 -07:00
cthomas
1c80e1c11f feat: add approvals persistence to message orm (#5309)
* feat: add approvals persistence to message orm

* fix imports in alembic migration

* missing import
2025-10-24 15:11:31 -07:00
Caren Thomas
a5354d7534 chore: bump version 0.11.8 2025-10-07 18:31:26 -07:00
Sarah Wooders
e07a589796 chore: rm composio (#5151) 2025-10-07 17:50:49 -07:00
Sarah Wooders
ef07e03ee3 feat: add run_id to input messages and step_id to messages (#5099) 2025-10-07 17:50:48 -07:00
Matthew Zhou
b5e848ff18 feat: Implement child tool rules args override [LET-4570] (#5060)
* Implement child tool rules args override

* Add zod types

* Run fern autogen and put ToolCallNode in new field

* Fix test_tool_rule_solver.py

* Fix types

* Fix types again

* Add tests to tool rule solver
2025-10-07 17:50:48 -07:00
Matthew Zhou
803b837c64 feat: Support pre-filling arguments on InitToolRule [LET-4569] (#5057)
* Add args

* Add testing to tool rule solver

* Add live integration tests for args prefilling

* Add args override
2025-10-07 17:50:48 -07:00
Matthew Zhou
bc2218b0ca feat: Add should_force_tool_call to tool rule solver (#5032)
Add  to tool rule solver
2025-10-07 17:50:47 -07:00
Charles Packer
a4041879a4 feat: add new agent loop (squash rebase of OSS PR) (#4815)
* feat: squash rebase of OSS PR

* fix: revert changes that weren't on manual rebase

* fix: caught another one

* fix: disable force

* chore: drop print

* fix: just stage-api && just publish-api

* fix: make agent_type consistently an arg in the client

* fix: patch multi-modal support

* chore: put in todo stub

* fix: disable hardcoding for tests

* fix: patch validate agent sync (#4882)

patch validate agent sync

* fix: strip bad merge diff

* fix: revert unrelated diff

* fix: react_v2 naming -> letta_v1 naming

* fix: strip bad merge

---------

Co-authored-by: Kevin Lin <klin5061@gmail.com>
2025-10-07 17:50:45 -07:00