letta-nightly 0.11.7.dev20251007104119__py3-none-any.whl → 0.12.0.dev20251009104148__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 (151) hide show
  1. letta/__init__.py +1 -1
  2. letta/adapters/letta_llm_adapter.py +1 -0
  3. letta/adapters/letta_llm_request_adapter.py +0 -1
  4. letta/adapters/letta_llm_stream_adapter.py +7 -2
  5. letta/adapters/simple_llm_request_adapter.py +88 -0
  6. letta/adapters/simple_llm_stream_adapter.py +192 -0
  7. letta/agents/agent_loop.py +6 -0
  8. letta/agents/ephemeral_summary_agent.py +2 -1
  9. letta/agents/helpers.py +142 -6
  10. letta/agents/letta_agent.py +13 -33
  11. letta/agents/letta_agent_batch.py +2 -4
  12. letta/agents/letta_agent_v2.py +87 -77
  13. letta/agents/letta_agent_v3.py +927 -0
  14. letta/agents/voice_agent.py +2 -6
  15. letta/constants.py +8 -4
  16. letta/database_utils.py +161 -0
  17. letta/errors.py +40 -0
  18. letta/functions/function_sets/base.py +84 -4
  19. letta/functions/function_sets/multi_agent.py +0 -3
  20. letta/functions/schema_generator.py +113 -71
  21. letta/groups/dynamic_multi_agent.py +3 -2
  22. letta/groups/helpers.py +1 -2
  23. letta/groups/round_robin_multi_agent.py +3 -2
  24. letta/groups/sleeptime_multi_agent.py +3 -2
  25. letta/groups/sleeptime_multi_agent_v2.py +1 -1
  26. letta/groups/sleeptime_multi_agent_v3.py +17 -17
  27. letta/groups/supervisor_multi_agent.py +84 -80
  28. letta/helpers/converters.py +3 -0
  29. letta/helpers/message_helper.py +4 -0
  30. letta/helpers/tool_rule_solver.py +92 -5
  31. letta/interfaces/anthropic_streaming_interface.py +409 -0
  32. letta/interfaces/gemini_streaming_interface.py +296 -0
  33. letta/interfaces/openai_streaming_interface.py +752 -1
  34. letta/llm_api/anthropic_client.py +127 -16
  35. letta/llm_api/bedrock_client.py +4 -2
  36. letta/llm_api/deepseek_client.py +4 -1
  37. letta/llm_api/google_vertex_client.py +124 -42
  38. letta/llm_api/groq_client.py +4 -1
  39. letta/llm_api/llm_api_tools.py +11 -4
  40. letta/llm_api/llm_client_base.py +6 -2
  41. letta/llm_api/openai.py +32 -2
  42. letta/llm_api/openai_client.py +423 -18
  43. letta/llm_api/xai_client.py +4 -1
  44. letta/main.py +9 -5
  45. letta/memory.py +1 -0
  46. letta/orm/__init__.py +2 -1
  47. letta/orm/agent.py +10 -0
  48. letta/orm/block.py +7 -16
  49. letta/orm/blocks_agents.py +8 -2
  50. letta/orm/files_agents.py +2 -0
  51. letta/orm/job.py +7 -5
  52. letta/orm/mcp_oauth.py +1 -0
  53. letta/orm/message.py +21 -6
  54. letta/orm/organization.py +2 -0
  55. letta/orm/provider.py +6 -2
  56. letta/orm/run.py +71 -0
  57. letta/orm/run_metrics.py +82 -0
  58. letta/orm/sandbox_config.py +7 -1
  59. letta/orm/sqlalchemy_base.py +0 -306
  60. letta/orm/step.py +6 -5
  61. letta/orm/step_metrics.py +5 -5
  62. letta/otel/tracing.py +28 -3
  63. letta/plugins/defaults.py +4 -4
  64. letta/prompts/system_prompts/__init__.py +2 -0
  65. letta/prompts/system_prompts/letta_v1.py +25 -0
  66. letta/schemas/agent.py +3 -2
  67. letta/schemas/agent_file.py +9 -3
  68. letta/schemas/block.py +23 -10
  69. letta/schemas/enums.py +21 -2
  70. letta/schemas/job.py +17 -4
  71. letta/schemas/letta_message_content.py +71 -2
  72. letta/schemas/letta_stop_reason.py +5 -5
  73. letta/schemas/llm_config.py +53 -3
  74. letta/schemas/memory.py +1 -1
  75. letta/schemas/message.py +564 -117
  76. letta/schemas/openai/responses_request.py +64 -0
  77. letta/schemas/providers/__init__.py +2 -0
  78. letta/schemas/providers/anthropic.py +16 -0
  79. letta/schemas/providers/ollama.py +115 -33
  80. letta/schemas/providers/openrouter.py +52 -0
  81. letta/schemas/providers/vllm.py +2 -1
  82. letta/schemas/run.py +48 -42
  83. letta/schemas/run_metrics.py +21 -0
  84. letta/schemas/step.py +2 -2
  85. letta/schemas/step_metrics.py +1 -1
  86. letta/schemas/tool.py +15 -107
  87. letta/schemas/tool_rule.py +88 -5
  88. letta/serialize_schemas/marshmallow_agent.py +1 -0
  89. letta/server/db.py +79 -408
  90. letta/server/rest_api/app.py +61 -10
  91. letta/server/rest_api/dependencies.py +14 -0
  92. letta/server/rest_api/redis_stream_manager.py +19 -8
  93. letta/server/rest_api/routers/v1/agents.py +364 -292
  94. letta/server/rest_api/routers/v1/blocks.py +14 -20
  95. letta/server/rest_api/routers/v1/identities.py +45 -110
  96. letta/server/rest_api/routers/v1/internal_templates.py +21 -0
  97. letta/server/rest_api/routers/v1/jobs.py +23 -6
  98. letta/server/rest_api/routers/v1/messages.py +1 -1
  99. letta/server/rest_api/routers/v1/runs.py +149 -99
  100. letta/server/rest_api/routers/v1/sandbox_configs.py +10 -19
  101. letta/server/rest_api/routers/v1/tools.py +281 -594
  102. letta/server/rest_api/routers/v1/voice.py +1 -1
  103. letta/server/rest_api/streaming_response.py +29 -29
  104. letta/server/rest_api/utils.py +122 -64
  105. letta/server/server.py +160 -887
  106. letta/services/agent_manager.py +236 -919
  107. letta/services/agent_serialization_manager.py +16 -0
  108. letta/services/archive_manager.py +0 -100
  109. letta/services/block_manager.py +211 -168
  110. letta/services/context_window_calculator/token_counter.py +1 -1
  111. letta/services/file_manager.py +1 -1
  112. letta/services/files_agents_manager.py +24 -33
  113. letta/services/group_manager.py +0 -142
  114. letta/services/helpers/agent_manager_helper.py +7 -2
  115. letta/services/helpers/run_manager_helper.py +69 -0
  116. letta/services/job_manager.py +96 -411
  117. letta/services/lettuce/__init__.py +6 -0
  118. letta/services/lettuce/lettuce_client_base.py +86 -0
  119. letta/services/mcp_manager.py +38 -6
  120. letta/services/message_manager.py +165 -362
  121. letta/services/organization_manager.py +0 -36
  122. letta/services/passage_manager.py +0 -345
  123. letta/services/provider_manager.py +0 -80
  124. letta/services/run_manager.py +364 -0
  125. letta/services/sandbox_config_manager.py +0 -234
  126. letta/services/step_manager.py +62 -39
  127. letta/services/summarizer/summarizer.py +9 -7
  128. letta/services/telemetry_manager.py +0 -16
  129. letta/services/tool_executor/builtin_tool_executor.py +35 -0
  130. letta/services/tool_executor/core_tool_executor.py +397 -2
  131. letta/services/tool_executor/files_tool_executor.py +3 -3
  132. letta/services/tool_executor/multi_agent_tool_executor.py +30 -15
  133. letta/services/tool_executor/tool_execution_manager.py +6 -8
  134. letta/services/tool_executor/tool_executor_base.py +3 -3
  135. letta/services/tool_manager.py +85 -339
  136. letta/services/tool_sandbox/base.py +24 -13
  137. letta/services/tool_sandbox/e2b_sandbox.py +16 -1
  138. letta/services/tool_schema_generator.py +123 -0
  139. letta/services/user_manager.py +0 -99
  140. letta/settings.py +20 -4
  141. letta/system.py +5 -1
  142. {letta_nightly-0.11.7.dev20251007104119.dist-info → letta_nightly-0.12.0.dev20251009104148.dist-info}/METADATA +3 -5
  143. {letta_nightly-0.11.7.dev20251007104119.dist-info → letta_nightly-0.12.0.dev20251009104148.dist-info}/RECORD +146 -135
  144. letta/agents/temporal/activities/__init__.py +0 -4
  145. letta/agents/temporal/activities/example_activity.py +0 -7
  146. letta/agents/temporal/activities/prepare_messages.py +0 -10
  147. letta/agents/temporal/temporal_agent_workflow.py +0 -56
  148. letta/agents/temporal/types.py +0 -25
  149. {letta_nightly-0.11.7.dev20251007104119.dist-info → letta_nightly-0.12.0.dev20251009104148.dist-info}/WHEEL +0 -0
  150. {letta_nightly-0.11.7.dev20251007104119.dist-info → letta_nightly-0.12.0.dev20251009104148.dist-info}/entry_points.txt +0 -0
  151. {letta_nightly-0.11.7.dev20251007104119.dist-info → letta_nightly-0.12.0.dev20251009104148.dist-info}/licenses/LICENSE +0 -0
@@ -208,6 +208,22 @@ class AgentSerializationManager:
208
208
  )
209
209
  agent_schema.id = agent_file_id
210
210
 
211
+ # Ensure all in-context messages are present before ID remapping.
212
+ # AgentSchema.from_agent_state fetches a limited slice (~50) and may exclude messages still
213
+ # referenced by in_context_message_ids. Fetch any missing in-context messages by ID so remapping succeeds.
214
+ existing_msg_ids = {m.id for m in (agent_schema.messages or [])}
215
+ in_context_ids = agent_schema.in_context_message_ids or []
216
+ missing_in_context_ids = [mid for mid in in_context_ids if mid not in existing_msg_ids]
217
+ if missing_in_context_ids:
218
+ missing_msgs = await self.message_manager.get_messages_by_ids_async(message_ids=missing_in_context_ids, actor=actor)
219
+ fetched_ids = {m.id for m in missing_msgs}
220
+ not_found = [mid for mid in missing_in_context_ids if mid not in fetched_ids]
221
+ if not_found:
222
+ # Surface a clear mapping error; handled upstream by the route/export wrapper.
223
+ raise AgentExportIdMappingError(db_id=not_found[0], entity_type=MessageSchema.__id_prefix__)
224
+ for msg in missing_msgs:
225
+ agent_schema.messages.append(MessageSchema.from_message(msg))
226
+
211
227
  # wipe the values of tool_exec_environment_variables (they contain secrets)
212
228
  agent_secrets = agent_schema.secrets or agent_schema.tool_exec_environment_variables
213
229
  if agent_secrets:
@@ -19,32 +19,6 @@ logger = get_logger(__name__)
19
19
  class ArchiveManager:
20
20
  """Manager class to handle business logic related to Archives."""
21
21
 
22
- @enforce_types
23
- @trace_method
24
- def create_archive(
25
- self,
26
- name: str,
27
- description: Optional[str] = None,
28
- actor: PydanticUser = None,
29
- ) -> PydanticArchive:
30
- """Create a new archive."""
31
- try:
32
- with db_registry.session() as session:
33
- # determine vector db provider based on settings
34
- vector_db_provider = VectorDBProvider.TPUF if should_use_tpuf() else VectorDBProvider.NATIVE
35
-
36
- archive = ArchiveModel(
37
- name=name,
38
- description=description,
39
- organization_id=actor.organization_id,
40
- vector_db_provider=vector_db_provider,
41
- )
42
- archive.create(session, actor=actor)
43
- return archive.to_pydantic()
44
- except Exception as e:
45
- logger.exception(f"Failed to create archive {name}. error={e}")
46
- raise
47
-
48
22
  @enforce_types
49
23
  @trace_method
50
24
  async def create_archive_async(
@@ -160,36 +134,6 @@ class ArchiveManager:
160
134
  )
161
135
  return [a.to_pydantic() for a in archives]
162
136
 
163
- @enforce_types
164
- @trace_method
165
- def attach_agent_to_archive(
166
- self,
167
- agent_id: str,
168
- archive_id: str,
169
- is_owner: bool,
170
- actor: PydanticUser,
171
- ) -> None:
172
- """Attach an agent to an archive."""
173
- with db_registry.session() as session:
174
- # Check if already attached
175
- existing = session.query(ArchivesAgents).filter_by(agent_id=agent_id, archive_id=archive_id).first()
176
-
177
- if existing:
178
- # Update ownership if needed
179
- if existing.is_owner != is_owner:
180
- existing.is_owner = is_owner
181
- session.commit()
182
- return
183
-
184
- # Create new relationship
185
- archives_agents = ArchivesAgents(
186
- agent_id=agent_id,
187
- archive_id=archive_id,
188
- is_owner=is_owner,
189
- )
190
- session.add(archives_agents)
191
- session.commit()
192
-
193
137
  @enforce_types
194
138
  @trace_method
195
139
  async def attach_agent_to_archive_async(
@@ -345,50 +289,6 @@ class ArchiveManager:
345
289
  # this shouldn't happen, but if it does, re-raise
346
290
  raise
347
291
 
348
- @enforce_types
349
- @trace_method
350
- def get_or_create_default_archive_for_agent(
351
- self,
352
- agent_id: str,
353
- agent_name: Optional[str] = None,
354
- actor: PydanticUser = None,
355
- ) -> PydanticArchive:
356
- """Get the agent's default archive, creating one if it doesn't exist."""
357
- with db_registry.session() as session:
358
- # First check if agent has any archives
359
- query = select(ArchivesAgents.archive_id).where(ArchivesAgents.agent_id == agent_id)
360
- result = session.execute(query)
361
- archive_ids = [row[0] for row in result.fetchall()]
362
-
363
- if archive_ids:
364
- # TODO: Remove this check once we support multiple archives per agent
365
- if len(archive_ids) > 1:
366
- raise ValueError(f"Agent {agent_id} has multiple archives, which is not yet supported")
367
- # Get the archive
368
- archive = ArchiveModel.read(db_session=session, identifier=archive_ids[0], actor=actor)
369
- return archive.to_pydantic()
370
-
371
- # Create a default archive for this agent
372
- archive_name = f"{agent_name or f'Agent {agent_id}'}'s Archive"
373
-
374
- # Create the archive
375
- archive_model = ArchiveModel(
376
- name=archive_name,
377
- description="Default archive created automatically",
378
- organization_id=actor.organization_id,
379
- )
380
- archive_model.create(session, actor=actor)
381
-
382
- # Attach the agent to the archive as owner
383
- self.attach_agent_to_archive(
384
- agent_id=agent_id,
385
- archive_id=archive_model.id,
386
- is_owner=True,
387
- actor=actor,
388
- )
389
-
390
- return archive_model.to_pydantic()
391
-
392
292
  @enforce_types
393
293
  @trace_method
394
294
  async def get_agents_for_archive_async(