letta-nightly 0.8.15.dev20250719104256__py3-none-any.whl → 0.8.16.dev20250721070720__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 (99) hide show
  1. letta/__init__.py +1 -1
  2. letta/agent.py +27 -11
  3. letta/agents/helpers.py +1 -1
  4. letta/agents/letta_agent.py +518 -322
  5. letta/agents/letta_agent_batch.py +1 -2
  6. letta/agents/voice_agent.py +15 -17
  7. letta/client/client.py +3 -3
  8. letta/constants.py +5 -0
  9. letta/embeddings.py +0 -2
  10. letta/errors.py +8 -0
  11. letta/functions/function_sets/base.py +3 -3
  12. letta/functions/helpers.py +2 -3
  13. letta/groups/sleeptime_multi_agent.py +0 -1
  14. letta/helpers/composio_helpers.py +2 -2
  15. letta/helpers/converters.py +1 -1
  16. letta/helpers/pinecone_utils.py +8 -0
  17. letta/helpers/tool_rule_solver.py +13 -18
  18. letta/llm_api/aws_bedrock.py +16 -2
  19. letta/llm_api/cohere.py +1 -1
  20. letta/llm_api/openai_client.py +1 -1
  21. letta/local_llm/grammars/gbnf_grammar_generator.py +1 -1
  22. letta/local_llm/llm_chat_completion_wrappers/zephyr.py +14 -14
  23. letta/local_llm/utils.py +1 -2
  24. letta/orm/agent.py +3 -3
  25. letta/orm/block.py +4 -4
  26. letta/orm/files_agents.py +0 -1
  27. letta/orm/identity.py +2 -0
  28. letta/orm/mcp_server.py +0 -2
  29. letta/orm/message.py +140 -14
  30. letta/orm/organization.py +5 -5
  31. letta/orm/passage.py +4 -4
  32. letta/orm/source.py +1 -1
  33. letta/orm/sqlalchemy_base.py +61 -39
  34. letta/orm/step.py +2 -0
  35. letta/otel/db_pool_monitoring.py +308 -0
  36. letta/otel/metric_registry.py +94 -1
  37. letta/otel/sqlalchemy_instrumentation.py +548 -0
  38. letta/otel/sqlalchemy_instrumentation_integration.py +124 -0
  39. letta/otel/tracing.py +37 -1
  40. letta/schemas/agent.py +0 -3
  41. letta/schemas/agent_file.py +283 -0
  42. letta/schemas/block.py +0 -3
  43. letta/schemas/file.py +28 -26
  44. letta/schemas/letta_message.py +15 -4
  45. letta/schemas/memory.py +1 -1
  46. letta/schemas/message.py +31 -26
  47. letta/schemas/openai/chat_completion_response.py +0 -1
  48. letta/schemas/providers.py +20 -0
  49. letta/schemas/source.py +11 -13
  50. letta/schemas/step.py +12 -0
  51. letta/schemas/tool.py +0 -4
  52. letta/serialize_schemas/marshmallow_agent.py +14 -1
  53. letta/serialize_schemas/marshmallow_block.py +23 -1
  54. letta/serialize_schemas/marshmallow_message.py +1 -3
  55. letta/serialize_schemas/marshmallow_tool.py +23 -1
  56. letta/server/db.py +110 -6
  57. letta/server/rest_api/app.py +85 -73
  58. letta/server/rest_api/routers/v1/agents.py +68 -53
  59. letta/server/rest_api/routers/v1/blocks.py +2 -2
  60. letta/server/rest_api/routers/v1/jobs.py +3 -0
  61. letta/server/rest_api/routers/v1/organizations.py +2 -2
  62. letta/server/rest_api/routers/v1/sources.py +18 -2
  63. letta/server/rest_api/routers/v1/tools.py +11 -12
  64. letta/server/rest_api/routers/v1/users.py +1 -1
  65. letta/server/rest_api/streaming_response.py +13 -5
  66. letta/server/rest_api/utils.py +8 -25
  67. letta/server/server.py +11 -4
  68. letta/server/ws_api/server.py +2 -2
  69. letta/services/agent_file_manager.py +616 -0
  70. letta/services/agent_manager.py +133 -46
  71. letta/services/block_manager.py +38 -17
  72. letta/services/file_manager.py +106 -21
  73. letta/services/file_processor/file_processor.py +93 -0
  74. letta/services/files_agents_manager.py +28 -0
  75. letta/services/group_manager.py +4 -5
  76. letta/services/helpers/agent_manager_helper.py +57 -9
  77. letta/services/identity_manager.py +22 -0
  78. letta/services/job_manager.py +210 -91
  79. letta/services/llm_batch_manager.py +9 -6
  80. letta/services/mcp/stdio_client.py +1 -2
  81. letta/services/mcp_manager.py +0 -1
  82. letta/services/message_manager.py +49 -26
  83. letta/services/passage_manager.py +0 -1
  84. letta/services/provider_manager.py +1 -1
  85. letta/services/source_manager.py +114 -5
  86. letta/services/step_manager.py +36 -4
  87. letta/services/telemetry_manager.py +9 -2
  88. letta/services/tool_executor/builtin_tool_executor.py +5 -1
  89. letta/services/tool_executor/core_tool_executor.py +3 -3
  90. letta/services/tool_manager.py +95 -20
  91. letta/services/user_manager.py +4 -12
  92. letta/settings.py +23 -6
  93. letta/system.py +1 -1
  94. letta/utils.py +26 -2
  95. {letta_nightly-0.8.15.dev20250719104256.dist-info → letta_nightly-0.8.16.dev20250721070720.dist-info}/METADATA +3 -2
  96. {letta_nightly-0.8.15.dev20250719104256.dist-info → letta_nightly-0.8.16.dev20250721070720.dist-info}/RECORD +99 -94
  97. {letta_nightly-0.8.15.dev20250719104256.dist-info → letta_nightly-0.8.16.dev20250721070720.dist-info}/LICENSE +0 -0
  98. {letta_nightly-0.8.15.dev20250719104256.dist-info → letta_nightly-0.8.16.dev20250721070720.dist-info}/WHEEL +0 -0
  99. {letta_nightly-0.8.15.dev20250719104256.dist-info → letta_nightly-0.8.16.dev20250721070720.dist-info}/entry_points.txt +0 -0
letta/__init__.py CHANGED
@@ -5,7 +5,7 @@ try:
5
5
  __version__ = version("letta")
6
6
  except PackageNotFoundError:
7
7
  # Fallback for development installations
8
- __version__ = "0.8.15"
8
+ __version__ = "0.8.16"
9
9
 
10
10
  if os.environ.get("LETTA_VERSION"):
11
11
  __version__ = os.environ["LETTA_VERSION"]
letta/agent.py CHANGED
@@ -1304,12 +1304,11 @@ class Agent(BaseAgent):
1304
1304
  async def get_context_window_from_tiktoken_async(self) -> ContextWindowOverview:
1305
1305
  """Get the context window of the agent"""
1306
1306
  # Grab the in-context messages
1307
- # conversion of messages to OpenAI dict format, which is passed to the token counter
1308
- (in_context_messages, passage_manager_size, message_manager_size) = await asyncio.gather(
1309
- self.message_manager.get_messages_by_ids_async(message_ids=self.agent_state.message_ids, actor=self.user),
1310
- self.passage_manager.agent_passage_size_async(actor=self.user, agent_id=self.agent_state.id),
1311
- self.message_manager.size_async(actor=self.user, agent_id=self.agent_state.id),
1307
+ in_context_messages = await self.message_manager.get_messages_by_ids_async(
1308
+ message_ids=self.agent_state.message_ids, actor=self.user
1312
1309
  )
1310
+
1311
+ # conversion of messages to OpenAI dict format, which is passed to the token counter
1313
1312
  in_context_messages_openai = [m.to_openai_dict() for m in in_context_messages]
1314
1313
 
1315
1314
  # Extract system, memory and external summary
@@ -1396,6 +1395,15 @@ class Agent(BaseAgent):
1396
1395
  )
1397
1396
  assert isinstance(num_tokens_used_total, int)
1398
1397
 
1398
+ passage_manager_size = await self.passage_manager.agent_passage_size_async(
1399
+ agent_id=self.agent_state.id,
1400
+ actor=self.user,
1401
+ )
1402
+ message_manager_size = await self.message_manager.size_async(
1403
+ agent_id=self.agent_state.id,
1404
+ actor=self.user,
1405
+ )
1406
+
1399
1407
  return ContextWindowOverview(
1400
1408
  # context window breakdown (in messages)
1401
1409
  num_messages=len(in_context_messages),
@@ -1426,12 +1434,11 @@ class Agent(BaseAgent):
1426
1434
  model = self.agent_state.llm_config.model if self.agent_state.llm_config.model_endpoint_type == "anthropic" else None
1427
1435
 
1428
1436
  # Grab the in-context messages
1429
- # conversion of messages to anthropic dict format, which is passed to the token counter
1430
- (in_context_messages, passage_manager_size, message_manager_size) = await asyncio.gather(
1431
- self.message_manager.get_messages_by_ids_async(message_ids=self.agent_state.message_ids, actor=self.user),
1432
- self.passage_manager.agent_passage_size_async(actor=self.user, agent_id=self.agent_state.id),
1433
- self.message_manager.size_async(actor=self.user, agent_id=self.agent_state.id),
1437
+ in_context_messages = await self.message_manager.get_messages_by_ids_async(
1438
+ message_ids=self.agent_state.message_ids, actor=self.user
1434
1439
  )
1440
+
1441
+ # conversion of messages to anthropic dict format, which is passed to the token counter
1435
1442
  in_context_messages_anthropic = [m.to_anthropic_dict() for m in in_context_messages]
1436
1443
 
1437
1444
  # Extract system, memory and external summary
@@ -1546,6 +1553,15 @@ class Agent(BaseAgent):
1546
1553
  )
1547
1554
  assert isinstance(num_tokens_used_total, int)
1548
1555
 
1556
+ passage_manager_size = await self.passage_manager.agent_passage_size_async(
1557
+ agent_id=self.agent_state.id,
1558
+ actor=self.user,
1559
+ )
1560
+ message_manager_size = await self.message_manager.size_async(
1561
+ agent_id=self.agent_state.id,
1562
+ actor=self.user,
1563
+ )
1564
+
1549
1565
  return ContextWindowOverview(
1550
1566
  # context window breakdown (in messages)
1551
1567
  num_messages=len(in_context_messages),
@@ -1625,7 +1641,7 @@ class Agent(BaseAgent):
1625
1641
  # Get the MCPClient from the server's handle
1626
1642
  # TODO these don't get raised properly
1627
1643
  if not self.mcp_clients:
1628
- raise ValueError(f"No MCP client available to use")
1644
+ raise ValueError("No MCP client available to use")
1629
1645
  if server_name not in self.mcp_clients:
1630
1646
  raise ValueError(f"Unknown MCP server name: {server_name}")
1631
1647
  mcp_client = self.mcp_clients[server_name]
letta/agents/helpers.py CHANGED
@@ -235,5 +235,5 @@ def _pop_heartbeat(tool_args: dict) -> bool:
235
235
  def _build_rule_violation_result(tool_name: str, valid: list[str], solver: ToolRulesSolver) -> ToolExecutionResult:
236
236
  hint_lines = solver.guess_rule_violation(tool_name)
237
237
  hint_txt = ("\n** Hint: Possible rules that were violated:\n" + "\n".join(f"\t- {h}" for h in hint_lines)) if hint_lines else ""
238
- msg = f"[ToolConstraintError] Cannot call {tool_name}, " f"valid tools include: {valid}.{hint_txt}"
238
+ msg = f"[ToolConstraintError] Cannot call {tool_name}, valid tools include: {valid}.{hint_txt}"
239
239
  return ToolExecutionResult(status="error", func_return=msg)