letta-nightly 0.13.0.dev20251031104146__py3-none-any.whl → 0.13.1.dev20251101010313__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.

Files changed (105) hide show
  1. letta/__init__.py +1 -1
  2. letta/adapters/simple_llm_stream_adapter.py +1 -0
  3. letta/agents/letta_agent_v2.py +8 -0
  4. letta/agents/letta_agent_v3.py +127 -27
  5. letta/agents/temporal/activities/__init__.py +25 -0
  6. letta/agents/temporal/activities/create_messages.py +26 -0
  7. letta/agents/temporal/activities/create_step.py +57 -0
  8. letta/agents/temporal/activities/example_activity.py +9 -0
  9. letta/agents/temporal/activities/execute_tool.py +130 -0
  10. letta/agents/temporal/activities/llm_request.py +114 -0
  11. letta/agents/temporal/activities/prepare_messages.py +27 -0
  12. letta/agents/temporal/activities/refresh_context.py +160 -0
  13. letta/agents/temporal/activities/summarize_conversation_history.py +77 -0
  14. letta/agents/temporal/activities/update_message_ids.py +25 -0
  15. letta/agents/temporal/activities/update_run.py +43 -0
  16. letta/agents/temporal/constants.py +59 -0
  17. letta/agents/temporal/temporal_agent_workflow.py +704 -0
  18. letta/agents/temporal/types.py +275 -0
  19. letta/constants.py +11 -0
  20. letta/errors.py +4 -0
  21. letta/functions/function_sets/base.py +0 -11
  22. letta/groups/helpers.py +7 -1
  23. letta/groups/sleeptime_multi_agent_v4.py +4 -3
  24. letta/interfaces/anthropic_streaming_interface.py +0 -1
  25. letta/interfaces/openai_streaming_interface.py +103 -100
  26. letta/llm_api/anthropic_client.py +57 -12
  27. letta/llm_api/bedrock_client.py +1 -0
  28. letta/llm_api/deepseek_client.py +3 -2
  29. letta/llm_api/google_vertex_client.py +5 -4
  30. letta/llm_api/groq_client.py +1 -0
  31. letta/llm_api/llm_client_base.py +15 -1
  32. letta/llm_api/openai.py +2 -2
  33. letta/llm_api/openai_client.py +17 -3
  34. letta/llm_api/xai_client.py +1 -0
  35. letta/orm/agent.py +3 -0
  36. letta/orm/organization.py +4 -0
  37. letta/orm/sqlalchemy_base.py +7 -0
  38. letta/otel/tracing.py +131 -4
  39. letta/schemas/agent.py +108 -40
  40. letta/schemas/agent_file.py +10 -10
  41. letta/schemas/block.py +22 -3
  42. letta/schemas/enums.py +21 -0
  43. letta/schemas/environment_variables.py +3 -2
  44. letta/schemas/group.py +3 -3
  45. letta/schemas/letta_response.py +36 -4
  46. letta/schemas/llm_batch_job.py +3 -3
  47. letta/schemas/llm_config.py +123 -4
  48. letta/schemas/mcp.py +3 -2
  49. letta/schemas/mcp_server.py +3 -2
  50. letta/schemas/message.py +167 -49
  51. letta/schemas/model.py +265 -0
  52. letta/schemas/organization.py +2 -1
  53. letta/schemas/passage.py +2 -1
  54. letta/schemas/provider_trace.py +2 -1
  55. letta/schemas/providers/openrouter.py +1 -2
  56. letta/schemas/run_metrics.py +2 -1
  57. letta/schemas/sandbox_config.py +3 -1
  58. letta/schemas/step_metrics.py +2 -1
  59. letta/schemas/tool_rule.py +2 -2
  60. letta/schemas/user.py +2 -1
  61. letta/server/rest_api/app.py +5 -1
  62. letta/server/rest_api/routers/v1/__init__.py +4 -0
  63. letta/server/rest_api/routers/v1/agents.py +71 -9
  64. letta/server/rest_api/routers/v1/blocks.py +7 -7
  65. letta/server/rest_api/routers/v1/groups.py +40 -0
  66. letta/server/rest_api/routers/v1/identities.py +2 -2
  67. letta/server/rest_api/routers/v1/internal_agents.py +31 -0
  68. letta/server/rest_api/routers/v1/internal_blocks.py +177 -0
  69. letta/server/rest_api/routers/v1/internal_runs.py +25 -1
  70. letta/server/rest_api/routers/v1/runs.py +2 -22
  71. letta/server/rest_api/routers/v1/tools.py +12 -1
  72. letta/server/server.py +20 -4
  73. letta/services/agent_manager.py +4 -4
  74. letta/services/archive_manager.py +16 -0
  75. letta/services/group_manager.py +44 -0
  76. letta/services/helpers/run_manager_helper.py +2 -2
  77. letta/services/lettuce/lettuce_client.py +148 -0
  78. letta/services/mcp/base_client.py +9 -3
  79. letta/services/run_manager.py +148 -37
  80. letta/services/source_manager.py +91 -3
  81. letta/services/step_manager.py +2 -3
  82. letta/services/streaming_service.py +52 -13
  83. letta/services/summarizer/summarizer.py +28 -2
  84. letta/services/tool_executor/builtin_tool_executor.py +1 -1
  85. letta/services/tool_executor/core_tool_executor.py +2 -117
  86. letta/services/tool_sandbox/e2b_sandbox.py +4 -1
  87. letta/services/tool_schema_generator.py +2 -2
  88. letta/validators.py +21 -0
  89. {letta_nightly-0.13.0.dev20251031104146.dist-info → letta_nightly-0.13.1.dev20251101010313.dist-info}/METADATA +1 -1
  90. {letta_nightly-0.13.0.dev20251031104146.dist-info → letta_nightly-0.13.1.dev20251101010313.dist-info}/RECORD +93 -87
  91. letta/agent.py +0 -1758
  92. letta/cli/cli_load.py +0 -16
  93. letta/client/__init__.py +0 -0
  94. letta/client/streaming.py +0 -95
  95. letta/client/utils.py +0 -78
  96. letta/functions/async_composio_toolset.py +0 -109
  97. letta/functions/composio_helpers.py +0 -96
  98. letta/helpers/composio_helpers.py +0 -38
  99. letta/orm/job_messages.py +0 -33
  100. letta/schemas/providers.py +0 -1617
  101. letta/server/rest_api/routers/openai/chat_completions/chat_completions.py +0 -132
  102. letta/services/tool_executor/composio_tool_executor.py +0 -57
  103. {letta_nightly-0.13.0.dev20251031104146.dist-info → letta_nightly-0.13.1.dev20251101010313.dist-info}/WHEEL +0 -0
  104. {letta_nightly-0.13.0.dev20251031104146.dist-info → letta_nightly-0.13.1.dev20251101010313.dist-info}/entry_points.txt +0 -0
  105. {letta_nightly-0.13.0.dev20251031104146.dist-info → letta_nightly-0.13.1.dev20251101010313.dist-info}/licenses/LICENSE +0 -0
@@ -4,7 +4,13 @@ import traceback
4
4
  from typing import List, Optional, Tuple, Union
5
5
 
6
6
  from letta.agents.ephemeral_summary_agent import EphemeralSummaryAgent
7
- from letta.constants import DEFAULT_MESSAGE_TOOL, DEFAULT_MESSAGE_TOOL_KWARG, MESSAGE_SUMMARY_REQUEST_ACK
7
+ from letta.constants import (
8
+ DEFAULT_MESSAGE_TOOL,
9
+ DEFAULT_MESSAGE_TOOL_KWARG,
10
+ MESSAGE_SUMMARY_REQUEST_ACK,
11
+ TOOL_RETURN_TRUNCATION_CHARS,
12
+ )
13
+ from letta.errors import ContextWindowExceededError
8
14
  from letta.helpers.message_helper import convert_message_creates_to_messages
9
15
  from letta.llm_api.llm_client import LLMClient
10
16
  from letta.log import get_logger
@@ -394,7 +400,27 @@ async def simple_summary(messages: List[Message], llm_config: LLMConfig, actor:
394
400
  response_data = await llm_client.request_async(request_data, summarizer_llm_config)
395
401
  except Exception as e:
396
402
  # handle LLM error (likely a context window exceeded error)
397
- raise llm_client.handle_llm_error(e)
403
+ try:
404
+ raise llm_client.handle_llm_error(e)
405
+ except ContextWindowExceededError as context_error:
406
+ logger.warning(
407
+ f"Context window exceeded during summarization, falling back to truncated tool returns. Original error: {context_error}"
408
+ )
409
+
410
+ # Fallback: rebuild request with truncated tool returns
411
+ request_data = llm_client.build_request_data(
412
+ AgentType.letta_v1_agent,
413
+ input_messages_obj,
414
+ summarizer_llm_config,
415
+ tools=[],
416
+ tool_return_truncation_chars=TOOL_RETURN_TRUNCATION_CHARS,
417
+ )
418
+
419
+ try:
420
+ response_data = await llm_client.request_async(request_data, summarizer_llm_config)
421
+ except Exception as fallback_error:
422
+ logger.error(f"Fallback summarization also failed: {fallback_error}")
423
+ raise llm_client.handle_llm_error(fallback_error)
398
424
  response = llm_client.convert_response_to_chat_completion(response_data, input_messages_obj, summarizer_llm_config)
399
425
  if response.choices[0].message.content is None:
400
426
  logger.warning("No content returned from summarizer")
@@ -189,7 +189,7 @@ class LettaBuiltinToolExecutor(ToolExecutor):
189
189
  return json.dumps(response, indent=2, ensure_ascii=False)
190
190
 
191
191
  except Exception as e:
192
- logger.error(f"Exa search failed for query '{query}': {str(e)}")
192
+ logger.info(f"Exa search failed for query '{query}': {str(e)}")
193
193
  return json.dumps({"query": query, "error": f"Search failed: {str(e)}"})
194
194
 
195
195
  async def fetch_webpage(self, agent_state: "AgentState", url: str) -> str:
@@ -688,115 +688,6 @@ class LettaCoreToolExecutor(ToolExecutor):
688
688
  except Exception as e:
689
689
  raise Exception(f"Error performing rename: {str(e)}")
690
690
 
691
- async def memory_view(self, agent_state: AgentState, actor: User, path: str, view_range: Optional[int] = None) -> str:
692
- """View the content of a memory block with optional line range."""
693
- try:
694
- # Special case: if path is "/memories", list all blocks
695
- if path == "/memories":
696
- blocks = agent_state.memory.get_blocks()
697
-
698
- if not blocks:
699
- raise ValueError("No memory blocks found.")
700
-
701
- result_lines = [f"Found {len(blocks)} memory block(s):\n"]
702
-
703
- for i, block in enumerate(blocks, 1):
704
- content = str(block.value)
705
- content_length = len(content)
706
- line_count = len(content.split("\n")) if content else 0
707
-
708
- # Basic info
709
- block_info = [f"{i}. {block.label}"]
710
-
711
- # Add description if available
712
- if block.description:
713
- block_info.append(f" Description: {block.description}")
714
-
715
- # Add read-only status
716
- if block.read_only:
717
- block_info.append(" Read-only: true")
718
-
719
- # Add content stats
720
- block_info.append(f" Character limit: {block.limit}")
721
- block_info.append(f" Current length: {content_length} characters")
722
- block_info.append(f" Lines: {line_count}")
723
-
724
- # Add content preview (first 100 characters)
725
- if content:
726
- preview = content[:100].replace("\n", "\\n")
727
- if len(content) > 100:
728
- preview += "..."
729
- block_info.append(f" Preview: {preview}")
730
- else:
731
- block_info.append(" Preview: (empty)")
732
-
733
- result_lines.append("\n".join(block_info))
734
- if i < len(blocks): # Add separator between blocks
735
- result_lines.append("")
736
-
737
- return "\n".join(result_lines)
738
-
739
- # Extract memory block label from path (e.g., "/memories/preferences.txt" -> "preferences.txt")
740
- if path.startswith("/memories/"):
741
- label = path[10:] # Remove "/memories/" prefix
742
- else:
743
- label = path
744
-
745
- # Get the memory block
746
- memory_block = agent_state.memory.get_block(label)
747
- if memory_block is None:
748
- raise ValueError(f"Error: Memory block '{label}' does not exist")
749
-
750
- # Get the content
751
- content = str(memory_block.value)
752
- if not content:
753
- raise ValueError(f"Memory block '{label}' is empty")
754
-
755
- # Split content into lines
756
- lines = content.split("\n")
757
- total_lines = len(lines)
758
-
759
- # Handle view_range parameter
760
- if view_range is not None:
761
- if view_range <= 0:
762
- raise ValueError(f"Error: view_range must be positive, got {view_range}")
763
-
764
- # Show only the first view_range lines
765
- lines_to_show = lines[:view_range]
766
- range_info = f" (showing first {view_range} of {total_lines} lines)"
767
- else:
768
- lines_to_show = lines
769
- range_info = f" ({total_lines} lines total)"
770
-
771
- # Format output with line numbers
772
- numbered_lines = []
773
- for i, line in enumerate(lines_to_show, start=1):
774
- numbered_lines.append(f"Line {i}: {line}")
775
-
776
- numbered_content = "\n".join(numbered_lines)
777
-
778
- # Add metadata information
779
- metadata_info = []
780
- if memory_block.description:
781
- metadata_info.append(f"Description: {memory_block.description}")
782
- if memory_block.read_only:
783
- metadata_info.append("Read-only: true")
784
- metadata_info.append(f"Character limit: {memory_block.limit}")
785
- metadata_info.append(f"Current length: {len(content)} characters")
786
-
787
- metadata_str = "\n".join(metadata_info)
788
-
789
- result = f"Memory block: {label}{range_info}\n"
790
- result += f"Metadata:\n{metadata_str}\n\n"
791
- result += f"Content:\n{numbered_content}"
792
-
793
- return result
794
-
795
- except KeyError:
796
- raise ValueError(f"Error: Memory block '{label}' does not exist")
797
- except Exception as e:
798
- raise Exception(f"Error viewing memory block: {str(e)}")
799
-
800
691
  async def memory_create(
801
692
  self, agent_state: AgentState, actor: User, path: str, description: str, file_text: Optional[str] = None
802
693
  ) -> str:
@@ -961,14 +852,8 @@ class LettaCoreToolExecutor(ToolExecutor):
961
852
  insert_text: Optional[str] = None,
962
853
  old_path: Optional[str] = None,
963
854
  new_path: Optional[str] = None,
964
- view_range: Optional[int] = None,
965
855
  ) -> Optional[str]:
966
- if command == "view":
967
- if path is None:
968
- raise ValueError("Error: path is required for view command")
969
- return await self.memory_view(agent_state, actor, path, view_range)
970
-
971
- elif command == "create":
856
+ if command == "create":
972
857
  if path is None:
973
858
  raise ValueError("Error: path is required for create command")
974
859
  if description is None:
@@ -1007,4 +892,4 @@ class LettaCoreToolExecutor(ToolExecutor):
1007
892
  )
1008
893
 
1009
894
  else:
1010
- raise ValueError(f"Error: Unknown command '{command}'. Supported commands: str_replace, str_insert, insert, delete, rename")
895
+ raise ValueError(f"Error: Unknown command '{command}'. Supported commands: create, str_replace, insert, delete, rename")
@@ -102,7 +102,10 @@ class AsyncToolSandboxE2B(AsyncToolSandboxBase):
102
102
  function_name=self.tool_name, exception_name=execution.error.name, exception_message=execution.error.value
103
103
  )
104
104
  execution.logs.stderr.append(execution.error.traceback)
105
- logger.info(f"E2B execution failed for ID {e2b_sandbox.sandbox_id}: {self.tool_name}")
105
+ logger.info(
106
+ f"E2B execution failed for ID {e2b_sandbox.sandbox_id}: {self.tool_name} - {execution.error.name}: {execution.error.value}"
107
+ )
108
+ logger.info(f"Traceback from e2b sandbox: \n{execution.error.traceback}")
106
109
  log_event(
107
110
  "e2b_execution_failed",
108
111
  {
@@ -45,7 +45,7 @@ def generate_schema_for_tool_creation(
45
45
 
46
46
  return derive_typescript_json_schema(source_code=tool.source_code)
47
47
  except Exception as e:
48
- logger.error(f"Failed to derive TypeScript json schema: {e}")
48
+ logger.warning(f"Failed to derive TypeScript json schema: {e}")
49
49
  raise ValueError(f"Failed to derive TypeScript json schema: {e}")
50
50
 
51
51
  # Python tools (default if not specified for backwards compatibility)
@@ -65,7 +65,7 @@ def generate_schema_for_tool_creation(
65
65
  try:
66
66
  return derive_openai_json_schema(source_code=tool.source_code)
67
67
  except Exception as e:
68
- logger.error(f"Failed to derive json schema: {e}")
68
+ logger.warning(f"Failed to derive json schema: {e}")
69
69
  raise ValueError(f"Failed to derive json schema: {e}")
70
70
  else:
71
71
  # TODO: convert to explicit error
letta/validators.py CHANGED
@@ -63,6 +63,27 @@ SandboxConfigId = Annotated[str, PATH_VALIDATORS[PrimitiveType.SANDBOX_CONFIG.va
63
63
  StepId = Annotated[str, PATH_VALIDATORS[PrimitiveType.STEP.value]()]
64
64
  IdentityId = Annotated[str, PATH_VALIDATORS[PrimitiveType.IDENTITY.value]()]
65
65
 
66
+ # Infrastructure types
67
+ McpServerId = Annotated[str, PATH_VALIDATORS[PrimitiveType.MCP_SERVER.value]()]
68
+ McpOAuthId = Annotated[str, PATH_VALIDATORS[PrimitiveType.MCP_OAUTH.value]()]
69
+ FileAgentId = Annotated[str, PATH_VALIDATORS[PrimitiveType.FILE_AGENT.value]()]
70
+
71
+ # Configuration types
72
+ SandboxEnvId = Annotated[str, PATH_VALIDATORS[PrimitiveType.SANDBOX_ENV.value]()]
73
+ AgentEnvId = Annotated[str, PATH_VALIDATORS[PrimitiveType.AGENT_ENV.value]()]
74
+
75
+ # Core entity types
76
+ UserId = Annotated[str, PATH_VALIDATORS[PrimitiveType.USER.value]()]
77
+ OrganizationId = Annotated[str, PATH_VALIDATORS[PrimitiveType.ORGANIZATION.value]()]
78
+ ToolRuleId = Annotated[str, PATH_VALIDATORS[PrimitiveType.TOOL_RULE.value]()]
79
+
80
+ # Batch processing types
81
+ BatchItemId = Annotated[str, PATH_VALIDATORS[PrimitiveType.BATCH_ITEM.value]()]
82
+ BatchRequestId = Annotated[str, PATH_VALIDATORS[PrimitiveType.BATCH_REQUEST.value]()]
83
+
84
+ # Telemetry types
85
+ ProviderTraceId = Annotated[str, PATH_VALIDATORS[PrimitiveType.PROVIDER_TRACE.value]()]
86
+
66
87
 
67
88
  def raise_on_invalid_id(param_name: str, expected_prefix: PrimitiveType):
68
89
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: letta-nightly
3
- Version: 0.13.0.dev20251031104146
3
+ Version: 0.13.1.dev20251101010313
4
4
  Summary: Create LLM agents with long-term memory and custom tools
5
5
  Author-email: Letta Team <contact@letta.com>
6
6
  License: Apache License