letta-nightly 0.7.5.dev20250427104041__py3-none-any.whl → 0.7.6.dev20250429062643__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.
Files changed (33) hide show
  1. letta/__init__.py +1 -1
  2. letta/agents/base_agent.py +1 -1
  3. letta/agents/ephemeral_memory_agent.py +353 -43
  4. letta/agents/voice_agent.py +196 -62
  5. letta/constants.py +2 -0
  6. letta/helpers/datetime_helpers.py +7 -0
  7. letta/interfaces/openai_chat_completions_streaming_interface.py +16 -12
  8. letta/llm_api/google_ai_client.py +4 -0
  9. letta/llm_api/llm_api_tools.py +5 -2
  10. letta/llm_api/openai.py +2 -1
  11. letta/llm_api/openai_client.py +3 -2
  12. letta/schemas/llm_config.py +5 -1
  13. letta/schemas/openai/chat_completion_request.py +1 -0
  14. letta/schemas/providers.py +4 -3
  15. letta/schemas/sandbox_config.py +4 -4
  16. letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +4 -10
  17. letta/server/rest_api/routers/v1/voice.py +8 -18
  18. letta/server/rest_api/utils.py +26 -20
  19. letta/server/server.py +67 -26
  20. letta/services/helpers/agent_manager_helper.py +2 -2
  21. letta/services/helpers/tool_execution_helper.py +30 -3
  22. letta/services/summarizer/summarizer.py +121 -54
  23. letta/services/tool_executor/tool_execution_sandbox.py +13 -9
  24. letta/services/tool_sandbox/local_sandbox.py +4 -4
  25. letta/services/user_manager.py +5 -2
  26. letta/settings.py +4 -2
  27. letta/system.py +0 -1
  28. letta/tracing.py +1 -0
  29. {letta_nightly-0.7.5.dev20250427104041.dist-info → letta_nightly-0.7.6.dev20250429062643.dist-info}/METADATA +1 -1
  30. {letta_nightly-0.7.5.dev20250427104041.dist-info → letta_nightly-0.7.6.dev20250429062643.dist-info}/RECORD +33 -33
  31. {letta_nightly-0.7.5.dev20250427104041.dist-info → letta_nightly-0.7.6.dev20250429062643.dist-info}/LICENSE +0 -0
  32. {letta_nightly-0.7.5.dev20250427104041.dist-info → letta_nightly-0.7.6.dev20250429062643.dist-info}/WHEEL +0 -0
  33. {letta_nightly-0.7.5.dev20250427104041.dist-info → letta_nightly-0.7.6.dev20250429062643.dist-info}/entry_points.txt +0 -0
@@ -1,13 +1,17 @@
1
+ import asyncio
1
2
  import json
2
- from json import JSONDecodeError
3
+ import traceback
3
4
  from typing import List, Tuple
4
5
 
5
- from letta.agents.base_agent import BaseAgent
6
+ from letta.agents.ephemeral_memory_agent import EphemeralMemoryAgent
7
+ from letta.log import get_logger
6
8
  from letta.schemas.enums import MessageRole
7
9
  from letta.schemas.letta_message_content import TextContent
8
10
  from letta.schemas.message import Message, MessageCreate
9
11
  from letta.services.summarizer.enums import SummarizationMode
10
12
 
13
+ logger = get_logger(__name__)
14
+
11
15
 
12
16
  class Summarizer:
13
17
  """
@@ -16,7 +20,9 @@ class Summarizer:
16
20
  static buffer approach but leave room for more advanced strategies.
17
21
  """
18
22
 
19
- def __init__(self, mode: SummarizationMode, summarizer_agent: BaseAgent, message_buffer_limit: int = 10, message_buffer_min: int = 3):
23
+ def __init__(
24
+ self, mode: SummarizationMode, summarizer_agent: EphemeralMemoryAgent, message_buffer_limit: int = 10, message_buffer_min: int = 3
25
+ ):
20
26
  self.mode = mode
21
27
 
22
28
  # Need to do validation on this
@@ -24,11 +30,8 @@ class Summarizer:
24
30
  self.message_buffer_min = message_buffer_min
25
31
  self.summarizer_agent = summarizer_agent
26
32
  # TODO: Move this to config
27
- self.summary_prefix = "Out of context message summarization:\n"
28
33
 
29
- async def summarize(
30
- self, in_context_messages: List[Message], new_letta_messages: List[Message], previous_summary: str
31
- ) -> Tuple[List[Message], str, bool]:
34
+ def summarize(self, in_context_messages: List[Message], new_letta_messages: List[Message]) -> Tuple[List[Message], bool]:
32
35
  """
33
36
  Summarizes or trims in_context_messages according to the chosen mode,
34
37
  and returns the updated messages plus any optional "summary message".
@@ -36,7 +39,6 @@ class Summarizer:
36
39
  Args:
37
40
  in_context_messages: The existing messages in the conversation's context.
38
41
  new_letta_messages: The newly added Letta messages (just appended).
39
- previous_summary: The previous summary string.
40
42
 
41
43
  Returns:
42
44
  (updated_messages, summary_message)
@@ -45,65 +47,130 @@ class Summarizer:
45
47
  (could be appended to the conversation if desired)
46
48
  """
47
49
  if self.mode == SummarizationMode.STATIC_MESSAGE_BUFFER:
48
- return await self._static_buffer_summarization(in_context_messages, new_letta_messages, previous_summary)
50
+ return self._static_buffer_summarization(in_context_messages, new_letta_messages)
49
51
  else:
50
52
  # Fallback or future logic
51
- return in_context_messages, "", False
53
+ return in_context_messages, False
54
+
55
+ def fire_and_forget(self, coro):
56
+ task = asyncio.create_task(coro)
57
+
58
+ def callback(t):
59
+ try:
60
+ t.result() # This re-raises exceptions from the task
61
+ except Exception:
62
+ logger.error("Background task failed: %s", traceback.format_exc())
52
63
 
53
- async def _static_buffer_summarization(
54
- self, in_context_messages: List[Message], new_letta_messages: List[Message], previous_summary: str
55
- ) -> Tuple[List[Message], str, bool]:
56
- previous_summary = previous_summary[: len(self.summary_prefix)]
64
+ task.add_done_callback(callback)
65
+ return task
66
+
67
+ def _static_buffer_summarization(
68
+ self, in_context_messages: List[Message], new_letta_messages: List[Message]
69
+ ) -> Tuple[List[Message], bool]:
57
70
  all_in_context_messages = in_context_messages + new_letta_messages
58
71
 
59
- # Only summarize if we exceed `message_buffer_limit`
60
72
  if len(all_in_context_messages) <= self.message_buffer_limit:
61
- return all_in_context_messages, previous_summary, False
73
+ logger.info(
74
+ f"Nothing to evict, returning in context messages as is. Current buffer length is {len(all_in_context_messages)}, limit is {self.message_buffer_limit}."
75
+ )
76
+ return all_in_context_messages, False
77
+
78
+ logger.info("Buffer length hit, evicting messages.")
62
79
 
63
- # Aim to trim down to `message_buffer_min`
64
80
  target_trim_index = len(all_in_context_messages) - self.message_buffer_min + 1
65
81
 
66
- # Move the trim index forward until it's at a `MessageRole.user`
67
82
  while target_trim_index < len(all_in_context_messages) and all_in_context_messages[target_trim_index].role != MessageRole.user:
68
83
  target_trim_index += 1
69
84
 
70
- # TODO: Assuming system message is always at index 0
71
- updated_in_context_messages = [all_in_context_messages[0]] + all_in_context_messages[target_trim_index:]
72
- out_of_context_messages = all_in_context_messages[:target_trim_index]
85
+ updated_in_context_messages = all_in_context_messages[target_trim_index:]
73
86
 
74
- formatted_messages = []
75
- for m in out_of_context_messages:
76
- if m.content:
77
- try:
78
- message = json.loads(m.content[0].text).get("message")
79
- except JSONDecodeError:
80
- continue
81
- if message:
82
- formatted_messages.append(f"{m.role.value}: {message}")
83
-
84
- # If we didn't trim any messages, return as-is
85
- if not formatted_messages:
86
- return all_in_context_messages, previous_summary, False
87
-
88
- # Generate summarization request
89
- summary_request_text = (
90
- "These are messages that are soon to be removed from the context window:\n"
91
- f"{formatted_messages}\n\n"
92
- "This is the current memory:\n"
93
- f"{previous_summary}\n\n"
94
- "Your task is to integrate any relevant updates from the messages into the memory."
95
- "It should be in note-taking format in natural English. You are to return the new, updated memory only."
96
- )
87
+ # Target trim index went beyond end of all_in_context_messages
88
+ if not updated_in_context_messages:
89
+ logger.info("Nothing to evict, returning in context messages as is.")
90
+ return all_in_context_messages, False
91
+
92
+ evicted_messages = all_in_context_messages[1:target_trim_index]
93
+
94
+ # Format
95
+ formatted_evicted_messages = format_transcript(evicted_messages)
96
+ formatted_in_context_messages = format_transcript(updated_in_context_messages)
97
+
98
+ # Update the message transcript of the memory agent
99
+ self.summarizer_agent.update_message_transcript(message_transcripts=formatted_evicted_messages + formatted_in_context_messages)
100
+
101
+ # Add line numbers to the formatted messages
102
+ line_number = 0
103
+ for i in range(len(formatted_evicted_messages)):
104
+ formatted_evicted_messages[i] = f"{line_number}. " + formatted_evicted_messages[i]
105
+ line_number += 1
106
+ for i in range(len(formatted_in_context_messages)):
107
+ formatted_in_context_messages[i] = f"{line_number}. " + formatted_in_context_messages[i]
108
+ line_number += 1
109
+
110
+ evicted_messages_str = "\n".join(formatted_evicted_messages)
111
+ in_context_messages_str = "\n".join(formatted_in_context_messages)
112
+ summary_request_text = f"""You are a specialized memory recall agent assisting another AI agent by asynchronously reorganizing its memory storage. The LLM agent you are helping maintains a limited context window that retains only the most recent {self.message_buffer_min} messages from its conversations. The provided conversation history includes messages that are about to be evicted from its context window, as well as some additional recent messages for extra clarity and context.
97
113
 
98
- response = await self.summarizer_agent.step(
99
- input_messages=[
100
- MessageCreate(
101
- role=MessageRole.user,
102
- content=[TextContent(text=summary_request_text)],
103
- ),
104
- ],
114
+ Your task is to carefully review the provided conversation history and proactively generate detailed, relevant memories about the human participant, specifically targeting information contained in messages that are about to be evicted from the context window. Your notes will help preserve critical insights, events, or facts that would otherwise be forgotten.
115
+
116
+ (Older) Evicted Messages:
117
+ {evicted_messages_str}
118
+
119
+ (Newer) In-Context Messages:
120
+ {in_context_messages_str}
121
+ """
122
+
123
+ # Fire-and-forget the summarization task
124
+ self.fire_and_forget(
125
+ self.summarizer_agent.step([MessageCreate(role=MessageRole.user, content=[TextContent(text=summary_request_text)])])
105
126
  )
106
- current_summary = "\n".join([m.content[0].text for m in response.messages if m.message_type == "assistant_message"])
107
- current_summary = f"{self.summary_prefix}{current_summary}"
108
127
 
109
- return updated_in_context_messages, current_summary, True
128
+ return [all_in_context_messages[0]] + updated_in_context_messages, True
129
+
130
+
131
+ def format_transcript(messages: List[Message], include_system: bool = False) -> List[str]:
132
+ """
133
+ Turn a list of Message objects into a human-readable transcript.
134
+
135
+ Args:
136
+ messages: List of Message instances, in chronological order.
137
+ include_system: If True, include system-role messages. Defaults to False.
138
+
139
+ Returns:
140
+ A single string, e.g.:
141
+ user: Hey, my name is Matt.
142
+ assistant: Hi Matt! It's great to meet you...
143
+ user: What's the weather like? ...
144
+ assistant: The weather in Las Vegas is sunny...
145
+ """
146
+ lines = []
147
+ for msg in messages:
148
+ role = msg.role.value # e.g. 'user', 'assistant', 'system', 'tool'
149
+ # skip system messages by default
150
+ if role == "system" and not include_system:
151
+ continue
152
+
153
+ # 1) Try plain content
154
+ if msg.content:
155
+ text = "".join(c.text for c in msg.content).strip()
156
+
157
+ # 2) Otherwise, try extracting from function calls
158
+ elif msg.tool_calls:
159
+ parts = []
160
+ for call in msg.tool_calls:
161
+ args_str = call.function.arguments
162
+ try:
163
+ args = json.loads(args_str)
164
+ # pull out a "message" field if present
165
+ parts.append(args.get("message", args_str))
166
+ except json.JSONDecodeError:
167
+ parts.append(args_str)
168
+ text = " ".join(parts).strip()
169
+
170
+ else:
171
+ # nothing to show for this message
172
+ continue
173
+
174
+ lines.append(f"{role}: {text}")
175
+
176
+ return lines
@@ -144,7 +144,7 @@ class ToolExecutionSandbox:
144
144
 
145
145
  # Write the code to a temp file in the sandbox_dir
146
146
  with tempfile.NamedTemporaryFile(mode="w", dir=local_configs.sandbox_dir, suffix=".py", delete=False) as temp_file:
147
- if local_configs.force_create_venv:
147
+ if local_configs.use_venv:
148
148
  # If using venv, we need to wrap with special string markers to separate out the output and the stdout (since it is all in stdout)
149
149
  code = self.generate_execution_script(agent_state=agent_state, wrap_print_with_markers=True)
150
150
  else:
@@ -154,7 +154,7 @@ class ToolExecutionSandbox:
154
154
  temp_file.flush()
155
155
  temp_file_path = temp_file.name
156
156
  try:
157
- if local_configs.force_create_venv:
157
+ if local_configs.use_venv:
158
158
  return self.run_local_dir_sandbox_venv(sbx_config, env, temp_file_path)
159
159
  else:
160
160
  return self.run_local_dir_sandbox_directly(sbx_config, env, temp_file_path)
@@ -220,7 +220,11 @@ class ToolExecutionSandbox:
220
220
  )
221
221
 
222
222
  except subprocess.CalledProcessError as e:
223
+ with open(temp_file_path, "r") as f:
224
+ code = f.read()
225
+
223
226
  logger.error(f"Executing tool {self.tool_name} has process error: {e}")
227
+ logger.error(f"Logging out tool {self.tool_name} auto-generated code for debugging: \n\n{code}")
224
228
  func_return = get_friendly_error_msg(
225
229
  function_name=self.tool_name,
226
230
  exception_name=type(e).__name__,
@@ -447,6 +451,11 @@ class ToolExecutionSandbox:
447
451
  Returns:
448
452
  code (str): The generated code strong
449
453
  """
454
+ if "agent_state" in self.parse_function_arguments(self.tool.source_code, self.tool.name):
455
+ inject_agent_state = True
456
+ else:
457
+ inject_agent_state = False
458
+
450
459
  # dump JSON representation of agent state to re-load
451
460
  code = "from typing import *\n"
452
461
  code += "import pickle\n"
@@ -454,7 +463,7 @@ class ToolExecutionSandbox:
454
463
  code += "import base64\n"
455
464
 
456
465
  # imports to support agent state
457
- if agent_state:
466
+ if inject_agent_state:
458
467
  code += "import letta\n"
459
468
  code += "from letta import * \n"
460
469
  import pickle
@@ -467,7 +476,7 @@ class ToolExecutionSandbox:
467
476
  code += schema_code + "\n"
468
477
 
469
478
  # load the agent state
470
- if agent_state:
479
+ if inject_agent_state:
471
480
  agent_state_pickle = pickle.dumps(agent_state)
472
481
  code += f"agent_state = pickle.loads({agent_state_pickle})\n"
473
482
  else:
@@ -483,11 +492,6 @@ class ToolExecutionSandbox:
483
492
  for param in self.args:
484
493
  code += self.initialize_param(param, self.args[param])
485
494
 
486
- if "agent_state" in self.parse_function_arguments(self.tool.source_code, self.tool.name):
487
- inject_agent_state = True
488
- else:
489
- inject_agent_state = False
490
-
491
495
  code += "\n" + self.tool.source_code + "\n"
492
496
 
493
497
  # TODO: handle wrapped print
@@ -69,7 +69,7 @@ class AsyncToolSandboxLocal(AsyncToolSandboxBase):
69
69
  else:
70
70
  sbx_config = self.sandbox_config_manager.get_or_create_default_sandbox_config(sandbox_type=SandboxType.LOCAL, actor=self.user)
71
71
  local_configs = sbx_config.get_local_config()
72
- force_create_venv = local_configs.force_create_venv
72
+ use_venv = local_configs.use_venv
73
73
 
74
74
  # Prepare environment variables
75
75
  env = os.environ.copy()
@@ -92,7 +92,7 @@ class AsyncToolSandboxLocal(AsyncToolSandboxBase):
92
92
 
93
93
  # If using a virtual environment, ensure it's prepared in parallel
94
94
  venv_preparation_task = None
95
- if force_create_venv:
95
+ if use_venv:
96
96
  venv_path = str(os.path.join(sandbox_dir, local_configs.venv_name))
97
97
  venv_preparation_task = asyncio.create_task(self._prepare_venv(local_configs, venv_path, env))
98
98
 
@@ -110,7 +110,7 @@ class AsyncToolSandboxLocal(AsyncToolSandboxBase):
110
110
 
111
111
  # Determine the python executable and environment for the subprocess
112
112
  exec_env = env.copy()
113
- if force_create_venv:
113
+ if use_venv:
114
114
  venv_path = str(os.path.join(sandbox_dir, local_configs.venv_name))
115
115
  python_executable = find_python_executable(local_configs)
116
116
  exec_env["VIRTUAL_ENV"] = venv_path
@@ -174,7 +174,7 @@ class AsyncToolSandboxLocal(AsyncToolSandboxBase):
174
174
  )
175
175
 
176
176
  try:
177
- stdout_bytes, stderr_bytes = await asyncio.wait_for(process.communicate(), timeout=tool_settings.local_sandbox_timeout)
177
+ stdout_bytes, stderr_bytes = await asyncio.wait_for(process.communicate(), timeout=tool_settings.tool_sandbox_timeout)
178
178
  except asyncio.TimeoutError:
179
179
  # Terminate the process on timeout
180
180
  if process.returncode is None:
@@ -84,8 +84,11 @@ class UserManager:
84
84
 
85
85
  @enforce_types
86
86
  def get_default_user(self) -> PydanticUser:
87
- """Fetch the default user."""
88
- return self.get_user_by_id(self.DEFAULT_USER_ID)
87
+ """Fetch the default user. If it doesn't exist, create it."""
88
+ try:
89
+ return self.get_user_by_id(self.DEFAULT_USER_ID)
90
+ except NoResultFound:
91
+ return self.create_default_user()
89
92
 
90
93
  @enforce_types
91
94
  def get_user_or_default(self, user_id: Optional[str] = None):
letta/settings.py CHANGED
@@ -16,8 +16,10 @@ class ToolSettings(BaseSettings):
16
16
  e2b_sandbox_template_id: Optional[str] = None # Updated manually
17
17
 
18
18
  # Local Sandbox configurations
19
- local_sandbox_dir: Optional[str] = None
20
- local_sandbox_timeout: float = 180
19
+ tool_exec_dir: Optional[str] = None
20
+ tool_sandbox_timeout: float = 180
21
+ tool_exec_venv_name: Optional[str] = None
22
+ tool_exec_autoreload_venv: bool = True
21
23
 
22
24
  # MCP settings
23
25
  mcp_connect_to_server_timeout: float = 30.0
letta/system.py CHANGED
@@ -224,7 +224,6 @@ def unpack_message(packed_message) -> str:
224
224
  try:
225
225
  message_json = json.loads(packed_message)
226
226
  except:
227
- warnings.warn(f"Was unable to load message as JSON to unpack: '{packed_message}'")
228
227
  return packed_message
229
228
 
230
229
  if "message" not in message_json:
letta/tracing.py CHANGED
@@ -23,6 +23,7 @@ _excluded_v1_endpoints_regex: List[str] = [
23
23
  "^GET /v1/agents/(?P<agent_id>[^/]+)/context$",
24
24
  "^GET /v1/agents/(?P<agent_id>[^/]+)/archival-memory$",
25
25
  "^GET /v1/agents/(?P<agent_id>[^/]+)/sources$",
26
+ r"^POST /v1/voice-beta/.*/chat/completions$",
26
27
  ]
27
28
 
28
29
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: letta-nightly
3
- Version: 0.7.5.dev20250427104041
3
+ Version: 0.7.6.dev20250429062643
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  License: Apache License
6
6
  Author: Letta Team
@@ -1,14 +1,14 @@
1
- letta/__init__.py,sha256=bAqRCwvutm5LP1C2uuuUcODc0u_yqtCtac7CL9bi61k,917
1
+ letta/__init__.py,sha256=NpAOglNuqPyCDdqIw6ZvUrkPChAef02s6hREmatgOc8,917
2
2
  letta/__main__.py,sha256=6Hs2PV7EYc5Tid4g4OtcLXhqVHiNYTGzSBdoOnW2HXA,29
3
3
  letta/agent.py,sha256=VCTvaT0skG1uj7s76GVEMKge9Q0ranjajlQtpjST4iw,72242
4
4
  letta/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- letta/agents/base_agent.py,sha256=yjB1Yz6L-9hTFinqkvyf6c-8dDX9O4u8VCrKrvA4G3s,2348
5
+ letta/agents/base_agent.py,sha256=Nv6OzvMeAvEv4yHAMaltgWvRU9eqSEJVuUm_7NnIeJk,2354
6
6
  letta/agents/ephemeral_agent.py,sha256=el-SUF_16vv_7OouIR-6z0pAE9Yc0PLibygvfCKwqfo,2736
7
- letta/agents/ephemeral_memory_agent.py,sha256=tVRsL18EvruNyrhzPkzLqiptfWa9jAC2GmSjUf5zKQo,4821
7
+ letta/agents/ephemeral_memory_agent.py,sha256=ZbfqfGxG_e0XjLmvUT8zAXQJgCdsbY7asJtUgI8eMHw,17286
8
8
  letta/agents/helpers.py,sha256=sYfjJLCEQg0aaKDRIJ2Xm_fG1yivCB9wU6bSskZMPKg,2568
9
9
  letta/agents/letta_agent.py,sha256=Y_hqJjFcFnVU2-kdbMmtKYp4l9_yCXeHCjvo8qqI1gU,18162
10
10
  letta/agents/letta_agent_batch.py,sha256=YsuYKwanRAmSPwmT5NVG3oIyOjlOz08hrQgpgRNhXt0,22899
11
- letta/agents/voice_agent.py,sha256=qzDw7MWQYwxsqOT4nIJ9OSl72n7b2Xy3ZUqc2_AEP5M,17334
11
+ letta/agents/voice_agent.py,sha256=UKRNWTVtsmdUbHxq0SOfoOL8AJESzY44aNzLZZVVt6k,23889
12
12
  letta/benchmark/benchmark.py,sha256=ebvnwfp3yezaXOQyGXkYCDYpsmre-b9hvNtnyx4xkG0,3701
13
13
  letta/benchmark/constants.py,sha256=aXc5gdpMGJT327VuxsT5FngbCK2J41PQYeICBO7g_RE,536
14
14
  letta/cli/cli.py,sha256=zJz78-qDUz-depb7VQWkg87RBKiETQU4h9DI6ukQBa8,16477
@@ -19,7 +19,7 @@ letta/client/client.py,sha256=nF2KxkTMp7JUx_ITLKhsU14z0e9Uwwkux3heskQmfeE,138224
19
19
  letta/client/streaming.py,sha256=UsDS_tDTsA3HgYryIDvGGmx_dWfnfQwtmEwLi4Z89Ik,4701
20
20
  letta/client/utils.py,sha256=VCGV-op5ZSmurd4yw7Vhf93XDQ0BkyBT8qsuV7EqfiU,2859
21
21
  letta/config.py,sha256=JFGY4TWW0Wm5fTbZamOwWqk5G8Nn-TXyhgByGoAqy2c,12375
22
- letta/constants.py,sha256=QohM-FZx5KIB4WFVQbCPoALXHGwEhC959fUiFCe8XG4,8635
22
+ letta/constants.py,sha256=NtcfXNpfTHxCNn4IZGtnkOLwoyaLzDADFB3lS84jwLo,8689
23
23
  letta/data_sources/connectors.py,sha256=m4ALtjlaZpSlJnlq2VMNzx0onowNpjvoa4ZjAB5SMQw,7243
24
24
  letta/data_sources/connectors_helper.py,sha256=oQpVlc-BjSz9sTZ7sp4PsJSXJbBKpZPi3Dam03CURTQ,3376
25
25
  letta/embeddings.py,sha256=KvC2bl5tARpVY9xcFmw4Cwu1vN0DoH266v2mSUZqwkY,10528
@@ -48,7 +48,7 @@ letta/groups/supervisor_multi_agent.py,sha256=ml8Gi9gyVjPuVZjAJAkpGZDjnM7GOS50Nk
48
48
  letta/helpers/__init__.py,sha256=p0luQ1Oe3Skc6sH4O58aHHA3Qbkyjifpuq0DZ1GAY0U,59
49
49
  letta/helpers/composio_helpers.py,sha256=5SznD1Y0Y1rV4_wu-uCaZdDU2tNedk-RIX0M9-0r6yo,947
50
50
  letta/helpers/converters.py,sha256=BC_K98vgRO7-_sQsjD9-JnG7XzmwluXU8Hxj9ACBoPU,13754
51
- letta/helpers/datetime_helpers.py,sha256=k-qldD3mqGYeoqCz0eG6pZy5JGEwx4yp5JSDodQeYs4,2911
51
+ letta/helpers/datetime_helpers.py,sha256=a39913WsZ3VH5p6irIuZly5XEDHm8D4b_rnvF-716_o,3044
52
52
  letta/helpers/json_helpers.py,sha256=PWZ5HhSqGXO4e563dM_8M72q7ScirjXQ4Rv1ckohaV8,396
53
53
  letta/helpers/message_helper.py,sha256=0nEXJDWF_McVXtdmimNk5H53CbF21-O934hl51SZnxU,1767
54
54
  letta/helpers/tool_execution_helper.py,sha256=Jxof1Z-NZ2quOYGQT2KLbaBYrv96NKfkBzjITYZxzs0,7590
@@ -59,7 +59,7 @@ letta/humans/examples/cs_phd.txt,sha256=9C9ZAV_VuG7GB31ksy3-_NAyk8rjE6YtVOkhp08k
59
59
  letta/interface.py,sha256=6GKasvJMASu-kcZch6Hffz1vnHuPA_ryI6cLH2bMArc,13023
60
60
  letta/interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
61
  letta/interfaces/anthropic_streaming_interface.py,sha256=9AH4iGe9Uh3l0smdCDy_1p1Qp0boqmnusJo6PkY38fU,16192
62
- letta/interfaces/openai_chat_completions_streaming_interface.py,sha256=SfqVp7V7AbBqv8D_IwyqrcztNiI0nKhjAvqtZQE_jfM,4729
62
+ letta/interfaces/openai_chat_completions_streaming_interface.py,sha256=5anzqE4ObcJPOrlEQzXGxp1X2s5Jkil01I5qTG9Loo0,4852
63
63
  letta/interfaces/utils.py,sha256=c6jvO0dBYHh8DQnlN-B0qeNC64d3CSunhfqlFA4pJTY,278
64
64
  letta/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  letta/jobs/helpers.py,sha256=kO4aj954xsQ1RAmkjY6LQQ7JEIGuhaxB1e9pzrYKHAY,914
@@ -74,16 +74,16 @@ letta/llm_api/azure_openai.py,sha256=YAkXwKyfnJFNhB45pkJVFsoxUNB_M74rQYchtw_CN6I
74
74
  letta/llm_api/azure_openai_constants.py,sha256=ZaR2IasJThijG0uhLKJThrixdAxLPD2IojfeaJ-KQMQ,294
75
75
  letta/llm_api/cohere.py,sha256=IZ6LXyOFMYjWHTeNG9lvFxCdV_NIl0hY2q9SPFYXNkQ,14849
76
76
  letta/llm_api/deepseek.py,sha256=b1mSW8gnBrpAI8d2GcBpDyLYDnuC-P1UP6xJPalfQS4,12456
77
- letta/llm_api/google_ai_client.py,sha256=im-GeRpn9FhbdRHqW9EukW2O-LPvpfDkr1aZ9O2aXkE,22758
77
+ letta/llm_api/google_ai_client.py,sha256=YRGFFYK-81nHoyjO4inoMAhlFNjj5ZjOxLqIUIaxvdc,23017
78
78
  letta/llm_api/google_constants.py,sha256=1dqwt-YwdYGnAHV5rIPfGHfE3ybPzSn_48vlNYfd-bk,588
79
79
  letta/llm_api/google_vertex_client.py,sha256=lTfAUTPSqwe-cuOoEgUehdwg2ZVHLqXRiu-sj6g8PJg,11645
80
80
  letta/llm_api/helpers.py,sha256=sLYv30UnKBRVPuhU_KDXfKFdbkUONiDAyVEwGr86l3A,16780
81
- letta/llm_api/llm_api_tools.py,sha256=s1n3YDGp-ShHOzxeuQ1BOje0oh7H_yGefRVwFXsc_A8,27547
81
+ letta/llm_api/llm_api_tools.py,sha256=aY7QFuho384AoGJPZORFo0FyZSRNSyv9biC5bKOadaU,27660
82
82
  letta/llm_api/llm_client.py,sha256=JpSZWLoJsHdjlfavyhNyNf_j7N5Ks2DktDuA2PyQO70,1827
83
83
  letta/llm_api/llm_client_base.py,sha256=-RSVo4986iNLbOyUR3IKggKL2zWD4IBsr8ZbF8p28Ac,5935
84
84
  letta/llm_api/mistral.py,sha256=fHdfD9ug-rQIk2qn8tRKay1U6w9maF11ryhKi91FfXM,1593
85
- letta/llm_api/openai.py,sha256=qTTOyI6qQA-KmS1atmy2giSyT1XpjysqkQZbbUY7eKs,23425
86
- letta/llm_api/openai_client.py,sha256=qm9-zgJIlUnP9vmdfFBR2BCOenzf2aYGEsBVIBzKgB8,13277
85
+ letta/llm_api/openai.py,sha256=k7-lW0jxZtXA8YYcVE_y2kTDHJpNU12C77udr-UKYdU,23473
86
+ letta/llm_api/openai_client.py,sha256=L98mGTHAVkbewbAfqW5qFJ_OBGLokWguwRhplb1WZC8,13316
87
87
  letta/local_llm/README.md,sha256=hFJyw5B0TU2jrh9nb0zGZMgdH-Ei1dSRfhvPQG_NSoU,168
88
88
  letta/local_llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
89
  letta/local_llm/chat_completion_proxy.py,sha256=gc5gaKoHP8QaWRulDeEYPk7Onl8KdCBmpF2l9znXKeQ,13853
@@ -211,21 +211,21 @@ letta/schemas/letta_message_content.py,sha256=eF2UEDofQx7S_nS1jc9MZypP4EGVWj7zdi
211
211
  letta/schemas/letta_request.py,sha256=TH00tm81Pe8D6r7IrxjKW0Hc8QE_Z4jclbc6VX0_Ybw,1542
212
212
  letta/schemas/letta_response.py,sha256=K11qneqSSE3R2twr65ZYnDzl0oBMf1N1nUnJpI4oiUs,7846
213
213
  letta/schemas/llm_batch_job.py,sha256=n9ZbWINBECRrZW6vslm-f2pk_rI_gpuxcZsqAphl9bE,2879
214
- letta/schemas/llm_config.py,sha256=DIJrjHUYohOd0yz3rNK8TAABbFZsLd8EpdscQErjobU,7927
214
+ letta/schemas/llm_config.py,sha256=6PAHBi_3ELLcFXBWinfCslPQ1SjcNZx3mptRnTwZuiw,8122
215
215
  letta/schemas/llm_config_overrides.py,sha256=-oRglCTcajF6UAK3RAa0FLWVuKODPI1v403fDIWMAtA,1815
216
216
  letta/schemas/memory.py,sha256=GOYDfPKzbWftUWO9Hv4KW7xAi1EIQmC8zpP7qvEkVHw,10245
217
217
  letta/schemas/message.py,sha256=Is9K5-J-V07-EiyLezsY4JBuENQTogZ_6FraOoLd_mc,49676
218
- letta/schemas/openai/chat_completion_request.py,sha256=PZHzx--ooqJLsHTo1NpHwfywm5L8Id-CUXaKR6eXuko,4171
218
+ letta/schemas/openai/chat_completion_request.py,sha256=XARKB7717Crt3P2A53eeBZ6hlNJcb9TJHosWwK17tFw,4210
219
219
  letta/schemas/openai/chat_completion_response.py,sha256=7SsfVNsWq_EUajmckU5KjFClkK0iXZF2jHWZZ0nr6T4,6701
220
220
  letta/schemas/openai/chat_completions.py,sha256=l0e9sT9boTD5VBU5YtJ0s7qUtCfFGB2K-gQLeEZ2LHU,3599
221
221
  letta/schemas/openai/embedding_response.py,sha256=WKIZpXab1Av7v6sxKG8feW3ZtpQUNosmLVSuhXYa_xU,357
222
222
  letta/schemas/openai/openai.py,sha256=Hilo5BiLAGabzxCwnwfzK5QrWqwYD8epaEKFa4Pwndk,7970
223
223
  letta/schemas/organization.py,sha256=TXrHN4IBQnX-mWvRuCOH57XZSLYCVOY0wWm2_UzDQIA,1279
224
224
  letta/schemas/passage.py,sha256=RG0vkaewEu4a_NAZM-FVyMammHjqpPP0RDYAdu27g6A,3723
225
- letta/schemas/providers.py,sha256=6TyGvmfAT-bgmYblfjheQ3Ki4gGxVCFfC5Lt8D3X4qc,51784
225
+ letta/schemas/providers.py,sha256=-ApnBM9MnbxEGnf_Mulo9ZLK2AK2ciGxYhusYAUp9z4,51881
226
226
  letta/schemas/response_format.py,sha256=pXNsjbtpA3Tf8HsDyIa40CSmoUbVR_7n2WOfQaX4aFs,2204
227
227
  letta/schemas/run.py,sha256=SRqPRziINIiPunjOhE_NlbnQYgxTvqmbauni_yfBQRA,2085
228
- letta/schemas/sandbox_config.py,sha256=Uu_GDofZasycarUVjXB1tL5-X1pLXSsrCB_7XycRIuM,6011
228
+ letta/schemas/sandbox_config.py,sha256=Qfkzw422HCQUsE3GKry94oecQGziAzGXIyd6ke8W06M,5985
229
229
  letta/schemas/source.py,sha256=IuenIFs7B8uOuYJIHXqR1E28wVSa-pUX6NkLZH7cukg,3141
230
230
  letta/schemas/step.py,sha256=WkcVnruUUOWLKwiWPn2Gfal4EQZPNLqlsd9859xhgsw,2224
231
231
  letta/schemas/tool.py,sha256=n1gYBORUwT4pH5NYLLfT8v97JcoI3W6mpnUsa-GzcNg,13063
@@ -257,7 +257,7 @@ letta/server/rest_api/interface.py,sha256=c-BaECsK4szrmkDTTl52JckLxx92WR4uwK_VSa
257
257
  letta/server/rest_api/optimistic_json_parser.py,sha256=SS60lTp1oH2MXbHOChEnNm46xYcoAU3nInIXWDglmmw,6739
258
258
  letta/server/rest_api/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
259
259
  letta/server/rest_api/routers/openai/chat_completions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
260
- letta/server/rest_api/routers/openai/chat_completions/chat_completions.py,sha256=Ksh_F6hJDOrafY2Gxz7NQdQZXBNeX-3-w4mVEQgMhrQ,5327
260
+ letta/server/rest_api/routers/openai/chat_completions/chat_completions.py,sha256=EK67d8r5CKTluQIAOknbRBRtq2LQxkLLkekchipdmgw,5149
261
261
  letta/server/rest_api/routers/v1/__init__.py,sha256=_skmAcDOK9ovHKfywRaBgigo3IvPmnUSQSR2hGVCOhY,1664
262
262
  letta/server/rest_api/routers/v1/agents.py,sha256=3mbPzEKBCzJmpUBUmJrs1WbmkIGTjEJ32HNUb1Lo5_M,34676
263
263
  letta/server/rest_api/routers/v1/blocks.py,sha256=Sefvon0jLvlNh0oAzntUcDZptnutuJOf-2Wcad_45Dg,4169
@@ -277,10 +277,10 @@ letta/server/rest_api/routers/v1/steps.py,sha256=DVVwaxLNbNAgWpr2oQkrNjdS-wi0bP8
277
277
  letta/server/rest_api/routers/v1/tags.py,sha256=coydgvL6-9cuG2Hy5Ea7QY3inhTHlsf69w0tcZenBus,880
278
278
  letta/server/rest_api/routers/v1/tools.py,sha256=FXFx8J4Zs-pZ1H8andFzI5Pyv-PJkY8YMlWkZlObGdQ,19544
279
279
  letta/server/rest_api/routers/v1/users.py,sha256=G5DBHSkPfBgVHN2Wkm-rVYiLQAudwQczIq2Z3YLdbVo,2277
280
- letta/server/rest_api/routers/v1/voice.py,sha256=0lerWjrKLkt4gXLhZl1cIcgstOz9Q2HZwc67L58BCXE,2451
280
+ letta/server/rest_api/routers/v1/voice.py,sha256=czt6y5na1msrJCvXlhN1XYluotnxFwIfYFMMOmynfgE,2072
281
281
  letta/server/rest_api/static_files.py,sha256=NG8sN4Z5EJ8JVQdj19tkFa9iQ1kBPTab9f_CUxd_u4Q,3143
282
- letta/server/rest_api/utils.py,sha256=OKUWg7u4vmROVweqRrs83bQvS958bZAoR_bUFDwwqsc,14861
283
- letta/server/server.py,sha256=XcZ_vrQkG2CVr_mgCKVAV6EMVjuR4lQVtU3FTAUJIIc,79726
282
+ letta/server/rest_api/utils.py,sha256=bZpp_nkqcL0yF1or91dEscE-LItDJEc16NTalz5ItbU,15357
283
+ letta/server/server.py,sha256=6_zoStXpAwH2UnJ-TcRNoJKlOh44_YFKG3rUEZSZNnw,82171
284
284
  letta/server/startup.sh,sha256=MRXh1RKbS5lyA7XAsk7O6Q4LEKOqnv5B-dwe0SnTHeQ,2514
285
285
  letta/server/static_files/assets/index-048c9598.js,sha256=mR16XppvselwKCcNgONs4L7kZEVa4OEERm4lNZYtLSk,146819
286
286
  letta/server/static_files/assets/index-0e31b727.css,sha256=SBbja96uiQVLDhDOroHgM6NSl7tS4lpJRCREgSS_hA8,7672
@@ -297,8 +297,8 @@ letta/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
297
297
  letta/services/agent_manager.py,sha256=9BRBbAf0LXftDzke8OBzVgzOmP1FLCnsRSQggbNxeOU,71581
298
298
  letta/services/block_manager.py,sha256=rphbpGBIEDFvCJ5GJt6A1OfbURGFQZ3WardljELQyAc,15225
299
299
  letta/services/group_manager.py,sha256=z1woWRRnjkWrGG_auSicXr2bJaJ653JV6PYl2N_AUfw,12224
300
- letta/services/helpers/agent_manager_helper.py,sha256=57ARg5TcmE_JdrWmhz5uaNHAt1NGlJ3wQH1tP2XOiAs,17825
301
- letta/services/helpers/tool_execution_helper.py,sha256=E8knHJUP_EKmAzwKx-z-rd5EKjU-oroyPzyElUmq83o,6968
300
+ letta/services/helpers/agent_manager_helper.py,sha256=c4ssr1rN8Ef3HFdAsCuYkM6OIenrLX3ix_f4a830Gkk,17891
301
+ letta/services/helpers/tool_execution_helper.py,sha256=JdH6VTWFrXfwPWsWNSZFKuRFhhXp8qiDYWjbPc8PLLI,7649
302
302
  letta/services/identity_manager.py,sha256=sjHTCPbLYRDyWCJ3qjcuKZqWqzDoEuslRsDVKQtBraE,9683
303
303
  letta/services/job_manager.py,sha256=Z9cSD-IqpiOIWE_UOTBUEIxGITrJ10JT1G3ske-0yIY,17166
304
304
  letta/services/llm_batch_manager.py,sha256=jm6MY91hrZdcPOsimSd7Ns3mf0J4SwKV2_ShWXhD02k,16819
@@ -317,25 +317,25 @@ letta/services/source_manager.py,sha256=yW88wAJoeAWtbg0FxifE352jhgOTKNiG7K-IPKXK
317
317
  letta/services/step_manager.py,sha256=B64iYn6Dt9yRKsSJ5vLxWQR2t-apvPLfUZyzrUsJTpI,5335
318
318
  letta/services/summarizer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
319
319
  letta/services/summarizer/enums.py,sha256=szzPX2OBRRJEZsBTGYQThrNz02ELFqhuLwvOR7ozi7A,208
320
- letta/services/summarizer/summarizer.py,sha256=4rbbzcB_lY4-3ybT8HMxM8OskLC38YCs9n5h0NhWRcY,4988
320
+ letta/services/summarizer/summarizer.py,sha256=Prfg6xRPZeb0EPrjdAP3p6YOFQR_T49tSUsTWvQ2Vhg,7639
321
321
  letta/services/tool_executor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
322
322
  letta/services/tool_executor/tool_execution_manager.py,sha256=RcmnwPougb8AxIwKdC4N9ZxTvOQqJyjI6CaVHF2HBi4,4505
323
- letta/services/tool_executor/tool_execution_sandbox.py,sha256=hu-SVqfRalJGcXRKTpbYkqgX-DZH3Uky_eD_vh0kx6s,24704
323
+ letta/services/tool_executor/tool_execution_sandbox.py,sha256=9gcERJ15Y6u_6AGAVH3KGJP-85fpr2HLCV8SatQAG0w,24891
324
324
  letta/services/tool_executor/tool_executor.py,sha256=k2yEzLpU18SFFA6NWrf5NYbCh505ixMpnf6pnBhmV8s,27413
325
325
  letta/services/tool_manager.py,sha256=ZtDRk9IODlMSJgwAzI1RQVee0fqgFzNu8iFZ92qwm-c,10569
326
326
  letta/services/tool_sandbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
327
327
  letta/services/tool_sandbox/base.py,sha256=pUnPFkEg9I5ktMuT4AOOxbTnTmZTGcTA2phLe1H1EdY,8306
328
328
  letta/services/tool_sandbox/e2b_sandbox.py,sha256=umsXfolzM_j67izswECDdVfnlcm03wLpMoZtS6SZ0sc,6147
329
- letta/services/tool_sandbox/local_sandbox.py,sha256=3TC8bVZerhmVD6T-PxPN-QeQGOKzKjHNG7zhhU1o2ME,10511
330
- letta/services/user_manager.py,sha256=ScHbdJK9kNF8QXjsd3ZWGEL87n_Uyp3YwfKetOJmpHs,4304
331
- letta/settings.py,sha256=CN48IzOHJ2mUUDvYR1qlh-n9ukXJxNuVDlj_v74UJmg,8046
329
+ letta/services/tool_sandbox/local_sandbox.py,sha256=ksbraC-zcMWt3vS7kSi98uWI9L73I0h73rMayhuTWsw,10474
330
+ letta/services/user_manager.py,sha256=_aoiQy73B4Jm_uVDrfAUrg2TnOYa_tJLRUwa3fF5ASY,4429
331
+ letta/settings.py,sha256=JT-VABiXDKlDBFPDWyItTjscZWcQk8tDiAhxcoTj7rg,8130
332
332
  letta/streaming_interface.py,sha256=kDSc5bnodgGzAuLcnq4Zf7p-uS6cdyxSIZ5U_JA_8FU,16300
333
333
  letta/streaming_utils.py,sha256=jLqFTVhUL76FeOuYk8TaRQHmPTf3HSRc2EoJwxJNK6U,11946
334
- letta/system.py,sha256=dnOrS2FlRMwijQnOvfrky0Lg8wEw-FUq2zzfAJOUSKA,8477
335
- letta/tracing.py,sha256=RstWXpfWVF77nmb_ISORVWd9IQw2Ky3de40k_S70yKI,8258
334
+ letta/system.py,sha256=mKxmvvekuP8mdgsebRINGBoFbUdJhxLJ260crPBNVyk,8386
335
+ letta/tracing.py,sha256=d_l8emrUMnAv3y1C9ttPZM0bnakHzP5Bgv06k-tBFrc,8308
336
336
  letta/utils.py,sha256=IZFvtj9WYcrxUbkoUUYGDxMYQYdn5SgfqsvnARGsAzc,32245
337
- letta_nightly-0.7.5.dev20250427104041.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
338
- letta_nightly-0.7.5.dev20250427104041.dist-info/METADATA,sha256=lEZIptlE5TJoyeEU3rWx9V2fvgCvVo1IFaBQTjW4c0A,22282
339
- letta_nightly-0.7.5.dev20250427104041.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
340
- letta_nightly-0.7.5.dev20250427104041.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
341
- letta_nightly-0.7.5.dev20250427104041.dist-info/RECORD,,
337
+ letta_nightly-0.7.6.dev20250429062643.dist-info/LICENSE,sha256=mExtuZ_GYJgDEI38GWdiEYZizZS4KkVt2SF1g_GPNhI,10759
338
+ letta_nightly-0.7.6.dev20250429062643.dist-info/METADATA,sha256=NJVUeJpEbez-k4yS0oOMxHjCu5-msrmViDj4yEAtSTo,22282
339
+ letta_nightly-0.7.6.dev20250429062643.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
340
+ letta_nightly-0.7.6.dev20250429062643.dist-info/entry_points.txt,sha256=2zdiyGNEZGV5oYBuS-y2nAAgjDgcC9yM_mHJBFSRt5U,40
341
+ letta_nightly-0.7.6.dev20250429062643.dist-info/RECORD,,