Commit Graph

269 Commits

Author SHA1 Message Date
Sarah Wooders
526da4c49b Revert "perf: optimize prefix caching by skipping system prompt rebuild on every step" (#9380)
Revert "perf: optimize prefix caching by skipping system prompt rebuild on ev…"

This reverts commit eafa4144c2577a45b7007a177b701863b98d1dfa.
2026-02-24 10:52:07 -08:00
Sarah Wooders
9dbe28e8f1 perf: optimize prefix caching by skipping system prompt rebuild on every step (#9080) 2026-02-24 10:52:07 -08:00
Charles Packer
f58c4a43fa fix(core): remove "edit again if necessary" from memory tool return message (#9367)
Models (especially Opus) take this instruction literally and re-call
the memory edit tool in a loop — one user saw 96 consecutive rethink
calls. Dropping the sentence stops the feedback loop while still
asking the agent to review the result.

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

Co-authored-by: Letta <noreply@letta.com>
2026-02-24 10:52:07 -08:00
Kian Jones
be60697a62 fix(core): handle protocol errors and foreign key violations (#9308)
* fix(core): handle PermissionDeniedError in provider API key validation

Fixed OpenAI PermissionDeniedError being raised as unknown error when
validating provider API keys. The check_api_key methods in OpenAI-based
providers (OpenAI, OpenRouter, Azure, Together) now properly catch and
re-raise PermissionDeniedError as LLMPermissionDeniedError.

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

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

* fix(core): handle Unicode surrogates in OpenAI requests

Sanitize invalid UTF-16 surrogates before sending requests to OpenAI API.
Fixes UnicodeEncodeError when message content contains unpaired surrogates
from corrupted emoji data or malformed Unicode sequences.

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

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

* fix(core): handle MCP tool schema validation errors gracefully

Catch fastmcp.exceptions.ToolError in execute_mcp_tool endpoint and
convert to LettaInvalidArgumentError (400) instead of letting it
propagate as 500 error. This is an expected user error when tool
arguments don't match the MCP tool's schema.

Fixes Datadog issue 8f2d874a-f8e5-11f0-9b25-da7ad0900000

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

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

* fix(core): handle ExceptionGroup-wrapped ToolError in MCP executor

When MCP tools fail with validation errors (e.g., missing required parameters),
fastmcp raises ToolError exceptions that may be wrapped in ExceptionGroup by
Python's async TaskGroup. The exception handler now unwraps single-exception
groups before checking if the error should be handled gracefully.

Fixes Calendly API "organization parameter missing" errors being logged to
Datadog instead of returning friendly error messages to users.

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

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

* fix: handle missing agent in create_conversation to prevent foreign key violation

* Update .gitignore

---------

Co-authored-by: Letta <noreply@letta.com>
2026-02-24 10:52:06 -08:00
Kevin Lin
3a13c63f60 fix: preserve slashes in memory block paths (#9172)
Remove .replace("/", "_") from memory block label processing to allow hierarchical memory organization with slashes.

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

Co-authored-by: Letta <noreply@letta.com>
2026-01-29 12:44:04 -08:00
Kian Jones
1ab21af725 fix: safer type coersion for tools (#8990)
* mvp

* perfrom type coercion in sandbox

* fix: safely resolve typing annotations on host

Use an AST whitelist for generic annotations to avoid eval while keeping list/dict coercion working.

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

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

---------

Co-authored-by: Letta <noreply@letta.com>
2026-01-29 12:43:53 -08:00
Kevin Lin
b5519f02fb feat: make tool return messages more explicit [LET-7145] (#8986)
prompt
2026-01-29 12:43:53 -08:00
Ari Webb
5645ca8107 fix: use labels for error messages for builtin memory tools [LET-7095] (#8941)
* fix: use labels for error messages for builtin memory tools

* catch specific error
2026-01-29 12:43:53 -08:00
Ari Webb
7a104a74fe fix: allow conversation_search time only queries [LET-7094] (#8939)
fix: allow conversation_search time only queries
2026-01-19 15:54:44 -08:00
github-actions[bot]
90f3ab9184 fix: validate URL scheme in fetch_webpage to reject file:// URLs (#8889)
Adds validation to the fetch_webpage tool to ensure only HTTP/HTTPS URLs
are accepted. Previously, passing a file:// URL would cause an unhandled
requests.exceptions.InvalidSchema error. Now it raises a clear ValueError
with a helpful error message.

Fixes: requests.exceptions.InvalidSchema: No connection adapters were found for 'file://...'

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

Co-authored-by: letta-code <248085862+letta-code@users.noreply.github.com>
Co-authored-by: datadog-official[bot] <datadog-official[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-19 15:54:44 -08:00
github-actions[bot]
940d648d42 fix(mcp): handle MCP tool errors gracefully to prevent Datadog alerts (#8687)
MCP tool errors (ToolError, McpError) are expected user-facing errors
from external MCP servers (e.g., "No connected account found"). These
were propagating through @trace_method decorator and being recorded
as errors in Datadog APM.

Changes:
- Add try/except to catch expected MCP errors in ExternalMCPToolExecutor
- Return ToolExecutionResult with status="error" instead of re-raising
- Log expected errors at INFO level instead of letting them trace as ERROR
- Remove stray 'pass' statement that was a no-op

Fixes #8685

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

Co-authored-by: letta-code <248085862+letta-code@users.noreply.github.com>
Co-authored-by: datadog-official[bot] <datadog-official[bot]@users.noreply.github.com>
Co-authored-by: Kian Jones <11655409+kianjones9@users.noreply.github.com>
2026-01-19 15:54:43 -08:00
Sarah Wooders
7c1da1e9e2 feat: add TypeScript tool support for E2B sandbox execution (#8796)
* feat: add TypeScript tool support for E2B sandbox execution

This change implements TypeScript tool support using the same E2B path as Python tools:

- Add TypeScript execution script generator (typescript_generator.py)
- Modify E2B sandbox to detect TypeScript tools and use language='ts'
- Add npm package installation for TypeScript tool dependencies
- Add validation requiring json_schema for TypeScript tools
- Add comprehensive integration tests for TypeScript tools

TypeScript tools:
- Require explicit json_schema (no docstring parsing)
- Use JSON serialization instead of pickle for results
- Support async functions with top-level await
- Support npm package dependencies via npm_requirements field

Closes #8793

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

* fix: disable AgentState for TypeScript tools & add letta-client injection

Based on Sarah's feedback:
1. AgentState is a legacy Python-only feature, disabled for TS tools
2. Added @letta-ai/letta-client npm package injection for TypeScript
   (similar to letta_client for Python)

Changes:
- base.py: Explicitly set inject_agent_state=False for TypeScript tools
- typescript_generator.py: Inject LettaClient initialization code
- e2b_sandbox.py: Auto-install @letta-ai/letta-client for TS tools
- Added tests verifying both behaviors

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

Co-Authored-By: Sarah Wooders <sarahwooders@users.noreply.github.com>
Co-Authored-By: Letta <noreply@letta.com>

* Update core-integration-tests.yml

* fix: convert TypeScript test fixtures to async

The OrganizationManager and UserManager no longer have sync methods,
only async variants. Updated all fixtures to use:
- create_organization_async
- create_actor_async
- create_or_update_tool_async

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

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

* fix: skip Python AST parsing for TypeScript tools in sandbox base

The _init_async method was calling parse_function_arguments (which uses
Python's ast.parse) before checking if the tool was TypeScript, causing
SyntaxError when running TypeScript tools.

Moved the is_typescript_tool() check to happen first, skipping Python
AST parsing entirely for TypeScript tools.

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

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

* letta_agent_id

* skip ast parsing for s

* add tool execution test

---------

Co-authored-by: letta-code <248085862+letta-code@users.noreply.github.com>
Co-authored-by: Sarah Wooders <sarahwooders@users.noreply.github.com>
Co-authored-by: Letta <noreply@letta.com>
Co-authored-by: Kian Jones <kian@letta.com>
2026-01-19 15:54:43 -08:00
Kevin Lin
8872c2b5d3 feat: extend memory_apply_patch for memory block create and delete (#8832)
* update memory_apply_patch for memory block create and delete

* update docstring

* update docstring

* fix label

* working
2026-01-19 15:54:42 -08:00
Kevin Lin
758b74b9c4 feat: rename memory tool arguments for consistency with edit tool [LET-6972] (#8631)
* update names

* stage

* chore: retrigger linear workflow
2026-01-19 15:54:41 -08:00
Kian Jones
15cede7281 fix: prevent db connection pool exhaustion in multi-agent tool executor (#6619)
Problem: When executing a tool that sends messages to many agents matching
tags, the code used asyncio.gather to process all agents concurrently. Each
agent processing creates database operations (run creation, message storage),
leading to N concurrent database connections.

Example: If 100 agents match the tags, 100 simultaneous database connections
are created, exhausting the connection pool and causing errors.

Root cause: asyncio.gather(*[_process_agent(...) for agent in agents])
creates all coroutines and runs them concurrently, each opening a DB session.

Solution: Process agents sequentially instead of concurrently. While this is
slower, it prevents database connection pool exhaustion. The operation is
still async, so it won't block the event loop.

Changes:
- apps/core/letta/services/tool_executor/multi_agent_tool_executor.py:
  - Replaced asyncio.gather with sequential for loop
  - Added explanatory comment about why sequential processing is needed

Impact: With 100 matching agents:
- Before: 100 concurrent DB connections (pool exhaustion)
- After: 1 DB connection at a time (no pool exhaustion)

Note: This follows the same pattern as PR #6617 which fixed a similar issue
in file attachment operations.
2025-12-15 12:02:34 -08:00
Kian Jones
fbd89c9360 fix: replace all 'PRODUCTION' references with 'prod' for consistency (#6627)
* fix: replace all 'PRODUCTION' references with 'prod' for consistency

Problem: Codebase had 11 references to 'PRODUCTION' (uppercase) that should
use 'prod' (lowercase) for consistency with the deployment workflows and
environment normalization.

Changes across 8 files:

1. Source files (using settings.environment):
   - letta/functions/function_sets/multi_agent.py
   - letta/services/tool_manager.py
   - letta/services/tool_executor/multi_agent_tool_executor.py
   - letta/services/helpers/agent_manager_helper.py
   All checks changed from: settings.environment == "PRODUCTION"
   To: settings.environment == "prod"

2. OTEL resource configuration:
   - letta/otel/resource.py
     - Updated _normalize_environment_tag() to handle 'prod' directly
     - Removed 'PRODUCTION' -> 'prod' mapping (no longer needed)
     - Updated device.id check from _env != "PRODUCTION" to _env != "prod"

3. Test files:
   - tests/managers/conftest.py
     - Fixture parameter changed from "PRODUCTION" to "prod"
   - tests/managers/test_agent_manager.py (3 occurrences)
   - tests/managers/test_tool_manager.py (2 occurrences)
   All test checks changed to use "prod"

Result: Complete consistency across the codebase:
- All environment checks use "prod" instead of "PRODUCTION"
- Normalization function simplified (no special case for PRODUCTION)
- Tests use correct "prod" value
- Matches deployment workflow configuration from PR #6626

This completes the environment naming standardization effort.

* fix: update settings.py environment description to use 'prod' instead of 'PRODUCTION'

The field description still referenced PRODUCTION as an example value.
Updated to use lowercase 'prod' for consistency with actual usage.

Before: "Application environment (PRODUCTION, DEV, CANARY, etc. - normalized to lowercase for OTEL tags)"
After: "Application environment (prod, dev, canary, etc. - lowercase values used for OTEL tags)"
2025-12-15 12:02:34 -08:00
Cameron
a56c6571d2 fix: update fetch_webpage docstring to reflect actual implementation (#6503)
The docstring incorrectly stated that fetch_webpage uses Jina AI reader.
Updated to accurately describe the actual implementation which uses:
1. Exa API (if EXA_API_KEY is available)
2. Trafilatura (fallback)
3. Readability + html2text (final fallback)

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

Co-authored-by: Letta <noreply@letta.com>
2025-12-15 12:02:34 -08:00
Sarah Wooders
ceadacd30e feat: support programmatic tool execution (cloud only) (#6441) 2025-12-15 12:02:19 -08:00
Charles Packer
d3f5307789 fix(core): patch bug in memory tool with leading '/' [LET-6266] (#6448)
fix(core): patch bug in memory tool with leading '/'
2025-12-15 12:02:19 -08:00
Sarah Wooders
c4d5c380d6 feat: pass in LETTA_TOOL_ID, LETTA_AGENT_ID, LETTA_PROJECT_ID into tool env (#6439) 2025-12-15 12:02:18 -08:00
Sarah Wooders
e349ba3bdd feat: support programmatic tool calling for custom tools [LET-6316] (#6369) 2025-11-26 14:39:40 -08:00
cthomas
1d55a0f4c5 fix: use new agent loop in multi agent test (#6384)
* use new agent loop and cleanup stale agents

* fix: make multi agent use new agent loop

* remove migration
2025-11-26 14:39:39 -08:00
Shubham Naik
a3dfdb1981 feat: e2e test for injected keys (#6196)
* feat: e2e test for injected keys

* chore: update errors

* chore: always log

* chore: log step orchestrator

* chore: add endpoint

---------

Co-authored-by: Shubham Naik <shub@memgpt.ai>
2025-11-24 19:10:27 -08:00
jnjpng
442b916fa9 feat: connect generated letta api key with modal function wrapper (#6329)
base

Co-authored-by: Letta Bot <noreply@letta.com>
2025-11-24 19:10:27 -08:00
Ari Webb
60a8292e0f fix: hotfix conversation_search recursion (#6308)
hotfix conversation_search recursion

Co-authored-by: Ari Webb <ari@letta.com>
2025-11-24 19:10:27 -08:00
Sarah Wooders
ce3add4f55 feat: migrate integration tests to use model_settings (#6125)
* migration integration tests to use model_settings

* updated configs

* update v2 tests

* revert files

* add some configs and fix tests

* fix conversation_search

---------

Co-authored-by: Ari Webb <ari@letta.com>
2025-11-24 19:09:33 -08:00
Ari Webb
ec953d27c0 fix: double escape leads to exponential growth in backslash character [LET-6016] (#6087) 2025-11-24 19:09:33 -08:00
Shubham Naik
acbbccd28a feat: have core ask cloud for any relavent api credentials to allow a… [LET-6179] (#6172)
feat: have core ask cloud for any relavent api credentials to allow an agent to perform letta tasks

Co-authored-by: Shubham Naik <shub@memgpt.ai>
2025-11-24 19:09:32 -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
Kevin Lin
f65eaa10c1 feat: Remove view from anthropic tool (#5832)
remove view from anthropic tool
2025-11-13 15:36:14 -08:00
Ari Webb
66ccc1d4df chore: silence exa search failed [LET-5952] (#5815)
silence exa search failed

Co-authored-by: Ari Webb <ari@letta.com>
2025-11-13 15:36:08 -08:00
Kevin Lin
4bb54f471c feat: memory apply patch [LET-5548] (#5475) 2025-10-24 15:13:15 -07:00
Kevin Lin
35b5383724 feat: match line number rendering to Anthropic / OAI defaults (#5492) 2025-10-24 15:13:15 -07:00
Ari Webb
3b399f999f chore: silence error [LET-5761] (#5610)
silence error

Co-authored-by: Ari Webb <ari@letta.com>
2025-10-24 15:13:15 -07:00
Ari Webb
967cc3decf move exceptions out of folders and sources [LET-4631] (#5444) 2025-10-24 15:12:11 -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
6016ac0f33 chore: undo fetch_webpage rename (#5132) 2025-10-07 17:50:49 -07:00
Charles Packer
09b173668a feat(core): rename fetch_webpage to web_fetch (#5110) 2025-10-07 17:50:48 -07:00
Matthew Zhou
29515e9a7d feat: Make exa get_contents async [LET-4574] (#5068)
Make exa async
2025-10-07 17:50:48 -07:00
Matthew Zhou
7390edeb00 feat: Add exa for fetch webpage (#5066)
Add exa for fetch webpage
2025-10-07 17:50:48 -07:00
Kevin Lin
09d9c3ffd4 feat: anthropic tools for claude sonnet 4.5 (#4988)
* add anthropic memory tools

* memory view working

* update memory examples

* tools

* feat: some changes (#5003)

* feat: added the ability to modify and add descriptions on creation

* fix: kill dead code & write into core_tool_executor instead

* fix: use block_manager not agent_manager where possible, also turn the return string errors into raising exceptions

* fix: cleanup, get rid of more return string errors replaced with valueerror, also drop deadcode

---------

Co-authored-by: Charles Packer <packercharles@gmail.com>
2025-10-07 17:50:47 -07:00
Sarah Wooders
354205f581 feat: create new runs table [LET-4467] (#4841) 2025-10-07 17:50:47 -07:00
Charles Packer
809956d1aa fix(core): patch bug in the broadcast multi-agent tool where we were not properly awating returns [LET-4484] (#4866)
fix(core): patch bug in the broadcast multi-agent tool where we were not await-ing the responses to return them properly
2025-10-07 17:50:45 -07:00
Kian Jones
b8e9a80d93 merge this (#4759)
* wait I forgot to comit locally

* cp the entire core directory and then rm the .git subdir
2025-09-17 15:47:40 -07:00
Matthew Zhou
3c2911e9ae feat: Remove jinja2 (#2971)
Co-authored-by: Sarah Wooders <sarahwooders@gmail.com>
2025-09-17 10:00:49 -07:00
cthomas
edb6c5e14e feat: replace tool_exec_environtment_variables with secrets (#2953) 2025-09-16 13:22:48 -07:00
Matthew Zhou
981d286fbe feat: Remove Turbopuffer mentions from semantic_search_files (#2843) 2025-09-11 14:54:14 -07:00
cthomas
636fb52d87 feat: make multi-agent tools use new agent loop (#2826) 2025-09-10 22:30:12 -07:00
cthomas
2d971cdcf0 feat: hold reference to asyncio tasks in memory (#2823) 2025-09-10 17:08:07 -07:00