letta-nightly 0.11.7.dev20251006104136__py3-none-any.whl → 0.11.7.dev20251008104128__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/adapters/letta_llm_adapter.py +1 -0
- letta/adapters/letta_llm_request_adapter.py +0 -1
- letta/adapters/letta_llm_stream_adapter.py +7 -2
- letta/adapters/simple_llm_request_adapter.py +88 -0
- letta/adapters/simple_llm_stream_adapter.py +192 -0
- letta/agents/agent_loop.py +6 -0
- letta/agents/ephemeral_summary_agent.py +2 -1
- letta/agents/helpers.py +142 -6
- letta/agents/letta_agent.py +13 -33
- letta/agents/letta_agent_batch.py +2 -4
- letta/agents/letta_agent_v2.py +87 -77
- letta/agents/letta_agent_v3.py +899 -0
- letta/agents/voice_agent.py +2 -6
- letta/constants.py +8 -4
- letta/errors.py +40 -0
- letta/functions/function_sets/base.py +84 -4
- letta/functions/function_sets/multi_agent.py +0 -3
- letta/functions/schema_generator.py +113 -71
- letta/groups/dynamic_multi_agent.py +3 -2
- letta/groups/helpers.py +1 -2
- letta/groups/round_robin_multi_agent.py +3 -2
- letta/groups/sleeptime_multi_agent.py +3 -2
- letta/groups/sleeptime_multi_agent_v2.py +1 -1
- letta/groups/sleeptime_multi_agent_v3.py +17 -17
- letta/groups/supervisor_multi_agent.py +84 -80
- letta/helpers/converters.py +3 -0
- letta/helpers/message_helper.py +4 -0
- letta/helpers/tool_rule_solver.py +92 -5
- letta/interfaces/anthropic_streaming_interface.py +409 -0
- letta/interfaces/gemini_streaming_interface.py +296 -0
- letta/interfaces/openai_streaming_interface.py +752 -1
- letta/llm_api/anthropic_client.py +126 -16
- letta/llm_api/bedrock_client.py +4 -2
- letta/llm_api/deepseek_client.py +4 -1
- letta/llm_api/google_vertex_client.py +123 -42
- letta/llm_api/groq_client.py +4 -1
- letta/llm_api/llm_api_tools.py +11 -4
- letta/llm_api/llm_client_base.py +6 -2
- letta/llm_api/openai.py +32 -2
- letta/llm_api/openai_client.py +423 -18
- letta/llm_api/xai_client.py +4 -1
- letta/main.py +9 -5
- letta/memory.py +1 -0
- letta/orm/__init__.py +1 -1
- letta/orm/agent.py +10 -0
- letta/orm/block.py +7 -16
- letta/orm/blocks_agents.py +8 -2
- letta/orm/files_agents.py +2 -0
- letta/orm/job.py +7 -5
- letta/orm/mcp_oauth.py +1 -0
- letta/orm/message.py +21 -6
- letta/orm/organization.py +2 -0
- letta/orm/provider.py +6 -2
- letta/orm/run.py +71 -0
- letta/orm/sandbox_config.py +7 -1
- letta/orm/sqlalchemy_base.py +0 -306
- letta/orm/step.py +6 -5
- letta/orm/step_metrics.py +5 -5
- letta/otel/tracing.py +28 -3
- letta/plugins/defaults.py +4 -4
- letta/prompts/system_prompts/__init__.py +2 -0
- letta/prompts/system_prompts/letta_v1.py +25 -0
- letta/schemas/agent.py +3 -2
- letta/schemas/agent_file.py +9 -3
- letta/schemas/block.py +23 -10
- letta/schemas/enums.py +21 -2
- letta/schemas/job.py +17 -4
- letta/schemas/letta_message_content.py +71 -2
- letta/schemas/letta_stop_reason.py +5 -5
- letta/schemas/llm_config.py +53 -3
- letta/schemas/memory.py +1 -1
- letta/schemas/message.py +504 -117
- letta/schemas/openai/responses_request.py +64 -0
- letta/schemas/providers/__init__.py +2 -0
- letta/schemas/providers/anthropic.py +16 -0
- letta/schemas/providers/ollama.py +115 -33
- letta/schemas/providers/openrouter.py +52 -0
- letta/schemas/providers/vllm.py +2 -1
- letta/schemas/run.py +48 -42
- letta/schemas/step.py +2 -2
- letta/schemas/step_metrics.py +1 -1
- letta/schemas/tool.py +15 -107
- letta/schemas/tool_rule.py +88 -5
- letta/serialize_schemas/marshmallow_agent.py +1 -0
- letta/server/db.py +86 -408
- letta/server/rest_api/app.py +61 -10
- letta/server/rest_api/dependencies.py +14 -0
- letta/server/rest_api/redis_stream_manager.py +19 -8
- letta/server/rest_api/routers/v1/agents.py +364 -292
- letta/server/rest_api/routers/v1/blocks.py +14 -20
- letta/server/rest_api/routers/v1/identities.py +45 -110
- letta/server/rest_api/routers/v1/internal_templates.py +21 -0
- letta/server/rest_api/routers/v1/jobs.py +23 -6
- letta/server/rest_api/routers/v1/messages.py +1 -1
- letta/server/rest_api/routers/v1/runs.py +126 -85
- letta/server/rest_api/routers/v1/sandbox_configs.py +10 -19
- letta/server/rest_api/routers/v1/tools.py +281 -594
- letta/server/rest_api/routers/v1/voice.py +1 -1
- letta/server/rest_api/streaming_response.py +29 -29
- letta/server/rest_api/utils.py +122 -64
- letta/server/server.py +160 -887
- letta/services/agent_manager.py +236 -919
- letta/services/agent_serialization_manager.py +16 -0
- letta/services/archive_manager.py +0 -100
- letta/services/block_manager.py +211 -168
- letta/services/file_manager.py +1 -1
- letta/services/files_agents_manager.py +24 -33
- letta/services/group_manager.py +0 -142
- letta/services/helpers/agent_manager_helper.py +7 -2
- letta/services/helpers/run_manager_helper.py +85 -0
- letta/services/job_manager.py +96 -411
- letta/services/lettuce/__init__.py +6 -0
- letta/services/lettuce/lettuce_client_base.py +86 -0
- letta/services/mcp_manager.py +38 -6
- letta/services/message_manager.py +165 -362
- letta/services/organization_manager.py +0 -36
- letta/services/passage_manager.py +0 -345
- letta/services/provider_manager.py +0 -80
- letta/services/run_manager.py +301 -0
- letta/services/sandbox_config_manager.py +0 -234
- letta/services/step_manager.py +62 -39
- letta/services/summarizer/summarizer.py +9 -7
- letta/services/telemetry_manager.py +0 -16
- letta/services/tool_executor/builtin_tool_executor.py +35 -0
- letta/services/tool_executor/core_tool_executor.py +397 -2
- letta/services/tool_executor/files_tool_executor.py +3 -3
- letta/services/tool_executor/multi_agent_tool_executor.py +30 -15
- letta/services/tool_executor/tool_execution_manager.py +6 -8
- letta/services/tool_executor/tool_executor_base.py +3 -3
- letta/services/tool_manager.py +85 -339
- letta/services/tool_sandbox/base.py +24 -13
- letta/services/tool_sandbox/e2b_sandbox.py +16 -1
- letta/services/tool_schema_generator.py +123 -0
- letta/services/user_manager.py +0 -99
- letta/settings.py +20 -4
- {letta_nightly-0.11.7.dev20251006104136.dist-info → letta_nightly-0.11.7.dev20251008104128.dist-info}/METADATA +3 -5
- {letta_nightly-0.11.7.dev20251006104136.dist-info → letta_nightly-0.11.7.dev20251008104128.dist-info}/RECORD +140 -132
- letta/agents/temporal/activities/__init__.py +0 -4
- letta/agents/temporal/activities/example_activity.py +0 -7
- letta/agents/temporal/activities/prepare_messages.py +0 -10
- letta/agents/temporal/temporal_agent_workflow.py +0 -56
- letta/agents/temporal/types.py +0 -25
- {letta_nightly-0.11.7.dev20251006104136.dist-info → letta_nightly-0.11.7.dev20251008104128.dist-info}/WHEEL +0 -0
- {letta_nightly-0.11.7.dev20251006104136.dist-info → letta_nightly-0.11.7.dev20251008104128.dist-info}/entry_points.txt +0 -0
- {letta_nightly-0.11.7.dev20251006104136.dist-info → letta_nightly-0.11.7.dev20251008104128.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
from letta.constants import DEFAULT_MAX_STEPS
|
2
|
+
from letta.schemas.agent import AgentState
|
3
|
+
from letta.schemas.letta_message import MessageType
|
4
|
+
from letta.schemas.message import MessageCreate
|
5
|
+
from letta.schemas.user import User
|
6
|
+
|
7
|
+
|
8
|
+
class LettuceClient:
|
9
|
+
"""Base class for LettuceClient."""
|
10
|
+
|
11
|
+
def __init__(self):
|
12
|
+
"""Initialize the LettuceClient."""
|
13
|
+
self.client: None = None
|
14
|
+
|
15
|
+
@classmethod
|
16
|
+
async def create(cls) -> "LettuceClient":
|
17
|
+
"""
|
18
|
+
Asynchronously creates the client.
|
19
|
+
|
20
|
+
Returns:
|
21
|
+
LettuceClient: The created LettuceClient instance.
|
22
|
+
"""
|
23
|
+
instance = cls()
|
24
|
+
return instance
|
25
|
+
|
26
|
+
def get_client(self) -> None:
|
27
|
+
"""
|
28
|
+
Get the inner client.
|
29
|
+
|
30
|
+
Returns:
|
31
|
+
None: The inner client.
|
32
|
+
"""
|
33
|
+
return self.client
|
34
|
+
|
35
|
+
async def get_status(self, run_id: str) -> str | None:
|
36
|
+
"""
|
37
|
+
Get the status of a run.
|
38
|
+
|
39
|
+
Args:
|
40
|
+
run_id (str): The ID of the run.
|
41
|
+
|
42
|
+
Returns:
|
43
|
+
str | None: The status of the run or None if not available.
|
44
|
+
"""
|
45
|
+
return None
|
46
|
+
|
47
|
+
async def cancel(self, run_id: str) -> str | None:
|
48
|
+
"""
|
49
|
+
Cancel a run.
|
50
|
+
|
51
|
+
Args:
|
52
|
+
run_id (str): The ID of the run to cancel.
|
53
|
+
|
54
|
+
Returns:
|
55
|
+
str | None: The ID of the canceled run or None if not available.
|
56
|
+
"""
|
57
|
+
return None
|
58
|
+
|
59
|
+
async def step(
|
60
|
+
self,
|
61
|
+
agent_state: AgentState,
|
62
|
+
actor: User,
|
63
|
+
input_messages: list[MessageCreate],
|
64
|
+
max_steps: int = DEFAULT_MAX_STEPS,
|
65
|
+
run_id: str | None = None,
|
66
|
+
use_assistant_message: bool = True,
|
67
|
+
include_return_message_types: list[MessageType] | None = None,
|
68
|
+
request_start_timestamp_ns: int | None = None,
|
69
|
+
) -> str | None:
|
70
|
+
"""
|
71
|
+
Execute the agent loop on Lettuce service.
|
72
|
+
|
73
|
+
Args:
|
74
|
+
agent_state (AgentState): The state of the agent.
|
75
|
+
actor (User): The actor.
|
76
|
+
input_messages (list[MessageCreate]): The input messages.
|
77
|
+
max_steps (int, optional): The maximum number of steps. Defaults to DEFAULT_MAX_STEPS.
|
78
|
+
run_id (str | None, optional): The ID of the run. Defaults to None.
|
79
|
+
use_assistant_message (bool, optional): Whether to use the assistant message. Defaults to True.
|
80
|
+
include_return_message_types (list[MessageType] | None, optional): The message types to include in the return. Defaults to None.
|
81
|
+
request_start_timestamp_ns (int | None, optional): The start timestamp of the request. Defaults to None.
|
82
|
+
|
83
|
+
Returns:
|
84
|
+
str | None: The ID of the run or None if client is not available.
|
85
|
+
"""
|
86
|
+
return None
|
letta/services/mcp_manager.py
CHANGED
@@ -18,6 +18,7 @@ from letta.functions.mcp_client.types import (
|
|
18
18
|
StdioServerConfig,
|
19
19
|
StreamableHTTPServerConfig,
|
20
20
|
)
|
21
|
+
from letta.functions.schema_generator import normalize_mcp_schema
|
21
22
|
from letta.functions.schema_validator import validate_complete_json_schema
|
22
23
|
from letta.log import get_logger
|
23
24
|
from letta.orm.errors import NoResultFound
|
@@ -72,7 +73,9 @@ class MCPManager:
|
|
72
73
|
tools = await mcp_client.list_tools()
|
73
74
|
# Add health information to each tool
|
74
75
|
for tool in tools:
|
76
|
+
# Try to normalize the schema and re-validate\
|
75
77
|
if tool.inputSchema:
|
78
|
+
tool.inputSchema = normalize_mcp_schema(tool.inputSchema)
|
76
79
|
health_status, reasons = validate_complete_json_schema(tool.inputSchema)
|
77
80
|
tool.health = MCPToolHealth(status=health_status.value, reasons=reasons)
|
78
81
|
|
@@ -140,12 +143,41 @@ class MCPManager:
|
|
140
143
|
for mcp_tool in mcp_tools:
|
141
144
|
# TODO: @jnjpng move health check to tool class
|
142
145
|
if mcp_tool.name == mcp_tool_name:
|
143
|
-
# Check tool health -
|
144
|
-
if mcp_tool.health:
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
146
|
+
# Check tool health - but try normalization first for INVALID schemas
|
147
|
+
if mcp_tool.health and mcp_tool.health.status == "INVALID":
|
148
|
+
logger.info(f"Attempting to normalize INVALID schema for tool {mcp_tool_name}")
|
149
|
+
logger.info(f"Original health reasons: {mcp_tool.health.reasons}")
|
150
|
+
|
151
|
+
# Try to normalize the schema and re-validate
|
152
|
+
try:
|
153
|
+
# Normalize the schema to fix common issues
|
154
|
+
logger.debug(f"Normalizing schema for {mcp_tool_name}")
|
155
|
+
normalized_schema = normalize_mcp_schema(mcp_tool.inputSchema)
|
156
|
+
|
157
|
+
# Re-validate after normalization
|
158
|
+
logger.debug(f"Re-validating schema for {mcp_tool_name}")
|
159
|
+
health_status, health_reasons = validate_complete_json_schema(normalized_schema)
|
160
|
+
logger.info(f"After normalization: status={health_status.value}, reasons={health_reasons}")
|
161
|
+
|
162
|
+
# Update the tool's schema and health (use inputSchema, not input_schema)
|
163
|
+
mcp_tool.inputSchema = normalized_schema
|
164
|
+
mcp_tool.health.status = health_status.value
|
165
|
+
mcp_tool.health.reasons = health_reasons
|
166
|
+
|
167
|
+
# Log the normalization result
|
168
|
+
if health_status.value != "INVALID":
|
169
|
+
logger.info(f"✓ MCP tool {mcp_tool_name} schema normalized successfully: {health_status.value}")
|
170
|
+
else:
|
171
|
+
logger.warning(f"MCP tool {mcp_tool_name} still INVALID after normalization. Reasons: {health_reasons}")
|
172
|
+
except Exception as e:
|
173
|
+
logger.error(f"Failed to normalize schema for tool {mcp_tool_name}: {e}", exc_info=True)
|
174
|
+
|
175
|
+
# After normalization attempt, check if still INVALID
|
176
|
+
if mcp_tool.health and mcp_tool.health.status == "INVALID":
|
177
|
+
raise ValueError(
|
178
|
+
f"Tool {mcp_tool_name} cannot be attached, JSON schema is invalid even after normalization. "
|
179
|
+
f"Reasons: {', '.join(mcp_tool.health.reasons)}"
|
180
|
+
)
|
149
181
|
|
150
182
|
tool_create = ToolCreate.from_mcp(mcp_server_name=mcp_server_name, mcp_tool=mcp_tool)
|
151
183
|
return await self.tool_manager.create_mcp_tool_async(
|