letta-nightly 0.6.41.dev20250317104157__py3-none-any.whl → 0.6.42.dev20250317175208__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.

Potentially problematic release.


This version of letta-nightly might be problematic. Click here for more details.

letta/embeddings.py CHANGED
@@ -3,6 +3,7 @@ from typing import Any, List, Optional
3
3
 
4
4
  import numpy as np
5
5
  import tiktoken
6
+ from openai import OpenAI
6
7
 
7
8
  from letta.constants import EMBEDDING_TO_TOKENIZER_DEFAULT, EMBEDDING_TO_TOKENIZER_MAP, MAX_EMBEDDING_DIM
8
9
  from letta.schemas.embedding_config import EmbeddingConfig
@@ -201,6 +202,21 @@ class GoogleVertexEmbeddings:
201
202
  return response.embeddings[0].embedding
202
203
 
203
204
 
205
+ class OpenAIEmbeddings:
206
+
207
+ def __init__(self, api_key: str, model: str, base_url: str):
208
+ if base_url:
209
+ self.client = OpenAI(api_key=api_key, base_url=base_url)
210
+ else:
211
+ self.client = OpenAI(api_key=api_key)
212
+ self.model = model
213
+
214
+ def get_text_embedding(self, text: str):
215
+ response = self.client.embeddings.create(input=text, model=self.model)
216
+
217
+ return response.data[0].embedding
218
+
219
+
204
220
  def query_embedding(embedding_model, query_text: str):
205
221
  """Generate padded embedding for querying database"""
206
222
  query_vec = embedding_model.get_text_embedding(query_text)
@@ -218,15 +234,9 @@ def embedding_model(config: EmbeddingConfig, user_id: Optional[uuid.UUID] = None
218
234
  from letta.settings import model_settings
219
235
 
220
236
  if endpoint_type == "openai":
221
- from llama_index.embeddings.openai import OpenAIEmbedding
222
-
223
- additional_kwargs = {"user_id": user_id} if user_id else {}
224
- model = OpenAIEmbedding(
225
- api_base=config.embedding_endpoint,
226
- api_key=model_settings.openai_api_key,
227
- additional_kwargs=additional_kwargs,
237
+ return OpenAIEmbeddings(
238
+ api_key=model_settings.openai_api_key, model=config.embedding_model, base_url=model_settings.openai_api_base
228
239
  )
229
- return model
230
240
 
231
241
  elif endpoint_type == "azure":
232
242
  assert all(
@@ -5,12 +5,14 @@ from mcp import ClientSession, Tool
5
5
 
6
6
  from letta.functions.mcp_client.types import BaseServerConfig
7
7
  from letta.log import get_logger
8
+ from letta.settings import tool_settings
8
9
 
9
10
  logger = get_logger(__name__)
10
11
 
11
12
 
12
13
  class BaseMCPClient:
13
- def __init__(self):
14
+ def __init__(self, server_config: BaseServerConfig):
15
+ self.server_config = server_config
14
16
  self.session: Optional[ClientSession] = None
15
17
  self.stdio = None
16
18
  self.write = None
@@ -18,30 +20,54 @@ class BaseMCPClient:
18
20
  self.loop = asyncio.new_event_loop()
19
21
  self.cleanup_funcs = []
20
22
 
21
- def connect_to_server(self, server_config: BaseServerConfig):
23
+ def connect_to_server(self):
22
24
  asyncio.set_event_loop(self.loop)
23
- success = self._initialize_connection(server_config)
25
+ success = self._initialize_connection(self.server_config, timeout=tool_settings.mcp_connect_to_server_timeout)
24
26
 
25
27
  if success:
26
- self.loop.run_until_complete(self.session.initialize())
27
- self.initialized = True
28
+ try:
29
+ self.loop.run_until_complete(
30
+ asyncio.wait_for(self.session.initialize(), timeout=tool_settings.mcp_connect_to_server_timeout)
31
+ )
32
+ self.initialized = True
33
+ except asyncio.TimeoutError:
34
+ raise RuntimeError(
35
+ f"Timed out while initializing session for MCP server {self.server_config.server_name} (timeout={tool_settings.mcp_connect_to_server_timeout}s)."
36
+ )
28
37
  else:
29
38
  raise RuntimeError(
30
- f"Connecting to MCP server failed. Please review your server config: {server_config.model_dump_json(indent=4)}"
39
+ f"Connecting to MCP server failed. Please review your server config: {self.server_config.model_dump_json(indent=4)}"
31
40
  )
32
41
 
33
- def _initialize_connection(self, server_config: BaseServerConfig) -> bool:
42
+ def _initialize_connection(self, server_config: BaseServerConfig, timeout: float) -> bool:
34
43
  raise NotImplementedError("Subclasses must implement _initialize_connection")
35
44
 
36
45
  def list_tools(self) -> List[Tool]:
37
46
  self._check_initialized()
38
- response = self.loop.run_until_complete(self.session.list_tools())
39
- return response.tools
47
+ try:
48
+ response = self.loop.run_until_complete(
49
+ asyncio.wait_for(self.session.list_tools(), timeout=tool_settings.mcp_list_tools_timeout)
50
+ )
51
+ return response.tools
52
+ except asyncio.TimeoutError:
53
+ # Could log, throw a custom exception, etc.
54
+ logger.error(
55
+ f"Timed out while listing tools for MCP server {self.server_config.server_name} (timeout={tool_settings.mcp_list_tools_timeout}s)."
56
+ )
57
+ return []
40
58
 
41
59
  def execute_tool(self, tool_name: str, tool_args: dict) -> Tuple[str, bool]:
42
60
  self._check_initialized()
43
- result = self.loop.run_until_complete(self.session.call_tool(tool_name, tool_args))
44
- return str(result.content), result.isError
61
+ try:
62
+ result = self.loop.run_until_complete(
63
+ asyncio.wait_for(self.session.call_tool(tool_name, tool_args), timeout=tool_settings.mcp_execute_tool_timeout)
64
+ )
65
+ return str(result.content), result.isError
66
+ except asyncio.TimeoutError:
67
+ logger.error(
68
+ f"Timed out while executing tool '{tool_name}' for MCP server {self.server_config.server_name} (timeout={tool_settings.mcp_execute_tool_timeout}s)."
69
+ )
70
+ return "", True
45
71
 
46
72
  def _check_initialized(self):
47
73
  if not self.initialized:
@@ -1,21 +1,33 @@
1
+ import asyncio
2
+
1
3
  from mcp import ClientSession
2
4
  from mcp.client.sse import sse_client
3
5
 
4
6
  from letta.functions.mcp_client.base_client import BaseMCPClient
5
7
  from letta.functions.mcp_client.types import SSEServerConfig
8
+ from letta.log import get_logger
6
9
 
7
10
  # see: https://modelcontextprotocol.io/quickstart/user
8
11
  MCP_CONFIG_TOPLEVEL_KEY = "mcpServers"
9
12
 
13
+ logger = get_logger(__name__)
14
+
10
15
 
11
16
  class SSEMCPClient(BaseMCPClient):
12
- def _initialize_connection(self, server_config: SSEServerConfig) -> bool:
13
- sse_cm = sse_client(url=server_config.server_url)
14
- sse_transport = self.loop.run_until_complete(sse_cm.__aenter__())
15
- self.stdio, self.write = sse_transport
16
- self.cleanup_funcs.append(lambda: self.loop.run_until_complete(sse_cm.__aexit__(None, None, None)))
17
+ def _initialize_connection(self, server_config: SSEServerConfig, timeout: float) -> bool:
18
+ try:
19
+ sse_cm = sse_client(url=server_config.server_url)
20
+ sse_transport = self.loop.run_until_complete(asyncio.wait_for(sse_cm.__aenter__(), timeout=timeout))
21
+ self.stdio, self.write = sse_transport
22
+ self.cleanup_funcs.append(lambda: self.loop.run_until_complete(sse_cm.__aexit__(None, None, None)))
17
23
 
18
- session_cm = ClientSession(self.stdio, self.write)
19
- self.session = self.loop.run_until_complete(session_cm.__aenter__())
20
- self.cleanup_funcs.append(lambda: self.loop.run_until_complete(session_cm.__aexit__(None, None, None)))
21
- return True
24
+ session_cm = ClientSession(self.stdio, self.write)
25
+ self.session = self.loop.run_until_complete(asyncio.wait_for(session_cm.__aenter__(), timeout=timeout))
26
+ self.cleanup_funcs.append(lambda: self.loop.run_until_complete(session_cm.__aexit__(None, None, None)))
27
+ return True
28
+ except asyncio.TimeoutError:
29
+ logger.error(f"Timed out while establishing SSE connection (timeout={timeout}s).")
30
+ return False
31
+ except Exception:
32
+ logger.exception("Exception occurred while initializing SSE client session.")
33
+ return False
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  import sys
2
3
  from contextlib import asynccontextmanager
3
4
 
@@ -16,19 +17,23 @@ logger = get_logger(__name__)
16
17
 
17
18
 
18
19
  class StdioMCPClient(BaseMCPClient):
19
- def _initialize_connection(self, server_config: StdioServerConfig) -> bool:
20
+ def _initialize_connection(self, server_config: StdioServerConfig, timeout: float) -> bool:
20
21
  try:
21
22
  server_params = StdioServerParameters(command=server_config.command, args=server_config.args)
22
23
  stdio_cm = forked_stdio_client(server_params)
23
- stdio_transport = self.loop.run_until_complete(stdio_cm.__aenter__())
24
+ stdio_transport = self.loop.run_until_complete(asyncio.wait_for(stdio_cm.__aenter__(), timeout=timeout))
24
25
  self.stdio, self.write = stdio_transport
25
26
  self.cleanup_funcs.append(lambda: self.loop.run_until_complete(stdio_cm.__aexit__(None, None, None)))
26
27
 
27
28
  session_cm = ClientSession(self.stdio, self.write)
28
- self.session = self.loop.run_until_complete(session_cm.__aenter__())
29
+ self.session = self.loop.run_until_complete(asyncio.wait_for(session_cm.__aenter__(), timeout=timeout))
29
30
  self.cleanup_funcs.append(lambda: self.loop.run_until_complete(session_cm.__aexit__(None, None, None)))
30
31
  return True
32
+ except asyncio.TimeoutError:
33
+ logger.error(f"Timed out while establishing stdio connection (timeout={timeout}s).")
34
+ return False
31
35
  except Exception:
36
+ logger.exception("Exception occurred while initializing stdio client session.")
32
37
  return False
33
38
 
34
39
 
@@ -840,7 +840,7 @@ def anthropic_chat_completions_process_stream(
840
840
  # Create a dummy message for ID/datetime if needed
841
841
  dummy_message = _Message(
842
842
  role=_MessageRole.assistant,
843
- text="",
843
+ content=[],
844
844
  agent_id="",
845
845
  model="",
846
846
  name=None,
letta/memory.py CHANGED
@@ -37,7 +37,12 @@ def get_memory_functions(cls: Memory) -> Dict[str, Callable]:
37
37
 
38
38
  def _format_summary_history(message_history: List[Message]):
39
39
  # TODO use existing prompt formatters for this (eg ChatML)
40
- return "\n".join([f"{m.role}: {m.content[0].text}" for m in message_history])
40
+ def get_message_text(content):
41
+ if content and len(content) == 1 and isinstance(content[0], TextContent):
42
+ return content[0].text
43
+ return ""
44
+
45
+ return "\n".join([f"{m.role}: {get_message_text(m.content)}" for m in message_history])
41
46
 
42
47
 
43
48
  def summarize_messages(
letta/schemas/source.py CHANGED
@@ -50,7 +50,12 @@ class SourceCreate(BaseSource):
50
50
  # required
51
51
  name: str = Field(..., description="The name of the source.")
52
52
  # TODO: @matt, make this required after shub makes the FE changes
53
- embedding_config: Optional[EmbeddingConfig] = Field(None, description="The embedding configuration used by the source.")
53
+
54
+ embedding: Optional[str] = Field(None, description="The hande for the embedding config used by the source.")
55
+ embedding_chunk_size: Optional[int] = Field(None, description="The chunk size of the embedding.")
56
+
57
+ # TODO: remove (legacy config)
58
+ embedding_config: Optional[EmbeddingConfig] = Field(None, description="(Legacy) The embedding configuration used by the source.")
54
59
 
55
60
  # optional
56
61
  description: Optional[str] = Field(None, description="The description of the source.")
@@ -256,15 +256,15 @@ def create_application() -> "FastAPI":
256
256
  )
257
257
 
258
258
  # Set up OpenTelemetry tracing
259
- endpoint = os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT")
260
- if endpoint:
261
- print(f"▶ Using OTLP tracing with endpoint: {endpoint}")
259
+ otlp_endpoint = settings.otel_exporter_otlp_endpoint
260
+ if otlp_endpoint:
261
+ print(f"▶ Using OTLP tracing with endpoint: {otlp_endpoint}")
262
262
  env_name_suffix = os.getenv("ENV_NAME")
263
263
  service_name = f"letta-server-{env_name_suffix.lower()}" if env_name_suffix else "letta-server"
264
264
  from letta.tracing import setup_tracing
265
265
 
266
266
  setup_tracing(
267
- endpoint=endpoint,
267
+ endpoint=otlp_endpoint,
268
268
  app=app,
269
269
  service_name=service_name,
270
270
  )
@@ -326,7 +326,7 @@ def start_server(
326
326
  print(f"▶ Server running at: https://{host or 'localhost'}:{port or REST_DEFAULT_PORT}")
327
327
  print(f"▶ View using ADE at: https://app.letta.com/development-servers/local/dashboard\n")
328
328
  uvicorn.run(
329
- app,
329
+ "letta.server.rest_api.app:app",
330
330
  host=host or "localhost",
331
331
  port=port or REST_DEFAULT_PORT,
332
332
  workers=settings.uvicorn_workers,
@@ -345,7 +345,7 @@ def start_server(
345
345
  print(f"▶ View using ADE at: https://app.letta.com/development-servers/local/dashboard\n")
346
346
 
347
347
  uvicorn.run(
348
- app,
348
+ "letta.server.rest_api.app:app",
349
349
  host=host or "localhost",
350
350
  port=port or REST_DEFAULT_PORT,
351
351
  workers=settings.uvicorn_workers,
@@ -76,8 +76,20 @@ def create_source(
76
76
  Create a new data source.
77
77
  """
78
78
  actor = server.user_manager.get_user_or_default(user_id=actor_id)
79
- source = Source(**source_create.model_dump())
80
-
79
+ if not source_create.embedding_config:
80
+ if not source_create.embedding:
81
+ # TODO: modify error type
82
+ raise ValueError("Must specify either embedding or embedding_config in request")
83
+ source_create.embedding_config = server.get_embedding_config_from_handle(
84
+ handle=source_create.embedding,
85
+ embedding_chunk_size=source_create.embedding_chunk_size or constants.DEFAULT_EMBEDDING_CHUNK_SIZE,
86
+ )
87
+ source = Source(
88
+ name=source_create.name,
89
+ embedding_config=source_create.embedding_config,
90
+ description=source_create.description,
91
+ metadata=source_create.metadata,
92
+ )
81
93
  return server.source_manager.create_source(source=source, actor=actor)
82
94
 
83
95
 
@@ -91,6 +103,7 @@ def modify_source(
91
103
  """
92
104
  Update the name or documentation of an existing data source.
93
105
  """
106
+ # TODO: allow updating the handle/embedding config
94
107
  actor = server.user_manager.get_user_or_default(user_id=actor_id)
95
108
  if not server.source_manager.get_source_by_id(source_id=source_id, actor=actor):
96
109
  raise HTTPException(status_code=404, detail=f"Source with id={source_id} does not exist.")
letta/server/server.py CHANGED
@@ -332,14 +332,14 @@ class SyncServer(Server):
332
332
 
333
333
  for server_name, server_config in mcp_server_configs.items():
334
334
  if server_config.type == MCPServerType.SSE:
335
- self.mcp_clients[server_name] = SSEMCPClient()
335
+ self.mcp_clients[server_name] = SSEMCPClient(server_config)
336
336
  elif server_config.type == MCPServerType.STDIO:
337
- self.mcp_clients[server_name] = StdioMCPClient()
337
+ self.mcp_clients[server_name] = StdioMCPClient(server_config)
338
338
  else:
339
339
  raise ValueError(f"Invalid MCP server config: {server_config}")
340
340
 
341
341
  try:
342
- self.mcp_clients[server_name].connect_to_server(server_config)
342
+ self.mcp_clients[server_name].connect_to_server()
343
343
  except Exception as e:
344
344
  logger.error(e)
345
345
  self.mcp_clients.pop(server_name)
@@ -1266,6 +1266,11 @@ class SyncServer(Server):
1266
1266
  # TODO support both command + SSE servers (via config)
1267
1267
  def get_mcp_servers(self) -> dict[str, Union[SSEServerConfig, StdioServerConfig]]:
1268
1268
  """List the MCP servers in the config (doesn't test that they are actually working)"""
1269
+
1270
+ # TODO implement non-flatfile mechanism
1271
+ if not tool_settings.mcp_read_from_config:
1272
+ raise RuntimeError("MCP config file disabled. Enable it in settings.")
1273
+
1269
1274
  mcp_server_list = {}
1270
1275
 
1271
1276
  # Attempt to read from ~/.letta/mcp_config.json
@@ -1326,13 +1331,18 @@ class SyncServer(Server):
1326
1331
 
1327
1332
  def add_mcp_server_to_config(
1328
1333
  self, server_config: Union[SSEServerConfig, StdioServerConfig], allow_upsert: bool = True
1329
- ) -> dict[str, Union[SSEServerConfig, StdioServerConfig]]:
1334
+ ) -> List[Union[SSEServerConfig, StdioServerConfig]]:
1330
1335
  """Add a new server config to the MCP config file"""
1331
1336
 
1337
+ # TODO implement non-flatfile mechanism
1338
+ if not tool_settings.mcp_read_from_config:
1339
+ raise RuntimeError("MCP config file disabled. Enable it in settings.")
1340
+
1332
1341
  # If the config file doesn't exist, throw an error.
1333
1342
  mcp_config_path = os.path.join(constants.LETTA_DIR, constants.MCP_CONFIG_NAME)
1334
1343
  if not os.path.exists(mcp_config_path):
1335
- raise FileNotFoundError(f"MCP config file not found: {mcp_config_path}")
1344
+ # Create the file if it doesn't exist
1345
+ logger.debug(f"MCP config file not found, creating new file at: {mcp_config_path}")
1336
1346
 
1337
1347
  # If the file does exist, attempt to parse it get calling get_mcp_servers
1338
1348
  try:
@@ -1348,13 +1358,13 @@ class SyncServer(Server):
1348
1358
 
1349
1359
  # Attempt to initialize the connection to the server
1350
1360
  if server_config.type == MCPServerType.SSE:
1351
- new_mcp_client = SSEMCPClient()
1361
+ new_mcp_client = SSEMCPClient(server_config)
1352
1362
  elif server_config.type == MCPServerType.STDIO:
1353
- new_mcp_client = StdioMCPClient()
1363
+ new_mcp_client = StdioMCPClient(server_config)
1354
1364
  else:
1355
1365
  raise ValueError(f"Invalid MCP server config: {server_config}")
1356
1366
  try:
1357
- new_mcp_client.connect_to_server(server_config)
1367
+ new_mcp_client.connect_to_server()
1358
1368
  except:
1359
1369
  logger.exception(f"Failed to connect to MCP server: {server_config.server_name}")
1360
1370
  raise RuntimeError(f"Failed to connect to MCP server: {server_config.server_name}")
@@ -1384,9 +1394,14 @@ class SyncServer(Server):
1384
1394
  def delete_mcp_server_from_config(self, server_name: str) -> dict[str, Union[SSEServerConfig, StdioServerConfig]]:
1385
1395
  """Delete a server config from the MCP config file"""
1386
1396
 
1397
+ # TODO implement non-flatfile mechanism
1398
+ if not tool_settings.mcp_read_from_config:
1399
+ raise RuntimeError("MCP config file disabled. Enable it in settings.")
1400
+
1387
1401
  # If the config file doesn't exist, throw an error.
1388
1402
  mcp_config_path = os.path.join(constants.LETTA_DIR, constants.MCP_CONFIG_NAME)
1389
1403
  if not os.path.exists(mcp_config_path):
1404
+ # If the file doesn't exist, raise an error
1390
1405
  raise FileNotFoundError(f"MCP config file not found: {mcp_config_path}")
1391
1406
 
1392
1407
  # If the file does exist, attempt to parse it get calling get_mcp_servers
letta/settings.py CHANGED
@@ -18,6 +18,12 @@ class ToolSettings(BaseSettings):
18
18
  # Local Sandbox configurations
19
19
  local_sandbox_dir: Optional[str] = None
20
20
 
21
+ # MCP settings
22
+ mcp_connect_to_server_timeout: float = 15.0
23
+ mcp_list_tools_timeout: float = 10.0
24
+ mcp_execute_tool_timeout: float = 60.0
25
+ mcp_read_from_config: bool = True # if False, will throw if attempting to read/write from file
26
+
21
27
 
22
28
  class SummarizerSettings(BaseSettings):
23
29
  model_config = SettingsConfigDict(env_prefix="letta_summarizer_", extra="ignore")
@@ -3,16 +3,18 @@ from typing import List, Optional
3
3
  from letta.agent import Agent, AgentState
4
4
  from letta.constants import DEFAULT_MESSAGE_TOOL
5
5
  from letta.functions.function_sets.multi_agent import send_message_to_all_agents_in_group
6
+ from letta.functions.functions import parse_source_code
7
+ from letta.functions.schema_generator import generate_schema
6
8
  from letta.interface import AgentInterface
7
9
  from letta.orm import User
8
10
  from letta.orm.enums import ToolType
9
11
  from letta.schemas.letta_message_content import TextContent
10
12
  from letta.schemas.message import Message, MessageCreate
13
+ from letta.schemas.tool import Tool
11
14
  from letta.schemas.tool_rule import ChildToolRule, InitToolRule, TerminalToolRule
12
15
  from letta.schemas.usage import LettaUsageStatistics
13
16
  from letta.services.agent_manager import AgentManager
14
17
  from letta.services.tool_manager import ToolManager
15
- from tests.helpers.utils import create_tool_from_func
16
18
 
17
19
 
18
20
  class SupervisorMultiAgent(Agent):
@@ -47,7 +49,14 @@ class SupervisorMultiAgent(Agent):
47
49
 
48
50
  # add multi agent tool
49
51
  if self.tool_manager.get_tool_by_name(tool_name="send_message_to_all_agents_in_group", actor=self.user) is None:
50
- multi_agent_tool = create_tool_from_func(send_message_to_all_agents_in_group)
52
+ multi_agent_tool = Tool(
53
+ name=send_message_to_all_agents_in_group.__name__,
54
+ description="",
55
+ source_type="python",
56
+ tags=[],
57
+ source_code=parse_source_code(send_message_to_all_agents_in_group),
58
+ json_schema=generate_schema(send_message_to_all_agents_in_group, None),
59
+ )
51
60
  multi_agent_tool.tool_type = ToolType.LETTA_MULTI_AGENT_CORE
52
61
  multi_agent_tool = self.tool_manager.create_or_update_tool(
53
62
  pydantic_tool=multi_agent_tool,
letta/tracing.py CHANGED
@@ -90,8 +90,8 @@ async def trace_error_handler(_request: Request, exc: Exception) -> JSONResponse
90
90
  # Add error details to current span
91
91
  span = trace.get_current_span()
92
92
  if span:
93
- span.add_event(
94
- name="exception",
93
+ span.record_exception(
94
+ exc,
95
95
  attributes={
96
96
  "exception.message": error_msg,
97
97
  "exception.type": type(exc).__name__,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.6.41.dev20250317104157
3
+ Version: 0.6.42.dev20250317175208
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -19,7 +19,7 @@ letta/constants.py,sha256=_QI06HD6yLmGFrTqexLkUnUWSsKUiBlM1QtbiLGEq4k,7773
19
19
  letta/data_sources/connectors.py,sha256=R2AssXpqS7wN6VI8AfxvqaZs5S1ZACc4E_FewmR9iZI,7022
20
20
  letta/data_sources/connectors_helper.py,sha256=oQpVlc-BjSz9sTZ7sp4PsJSXJbBKpZPi3Dam03CURTQ,3376
21
21
  letta/dynamic_multi_agent.py,sha256=syJ-uODfZR_OHd4Acx19yMvjSJ2jwjyX0SOPaeLsZ38,12056
22
- letta/embeddings.py,sha256=zqlfbN3aCgSOlNd9M2NW9zrwx4WwQzketb8oa5BzzE8,10831
22
+ letta/embeddings.py,sha256=0XHDkca0cXvqSEU06fWfpSfOODU_3HcqDaSh6kuP6EM,11115
23
23
  letta/errors.py,sha256=6fQXg2unP-2fo3R7db0ayKKWlD2XMusOPNi9TgJplCg,5558
24
24
  letta/functions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  letta/functions/ast_parsers.py,sha256=CQI0rUoIXcLKAev_GYrXcldRIGN5ZQtk5u4FLoHe5sE,5728
@@ -30,9 +30,9 @@ letta/functions/functions.py,sha256=NyWLh7a-f4mXti5vM1oWDwXzfA58VmVVqL03O9vosKY,
30
30
  letta/functions/helpers.py,sha256=0I-ezZeM3slhAifpdlR5k2Rn6GxExD6xACCKuoYmE8M,29119
31
31
  letta/functions/interface.py,sha256=s_PPp5WDvGH_y9KUpMlORkdC141ITczFk3wsevrrUD8,2866
32
32
  letta/functions/mcp_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- letta/functions/mcp_client/base_client.py,sha256=uHp4XuXFy3avCkc3XYr1IxEPTHZWADqrDk-kR-oFyLY,2144
34
- letta/functions/mcp_client/sse_client.py,sha256=VElaM87sEMTvam4t3IJgWGhyqs5BL4YVErqVPv2hQug,961
35
- letta/functions/mcp_client/stdio_client.py,sha256=qy9vHB99oI4pCAQ4KmQUKY0bTboaQI4pnPm9DPQfPvY,4210
33
+ letta/functions/mcp_client/base_client.py,sha256=n2j1wEDopF8BkivkqrZDWrq3I2gChVfkQ0MgH4Iyg1I,3507
34
+ letta/functions/mcp_client/sse_client.py,sha256=XOLnWIcrjBEkZ-IksgnHKSdVds3pC2E8OPkIhCNxloo,1470
35
+ letta/functions/mcp_client/stdio_client.py,sha256=2oouLGphu4S15OrYj97n9_ZYZo-GMRWNLWwaw-U4TNs,4562
36
36
  letta/functions/mcp_client/types.py,sha256=nmcnQn2EpxXzXg5_pWPsHZobfxO6OucaUgz1bVvam7o,1411
37
37
  letta/functions/schema_generator.py,sha256=4hiDQpHemyfKWME-5X6xJuSiv7g9V_BgAPFegohHBIM,22327
38
38
  letta/helpers/__init__.py,sha256=p0luQ1Oe3Skc6sH4O58aHHA3Qbkyjifpuq0DZ1GAY0U,59
@@ -50,7 +50,7 @@ letta/interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
50
50
  letta/interfaces/openai_chat_completions_streaming_interface.py,sha256=SfqVp7V7AbBqv8D_IwyqrcztNiI0nKhjAvqtZQE_jfM,4729
51
51
  letta/interfaces/utils.py,sha256=c6jvO0dBYHh8DQnlN-B0qeNC64d3CSunhfqlFA4pJTY,278
52
52
  letta/llm_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
- letta/llm_api/anthropic.py,sha256=pDj9W_Myz4fe05eoMiApO45G8jqzVoO9QyfFpCs-uV0,38360
53
+ letta/llm_api/anthropic.py,sha256=XHmy2MJvV6y-Rc-GOv2M8xdaB5jmEcp7SMKI2Wc4izw,38363
54
54
  letta/llm_api/aws_bedrock.py,sha256=J_oCM810-m2T-tgo3iRwSM0BuykBN5AK3SbkyiOaGbc,3835
55
55
  letta/llm_api/azure_openai.py,sha256=GP50e3WyoU2O_vb_b06GYTA1S157I0G21lF9-qv9nsA,6459
56
56
  letta/llm_api/azure_openai_constants.py,sha256=ZaR2IasJThijG0uhLKJThrixdAxLPD2IojfeaJ-KQMQ,294
@@ -106,7 +106,7 @@ letta/local_llm/webui/legacy_settings.py,sha256=BLmd3TSx5StnY3ibjwaxYATPt_Lvq-o1
106
106
  letta/local_llm/webui/settings.py,sha256=gmLHfiOl1u4JmlAZU2d2O8YKF9lafdakyjwR_ftVPh8,552
107
107
  letta/log.py,sha256=FbFwU9KEX7k0FBYhPl7fJ6uQ3NO3-ZbsnM2OpcTFXjo,2217
108
108
  letta/main.py,sha256=_agyaYPJq70OL0goNwO34zENL2KupnTgqlg-HVcNaTY,15379
109
- letta/memory.py,sha256=JjKripPdzsCxXCPYBmFP_yRVN_PSqEQW5s8EKK-Mt9M,3411
109
+ letta/memory.py,sha256=dGzMdYYG1Mhan9POLcmyI6fVL7Xs8TEozWfAo4v1QQo,3592
110
110
  letta/offline_memory_agent.py,sha256=P_rm6GmKAH6lg7-njuv7dK29f7v5-tAQy-rMOwcPfwk,7499
111
111
  letta/openai_backcompat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
112
112
  letta/openai_backcompat/openai_object.py,sha256=GSzeCTwLpLD2fH4X8wVqzwdmoTjKK2I4PnriBY453lc,13505
@@ -201,7 +201,7 @@ letta/schemas/passage.py,sha256=RG0vkaewEu4a_NAZM-FVyMammHjqpPP0RDYAdu27g6A,3723
201
201
  letta/schemas/providers.py,sha256=2Ijzjj1gPETiFyl8yb4ZbwaTljw5WSCdGayAgCsBeYE,43665
202
202
  letta/schemas/run.py,sha256=SRqPRziINIiPunjOhE_NlbnQYgxTvqmbauni_yfBQRA,2085
203
203
  letta/schemas/sandbox_config.py,sha256=SZCo3FSMz-DIBMKGu0atT4tsVFXGsqMFPaJnjrxpkX4,5993
204
- letta/schemas/source.py,sha256=-BQVolcXA2ziCu2ztR6cbTdGUc8G7vGJy7rvpdf1hpg,2880
204
+ letta/schemas/source.py,sha256=IuenIFs7B8uOuYJIHXqR1E28wVSa-pUX6NkLZH7cukg,3141
205
205
  letta/schemas/step.py,sha256=WkcVnruUUOWLKwiWPn2Gfal4EQZPNLqlsd9859xhgsw,2224
206
206
  letta/schemas/tool.py,sha256=PXWxEqzM-kADijlsJzu0ZYtWLnjpq4ZUNX4NzesIWNQ,12291
207
207
  letta/schemas/tool_rule.py,sha256=2YQZba4fXS3u4j8pIk7BDujfq8rnxSVMwJSyaVgApH4,2149
@@ -222,7 +222,7 @@ letta/server/constants.py,sha256=yAdGbLkzlOU_dLTx0lKDmAnj0ZgRXCEaIcPJWO69eaE,92
222
222
  letta/server/db.py,sha256=cA1MHpMCTTC1MX7VWppJ-cKq1XW93Vws_vTV0-bKmTE,3642
223
223
  letta/server/generate_openapi_schema.sh,sha256=0OtBhkC1g6CobVmNEd_m2B6sTdppjbJLXaM95icejvE,371
224
224
  letta/server/rest_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
225
- letta/server/rest_api/app.py,sha256=gP558sE9dY4914GYVPuypPwYiGHaVtfeWSsOUZBq67c,13618
225
+ letta/server/rest_api/app.py,sha256=Uo1m8Fefae2_s1RhhkJgaDRJUJP7z6bFRAvbetCOoEE,13690
226
226
  letta/server/rest_api/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
227
227
  letta/server/rest_api/auth/index.py,sha256=fQBGyVylGSRfEMLQ17cZzrHd5Y1xiVylvPqH5Rl-lXQ,1378
228
228
  letta/server/rest_api/auth_token.py,sha256=725EFEIiNj4dh70hrSd94UysmFD8vcJLrTRfNHkzxDo,774
@@ -244,7 +244,7 @@ letta/server/rest_api/routers/v1/organizations.py,sha256=8n-kA9LHtKImdY2xL-v7m6n
244
244
  letta/server/rest_api/routers/v1/providers.py,sha256=qyZsNTXgLVsoLZoCVY4qaqiG34zCEVmRUP2Cn6maK_4,2949
245
245
  letta/server/rest_api/routers/v1/runs.py,sha256=-2_YA2nuxcLqiPjG9CPHeZbyrtlNQZnAsaNohGn5fMg,8278
246
246
  letta/server/rest_api/routers/v1/sandbox_configs.py,sha256=9hqnnMwJ3wCwO-Bezu3Xl8i3TDSIuInw3gSeHaKUXfE,8526
247
- letta/server/rest_api/routers/v1/sources.py,sha256=rpQhaRHyzGUK43LX623L8BBLqL85HJ6fUYPMvI4k3kA,8434
247
+ letta/server/rest_api/routers/v1/sources.py,sha256=-3JB2ohr4hqkB7Zw0frTG1PN2KplU1SRr2mLX6KXJ44,9104
248
248
  letta/server/rest_api/routers/v1/steps.py,sha256=DVVwaxLNbNAgWpr2oQkrNjdS-wi0bP8kVJZUO-hiaf8,3275
249
249
  letta/server/rest_api/routers/v1/tags.py,sha256=coydgvL6-9cuG2Hy5Ea7QY3inhTHlsf69w0tcZenBus,880
250
250
  letta/server/rest_api/routers/v1/tools.py,sha256=pWIlYUksq9QNFSmknB_DdSB5zs77zaHoj-Ha-WxYkO8,17211
@@ -252,7 +252,7 @@ letta/server/rest_api/routers/v1/users.py,sha256=G5DBHSkPfBgVHN2Wkm-rVYiLQAudwQc
252
252
  letta/server/rest_api/routers/v1/voice.py,sha256=7J0L-Nkz65m0PXcpQI2ATMIZzumDDSUzgtIus7d-tv8,2461
253
253
  letta/server/rest_api/static_files.py,sha256=NG8sN4Z5EJ8JVQdj19tkFa9iQ1kBPTab9f_CUxd_u4Q,3143
254
254
  letta/server/rest_api/utils.py,sha256=aF0u__Q33-aPWAiHi9JA0jKAjqnwbVKzJdD5NgFpnOU,13828
255
- letta/server/server.py,sha256=Ml4-MklB28x3iAONfp3m2oSbrhVctAvvxUWApeWIWrk,75884
255
+ letta/server/server.py,sha256=SvD9N9usvwm44MBBKDNETOjKp2DlT9KggqdQF0L5BiE,76572
256
256
  letta/server/startup.sh,sha256=2S_MuvYYY5YZQOYBL-7mq2CC-A7Hhwyd9be2QqmNqzA,2514
257
257
  letta/server/static_files/assets/index-048c9598.js,sha256=mR16XppvselwKCcNgONs4L7kZEVa4OEERm4lNZYtLSk,146819
258
258
  letta/server/static_files/assets/index-0e31b727.css,sha256=SBbja96uiQVLDhDOroHgM6NSl7tS4lpJRCREgSS_hA8,7672
@@ -287,15 +287,15 @@ letta/services/summarizer/summarizer.py,sha256=qPcR7VsHsgUsUtxmKx_73l3XdDhFvDzZ8
287
287
  letta/services/tool_execution_sandbox.py,sha256=6AB3rFS34PzoyE9dxtUmuaUUWvKrwdE083NuBRa1eC0,22969
288
288
  letta/services/tool_manager.py,sha256=rXOdB2quTWE9EGjkg9Q4EY6-hAwX2R9gGBCXFs8hR4w,9862
289
289
  letta/services/user_manager.py,sha256=ScHbdJK9kNF8QXjsd3ZWGEL87n_Uyp3YwfKetOJmpHs,4304
290
- letta/settings.py,sha256=W3gFFywjk6CKbWTSlj0zXGyzl8CJUrQJgMLvq2sKEWA,7074
290
+ letta/settings.py,sha256=RfnxS_ga96XP8WuYfqq6aDTHoFJRFPjrCse3_Hh98M4,7326
291
291
  letta/streaming_interface.py,sha256=1vuAckIxo1p1UsXtDzE8LTUve5RoTZRdXUe-WBIYDWU,15818
292
292
  letta/streaming_utils.py,sha256=jLqFTVhUL76FeOuYk8TaRQHmPTf3HSRc2EoJwxJNK6U,11946
293
- letta/supervisor_multi_agent.py,sha256=dw6XPAxZcyjAXEVYkMIxJFhZdR2m2_rq-fYev5hZE50,3936
293
+ letta/supervisor_multi_agent.py,sha256=jMy0J-a1_u5ZCulweXwJ98SgF6Hnvwxh1L3_wavnTi4,4330
294
294
  letta/system.py,sha256=dnOrS2FlRMwijQnOvfrky0Lg8wEw-FUq2zzfAJOUSKA,8477
295
- letta/tracing.py,sha256=e1dNfdMI__38E-_xMxPrxyM5mSGil8Od1tSbf_UNWaY,8004
295
+ letta/tracing.py,sha256=bBdz-SC63XKGCpgOYGwisrfhLARLsE3lc_VgNliDbgI,7998
296
296
  letta/utils.py,sha256=AdHrQ2OQ3V4XhJ1LtYwbLUO71j2IJY37cIUxXPgaaRY,32125
297
- letta_nightly-0.6.41.dev20250317104157.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
298
- letta_nightly-0.6.41.dev20250317104157.dist-info/METADATA,sha256=Tg27LnMLvS_yubSnumqbGU_5pXTCdM0V-BzpEMywOKs,22886
299
- letta_nightly-0.6.41.dev20250317104157.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
300
- letta_nightly-0.6.41.dev20250317104157.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
301
- letta_nightly-0.6.41.dev20250317104157.dist-info/RECORD,,
297
+ letta_nightly-0.6.42.dev20250317175208.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
298
+ letta_nightly-0.6.42.dev20250317175208.dist-info/METADATA,sha256=nolr8bOVDnAG6s7M29v217CuLURz0BgK2qGHNt-OMbI,22886
299
+ letta_nightly-0.6.42.dev20250317175208.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
300
+ letta_nightly-0.6.42.dev20250317175208.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
301
+ letta_nightly-0.6.42.dev20250317175208.dist-info/RECORD,,