letta-nightly 0.7.29.dev20250602104315__py3-none-any.whl → 0.8.0.dev20250604104349__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- letta/__init__.py +7 -1
- letta/agent.py +16 -9
- letta/agents/base_agent.py +1 -0
- letta/agents/ephemeral_summary_agent.py +104 -0
- letta/agents/helpers.py +35 -3
- letta/agents/letta_agent.py +492 -176
- letta/agents/letta_agent_batch.py +22 -16
- letta/agents/prompts/summary_system_prompt.txt +62 -0
- letta/agents/voice_agent.py +22 -7
- letta/agents/voice_sleeptime_agent.py +13 -8
- letta/constants.py +33 -1
- letta/data_sources/connectors.py +52 -36
- letta/errors.py +4 -0
- letta/functions/ast_parsers.py +13 -30
- letta/functions/function_sets/base.py +3 -1
- letta/functions/functions.py +2 -0
- letta/functions/mcp_client/base_client.py +151 -97
- letta/functions/mcp_client/sse_client.py +49 -31
- letta/functions/mcp_client/stdio_client.py +107 -106
- letta/functions/schema_generator.py +22 -22
- letta/groups/helpers.py +3 -4
- letta/groups/sleeptime_multi_agent.py +4 -4
- letta/groups/sleeptime_multi_agent_v2.py +22 -0
- letta/helpers/composio_helpers.py +16 -0
- letta/helpers/converters.py +20 -0
- letta/helpers/datetime_helpers.py +1 -6
- letta/helpers/tool_rule_solver.py +2 -1
- letta/interfaces/anthropic_streaming_interface.py +17 -2
- letta/interfaces/openai_chat_completions_streaming_interface.py +1 -0
- letta/interfaces/openai_streaming_interface.py +18 -2
- letta/jobs/llm_batch_job_polling.py +1 -1
- letta/jobs/scheduler.py +1 -1
- letta/llm_api/anthropic_client.py +24 -3
- letta/llm_api/google_ai_client.py +0 -15
- letta/llm_api/google_vertex_client.py +6 -5
- letta/llm_api/llm_client_base.py +15 -0
- letta/llm_api/openai.py +2 -2
- letta/llm_api/openai_client.py +60 -8
- letta/orm/__init__.py +2 -0
- letta/orm/agent.py +45 -43
- letta/orm/base.py +0 -2
- letta/orm/block.py +1 -0
- letta/orm/custom_columns.py +13 -0
- letta/orm/enums.py +5 -0
- letta/orm/file.py +3 -1
- letta/orm/files_agents.py +68 -0
- letta/orm/mcp_server.py +48 -0
- letta/orm/message.py +1 -0
- letta/orm/organization.py +11 -2
- letta/orm/passage.py +25 -10
- letta/orm/sandbox_config.py +5 -2
- letta/orm/sqlalchemy_base.py +171 -110
- letta/prompts/system/memgpt_base.txt +6 -1
- letta/prompts/system/memgpt_v2_chat.txt +57 -0
- letta/prompts/system/sleeptime.txt +2 -0
- letta/prompts/system/sleeptime_v2.txt +28 -0
- letta/schemas/agent.py +87 -20
- letta/schemas/block.py +7 -1
- letta/schemas/file.py +57 -0
- letta/schemas/mcp.py +74 -0
- letta/schemas/memory.py +5 -2
- letta/schemas/message.py +9 -0
- letta/schemas/openai/openai.py +0 -6
- letta/schemas/providers.py +33 -4
- letta/schemas/tool.py +26 -21
- letta/schemas/tool_execution_result.py +5 -0
- letta/server/db.py +23 -8
- letta/server/rest_api/app.py +73 -56
- letta/server/rest_api/interface.py +4 -4
- letta/server/rest_api/routers/v1/agents.py +132 -47
- letta/server/rest_api/routers/v1/blocks.py +3 -2
- letta/server/rest_api/routers/v1/embeddings.py +3 -3
- letta/server/rest_api/routers/v1/groups.py +3 -3
- letta/server/rest_api/routers/v1/jobs.py +14 -17
- letta/server/rest_api/routers/v1/organizations.py +10 -10
- letta/server/rest_api/routers/v1/providers.py +12 -10
- letta/server/rest_api/routers/v1/runs.py +3 -3
- letta/server/rest_api/routers/v1/sandbox_configs.py +12 -12
- letta/server/rest_api/routers/v1/sources.py +108 -43
- letta/server/rest_api/routers/v1/steps.py +8 -6
- letta/server/rest_api/routers/v1/tools.py +134 -95
- letta/server/rest_api/utils.py +12 -1
- letta/server/server.py +272 -73
- letta/services/agent_manager.py +246 -313
- letta/services/block_manager.py +30 -9
- letta/services/context_window_calculator/__init__.py +0 -0
- letta/services/context_window_calculator/context_window_calculator.py +150 -0
- letta/services/context_window_calculator/token_counter.py +82 -0
- letta/services/file_processor/__init__.py +0 -0
- letta/services/file_processor/chunker/__init__.py +0 -0
- letta/services/file_processor/chunker/llama_index_chunker.py +29 -0
- letta/services/file_processor/embedder/__init__.py +0 -0
- letta/services/file_processor/embedder/openai_embedder.py +84 -0
- letta/services/file_processor/file_processor.py +123 -0
- letta/services/file_processor/parser/__init__.py +0 -0
- letta/services/file_processor/parser/base_parser.py +9 -0
- letta/services/file_processor/parser/mistral_parser.py +54 -0
- letta/services/file_processor/types.py +0 -0
- letta/services/files_agents_manager.py +184 -0
- letta/services/group_manager.py +118 -0
- letta/services/helpers/agent_manager_helper.py +76 -21
- letta/services/helpers/tool_execution_helper.py +3 -0
- letta/services/helpers/tool_parser_helper.py +100 -0
- letta/services/identity_manager.py +44 -42
- letta/services/job_manager.py +21 -10
- letta/services/mcp/base_client.py +5 -2
- letta/services/mcp/sse_client.py +3 -5
- letta/services/mcp/stdio_client.py +3 -5
- letta/services/mcp_manager.py +281 -0
- letta/services/message_manager.py +40 -26
- letta/services/organization_manager.py +55 -19
- letta/services/passage_manager.py +211 -13
- letta/services/provider_manager.py +48 -2
- letta/services/sandbox_config_manager.py +105 -0
- letta/services/source_manager.py +4 -5
- letta/services/step_manager.py +9 -6
- letta/services/summarizer/summarizer.py +50 -23
- letta/services/telemetry_manager.py +7 -0
- letta/services/tool_executor/tool_execution_manager.py +11 -52
- letta/services/tool_executor/tool_execution_sandbox.py +4 -34
- letta/services/tool_executor/tool_executor.py +107 -105
- letta/services/tool_manager.py +56 -17
- letta/services/tool_sandbox/base.py +39 -92
- letta/services/tool_sandbox/e2b_sandbox.py +16 -11
- letta/services/tool_sandbox/local_sandbox.py +51 -23
- letta/services/user_manager.py +36 -3
- letta/settings.py +10 -3
- letta/templates/__init__.py +0 -0
- letta/templates/sandbox_code_file.py.j2 +47 -0
- letta/templates/template_helper.py +16 -0
- letta/tracing.py +30 -1
- letta/types/__init__.py +7 -0
- letta/utils.py +25 -1
- {letta_nightly-0.7.29.dev20250602104315.dist-info → letta_nightly-0.8.0.dev20250604104349.dist-info}/METADATA +7 -2
- {letta_nightly-0.7.29.dev20250602104315.dist-info → letta_nightly-0.8.0.dev20250604104349.dist-info}/RECORD +138 -112
- {letta_nightly-0.7.29.dev20250602104315.dist-info → letta_nightly-0.8.0.dev20250604104349.dist-info}/LICENSE +0 -0
- {letta_nightly-0.7.29.dev20250602104315.dist-info → letta_nightly-0.8.0.dev20250604104349.dist-info}/WHEEL +0 -0
- {letta_nightly-0.7.29.dev20250602104315.dist-info → letta_nightly-0.8.0.dev20250604104349.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
{{ 'from __future__ import annotations' if future_import else '' }}
|
2
|
+
from typing import *
|
3
|
+
import pickle
|
4
|
+
import sys
|
5
|
+
import base64
|
6
|
+
import struct
|
7
|
+
import hashlib
|
8
|
+
|
9
|
+
{# Additional imports to support agent state #}
|
10
|
+
{% if inject_agent_state %}
|
11
|
+
import letta
|
12
|
+
from letta import *
|
13
|
+
{% endif %}
|
14
|
+
|
15
|
+
{# Add schema code if available #}
|
16
|
+
{{ schema_imports or ''}}
|
17
|
+
|
18
|
+
{# Load agent state #}
|
19
|
+
agent_state = {{ 'pickle.loads(' ~ agent_state_pickle ~ ')' if agent_state_pickle else 'None' }}
|
20
|
+
|
21
|
+
{{ tool_args }}
|
22
|
+
|
23
|
+
{# The tool's source code #}
|
24
|
+
{{ tool_source_code }}
|
25
|
+
|
26
|
+
{# Invoke the function and store the result in a global variable #}
|
27
|
+
{{ local_sandbox_result_var_name }} = {
|
28
|
+
"results": {{ invoke_function_call }},
|
29
|
+
"agent_state": agent_state
|
30
|
+
}
|
31
|
+
|
32
|
+
{{ local_sandbox_result_var_name }}_pkl = pickle.dumps({{ local_sandbox_result_var_name }})
|
33
|
+
|
34
|
+
{% if wrap_print_with_markers %}
|
35
|
+
{# Combine everything to flush and write at once. #}
|
36
|
+
data_checksum = hashlib.md5({{ local_sandbox_result_var_name }}_pkl).hexdigest().encode('ascii')
|
37
|
+
{{ local_sandbox_result_var_name }}_msg = (
|
38
|
+
{{ start_marker }} +
|
39
|
+
struct.pack('>I', len({{ local_sandbox_result_var_name }}_pkl)) +
|
40
|
+
data_checksum +
|
41
|
+
{{ local_sandbox_result_var_name }}_pkl
|
42
|
+
)
|
43
|
+
sys.stdout.buffer.write({{ local_sandbox_result_var_name }}_msg)
|
44
|
+
sys.stdout.buffer.flush()
|
45
|
+
{% else %}
|
46
|
+
base64.b64encode({{ local_sandbox_result_var_name }}_pkl).decode('utf-8')
|
47
|
+
{% endif %}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from jinja2 import Environment, FileSystemLoader, StrictUndefined
|
4
|
+
|
5
|
+
TEMPLATE_DIR = os.path.dirname(__file__)
|
6
|
+
jinja_env = Environment(
|
7
|
+
loader=FileSystemLoader(TEMPLATE_DIR),
|
8
|
+
undefined=StrictUndefined,
|
9
|
+
trim_blocks=True,
|
10
|
+
lstrip_blocks=True,
|
11
|
+
)
|
12
|
+
|
13
|
+
|
14
|
+
def render_template(template_name: str, **kwargs):
|
15
|
+
template = jinja_env.get_template(template_name)
|
16
|
+
return template.render(**kwargs)
|
letta/tracing.py
CHANGED
@@ -16,6 +16,8 @@ from opentelemetry.sdk.trace import TracerProvider
|
|
16
16
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
17
17
|
from opentelemetry.trace import Status, StatusCode
|
18
18
|
|
19
|
+
from letta import __version__ as letta_version
|
20
|
+
|
19
21
|
tracer = trace.get_tracer(__name__)
|
20
22
|
_is_tracing_initialized = False
|
21
23
|
_excluded_v1_endpoints_regex: List[str] = [
|
@@ -24,6 +26,7 @@ _excluded_v1_endpoints_regex: List[str] = [
|
|
24
26
|
# "^GET /v1/agents/(?P<agent_id>[^/]+)/archival-memory$",
|
25
27
|
# "^GET /v1/agents/(?P<agent_id>[^/]+)/sources$",
|
26
28
|
# r"^POST /v1/voice-beta/.*/chat/completions$",
|
29
|
+
"^GET /v1/health$",
|
27
30
|
]
|
28
31
|
|
29
32
|
|
@@ -80,6 +83,31 @@ async def update_trace_attributes(request: Request):
|
|
80
83
|
if user_id:
|
81
84
|
span.set_attribute("user.id", user_id)
|
82
85
|
|
86
|
+
# Add organization_id if available
|
87
|
+
organization_id = request.headers.get("x-organization-id")
|
88
|
+
if organization_id:
|
89
|
+
span.set_attribute("organization.id", organization_id)
|
90
|
+
|
91
|
+
# Add project_id if available
|
92
|
+
project_id = request.headers.get("x-project-id")
|
93
|
+
if project_id:
|
94
|
+
span.set_attribute("project.id", project_id)
|
95
|
+
|
96
|
+
# Add agent_id if available
|
97
|
+
agent_id = request.headers.get("x-agent-id")
|
98
|
+
if agent_id:
|
99
|
+
span.set_attribute("agent.id", agent_id)
|
100
|
+
|
101
|
+
# Add template_id if available
|
102
|
+
template_id = request.headers.get("x-template-id")
|
103
|
+
if template_id:
|
104
|
+
span.set_attribute("template.id", template_id)
|
105
|
+
|
106
|
+
# Add base_template_id if available
|
107
|
+
base_template_id = request.headers.get("x-base-template-id")
|
108
|
+
if base_template_id:
|
109
|
+
span.set_attribute("base_template.id", base_template_id)
|
110
|
+
|
83
111
|
# Add request body if available
|
84
112
|
try:
|
85
113
|
body = await request.json()
|
@@ -124,7 +152,8 @@ def setup_tracing(
|
|
124
152
|
resource=Resource.create(
|
125
153
|
{
|
126
154
|
"service.name": service_name,
|
127
|
-
"device.id": uuid.getnode(), # MAC address as unique device identifier
|
155
|
+
"device.id": uuid.getnode(), # MAC address as unique device identifier,
|
156
|
+
"letta.version": letta_version,
|
128
157
|
}
|
129
158
|
)
|
130
159
|
)
|
letta/types/__init__.py
CHANGED
letta/utils.py
CHANGED
@@ -1018,7 +1018,7 @@ def sanitize_filename(filename: str) -> str:
|
|
1018
1018
|
base = base[:max_base_length]
|
1019
1019
|
|
1020
1020
|
# Append a unique UUID suffix for uniqueness
|
1021
|
-
unique_suffix = uuid.uuid4().hex
|
1021
|
+
unique_suffix = uuid.uuid4().hex[:4]
|
1022
1022
|
sanitized_filename = f"{base}_{unique_suffix}{ext}"
|
1023
1023
|
|
1024
1024
|
# Return the sanitized filename
|
@@ -1034,6 +1034,20 @@ def get_friendly_error_msg(function_name: str, exception_name: str, exception_me
|
|
1034
1034
|
return error_msg
|
1035
1035
|
|
1036
1036
|
|
1037
|
+
def parse_stderr_error_msg(stderr_txt: str, last_n_lines: int = 3) -> tuple[str, str]:
|
1038
|
+
"""
|
1039
|
+
Parses out from the last `last_n_line` of `stderr_txt` the Exception type and message.
|
1040
|
+
"""
|
1041
|
+
index = -(last_n_lines + 1)
|
1042
|
+
pattern = r"(\w+(?:Error|Exception)): (.+?)$"
|
1043
|
+
for line in stderr_txt.split("\n")[:index:-1]:
|
1044
|
+
if "Error" in line or "Exception" in line:
|
1045
|
+
match = re.search(pattern, line)
|
1046
|
+
if match:
|
1047
|
+
return match.group(1), match.group(2)
|
1048
|
+
return "", ""
|
1049
|
+
|
1050
|
+
|
1037
1051
|
def run_async_task(coro: Coroutine[Any, Any, Any]) -> Any:
|
1038
1052
|
"""
|
1039
1053
|
Safely runs an asynchronous coroutine in a synchronous context.
|
@@ -1074,3 +1088,13 @@ def log_telemetry(logger: Logger, event: str, **kwargs):
|
|
1074
1088
|
|
1075
1089
|
def make_key(*args, **kwargs):
|
1076
1090
|
return str((args, tuple(sorted(kwargs.items()))))
|
1091
|
+
|
1092
|
+
|
1093
|
+
def safe_create_task(coro, logger: Logger, label: str = "background task"):
|
1094
|
+
async def wrapper():
|
1095
|
+
try:
|
1096
|
+
await coro
|
1097
|
+
except Exception as e:
|
1098
|
+
logger.exception(f"{label} failed with {type(e).__name__}: {e}")
|
1099
|
+
|
1100
|
+
return asyncio.create_task(wrapper())
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: letta-nightly
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.8.0.dev20250604104349
|
4
4
|
Summary: Create LLM agents with long-term memory and custom tools
|
5
5
|
License: Apache License
|
6
6
|
Author: Letta Team
|
@@ -16,6 +16,7 @@ Provides-Extra: bedrock
|
|
16
16
|
Provides-Extra: cloud-tool-sandbox
|
17
17
|
Provides-Extra: desktop
|
18
18
|
Provides-Extra: dev
|
19
|
+
Provides-Extra: experimental
|
19
20
|
Provides-Extra: external-tools
|
20
21
|
Provides-Extra: google
|
21
22
|
Provides-Extra: postgres
|
@@ -27,7 +28,8 @@ Requires-Dist: aiosqlite (>=0.21.0,<0.22.0)
|
|
27
28
|
Requires-Dist: alembic (>=1.13.3,<2.0.0)
|
28
29
|
Requires-Dist: anthropic (>=0.49.0,<0.50.0)
|
29
30
|
Requires-Dist: apscheduler (>=3.11.0,<4.0.0)
|
30
|
-
Requires-Dist:
|
31
|
+
Requires-Dist: async-lru (>=2.0.5,<3.0.0)
|
32
|
+
Requires-Dist: asyncpg (>=0.30.0,<0.31.0) ; extra == "postgres"
|
31
33
|
Requires-Dist: autoflake (>=2.3.0,<3.0.0) ; extra == "dev" or extra == "all"
|
32
34
|
Requires-Dist: black[jupyter] (>=24.2.0,<25.0.0) ; extra == "dev" or extra == "all"
|
33
35
|
Requires-Dist: boto3 (>=1.36.24,<2.0.0) ; extra == "bedrock"
|
@@ -43,6 +45,7 @@ Requires-Dist: faker (>=36.1.0,<37.0.0)
|
|
43
45
|
Requires-Dist: fastapi (>=0.115.6,<0.116.0) ; extra == "server" or extra == "desktop" or extra == "all"
|
44
46
|
Requires-Dist: firecrawl-py (>=1.15.0,<2.0.0)
|
45
47
|
Requires-Dist: google-genai (>=1.15.0,<2.0.0) ; extra == "google"
|
48
|
+
Requires-Dist: granian[reload,uvloop] (>=2.3.2,<3.0.0) ; extra == "experimental" or extra == "all"
|
46
49
|
Requires-Dist: grpcio (>=1.68.1,<2.0.0)
|
47
50
|
Requires-Dist: grpcio-tools (>=1.68.1,<2.0.0)
|
48
51
|
Requires-Dist: html2text (>=2020.1.16,<2021.0.0)
|
@@ -59,6 +62,7 @@ Requires-Dist: locust (>=2.31.5,<3.0.0) ; extra == "dev" or extra == "desktop" o
|
|
59
62
|
Requires-Dist: marshmallow-sqlalchemy (>=1.4.1,<2.0.0)
|
60
63
|
Requires-Dist: matplotlib (>=3.10.1,<4.0.0)
|
61
64
|
Requires-Dist: mcp (>=1.3.0,<2.0.0)
|
65
|
+
Requires-Dist: mistralai (>=1.8.1,<2.0.0)
|
62
66
|
Requires-Dist: nltk (>=3.8.1,<4.0.0)
|
63
67
|
Requires-Dist: numpy (>=1.26.2,<2.0.0)
|
64
68
|
Requires-Dist: openai (>=1.60.0,<2.0.0)
|
@@ -97,6 +101,7 @@ Requires-Dist: tavily-python (>=0.7.2,<0.8.0)
|
|
97
101
|
Requires-Dist: tqdm (>=4.66.1,<5.0.0)
|
98
102
|
Requires-Dist: typer[all] (>=0.9.0,<0.10.0)
|
99
103
|
Requires-Dist: uvicorn (>=0.24.0.post1,<0.25.0) ; extra == "server" or extra == "desktop" or extra == "all"
|
104
|
+
Requires-Dist: uvloop (>=0.21.0,<0.22.0) ; extra == "experimental" or extra == "all"
|
100
105
|
Requires-Dist: wikipedia (>=1.4.0,<2.0.0) ; extra == "external-tools" or extra == "tests" or extra == "desktop" or extra == "all"
|
101
106
|
Description-Content-Type: text/markdown
|
102
107
|
|