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
letta/schemas/agent.py CHANGED
@@ -17,6 +17,7 @@ from letta.schemas.letta_base import OrmMetadataBase
17
17
  from letta.schemas.llm_config import LLMConfig
18
18
  from letta.schemas.memory import Memory
19
19
  from letta.schemas.message import Message, MessageCreate
20
+ from letta.schemas.model import EmbeddingModelSettings, ModelSettings
20
21
  from letta.schemas.openai.chat_completion_response import UsageStatistics
21
22
  from letta.schemas.response_format import ResponseFormatUnion
22
23
  from letta.schemas.source import Source
@@ -87,11 +88,19 @@ class AgentState(OrmMetadataBase, validate_assignment=True):
87
88
  # agent configuration
88
89
  agent_type: AgentType = Field(..., description="The type of agent.")
89
90
 
90
- # llm information
91
- llm_config: LLMConfig = Field(..., description="The LLM configuration used by the agent.")
92
- embedding_config: EmbeddingConfig = Field(..., description="The embedding configuration used by the agent.")
91
+ # model information
92
+ llm_config: LLMConfig = Field(
93
+ ..., description="Deprecated: Use `model` field instead. The LLM configuration used by the agent.", deprecated=True
94
+ )
95
+ embedding_config: EmbeddingConfig = Field(
96
+ ..., description="Deprecated: Use `embedding` field instead. The embedding configuration used by the agent.", deprecated=True
97
+ )
98
+ model: Optional[ModelSettings] = Field(None, description="The model used by the agent.")
99
+ embedding: Optional[EmbeddingModelSettings] = Field(None, description="The embedding model used by the agent.")
100
+
93
101
  response_format: Optional[ResponseFormatUnion] = Field(
94
- None, description="The response format used by the agent when returning from `send_message`."
102
+ None,
103
+ description="The response format used by the agent",
95
104
  )
96
105
 
97
106
  # This is an object representing the in-process state of a running `Agent`
@@ -99,7 +108,7 @@ class AgentState(OrmMetadataBase, validate_assignment=True):
99
108
  description: Optional[str] = Field(None, description="The description of the agent.")
100
109
  metadata: Optional[Dict] = Field(None, description="The metadata of the agent.")
101
110
 
102
- memory: Memory = Field(..., description="The in-context memory of the agent.", deprecated=True)
111
+ memory: Memory = Field(..., description="Deprecated: Use `blocks` field instead. The in-context memory of the agent.", deprecated=True)
103
112
  blocks: List[Block] = Field(..., description="The memory blocks used by the agent.")
104
113
  tools: List[Tool] = Field(..., description="The tools used by the agent.")
105
114
  sources: List[Source] = Field(..., description="The sources used by the agent.")
@@ -117,7 +126,9 @@ class AgentState(OrmMetadataBase, validate_assignment=True):
117
126
  base_template_id: Optional[str] = Field(None, description="The base template id of the agent.")
118
127
  deployment_id: Optional[str] = Field(None, description="The id of the deployment.")
119
128
  entity_id: Optional[str] = Field(None, description="The id of the entity within the template.")
120
- identity_ids: List[str] = Field([], description="The ids of the identities associated with this agent.", deprecated=True)
129
+ identity_ids: List[str] = Field(
130
+ [], description="Deprecated: Use `identities` field instead. The ids of the identities associated with this agent.", deprecated=True
131
+ )
121
132
  identities: List[Identity] = Field([], description="The identities associated with this agent.")
122
133
 
123
134
  # An advanced configuration that makes it so this agent does not remember any previous messages
@@ -130,7 +141,9 @@ class AgentState(OrmMetadataBase, validate_assignment=True):
130
141
  description="If set to True, memory management will move to a background agent thread.",
131
142
  )
132
143
 
133
- multi_agent_group: Optional[Group] = Field(None, description="The multi-agent group that this agent manages", deprecated=True)
144
+ multi_agent_group: Optional[Group] = Field(
145
+ None, description="Deprecated: Use `managed_group` field instead. The multi-agent group that this agent manages.", deprecated=True
146
+ )
134
147
  managed_group: Optional[Group] = Field(None, description="The multi-agent group that this agent manages")
135
148
  # Run metrics
136
149
  last_run_completion: Optional[datetime] = Field(None, description="The timestamp when the agent last completed a run.")
@@ -202,8 +215,6 @@ class CreateAgent(BaseModel, validate_assignment=True): #
202
215
  tags: Optional[List[str]] = Field(None, description="The tags associated with the agent.")
203
216
  system: Optional[str] = Field(None, description="The system prompt used by the agent.")
204
217
  agent_type: AgentType = Field(default_factory=lambda: AgentType.memgpt_v2_agent, description="The type of agent.")
205
- llm_config: Optional[LLMConfig] = Field(None, description="The LLM configuration used by the agent.")
206
- embedding_config: Optional[EmbeddingConfig] = Field(None, description="The embedding configuration used by the agent.")
207
218
  # Note: if this is None, then we'll populate with the standard "more human than human" initial message sequence
208
219
  # If the client wants to make this empty, then the client can set the arg to an empty list
209
220
  initial_message_sequence: Optional[List[MessageCreate]] = Field(
@@ -216,43 +227,78 @@ class CreateAgent(BaseModel, validate_assignment=True): #
216
227
  include_base_tool_rules: Optional[bool] = Field(
217
228
  None, description="If true, attaches the Letta base tool rules (e.g. deny all tools not explicitly allowed)."
218
229
  )
219
- include_default_source: bool = Field(
220
- False, description="If true, automatically creates and attaches a default data source for this agent."
230
+ include_default_source: bool = Field( # TODO: get rid of this
231
+ False, description="If true, automatically creates and attaches a default data source for this agent.", deprecated=True
221
232
  )
222
233
  description: Optional[str] = Field(None, description="The description of the agent.")
223
234
  metadata: Optional[Dict] = Field(None, description="The metadata of the agent.")
224
- model: Optional[str] = Field(
235
+
236
+ # model configuration
237
+ llm_config: Optional[LLMConfig] = Field(
238
+ None, description="Deprecated: Use `model` field instead. The LLM configuration used by the agent.", deprecated=True
239
+ )
240
+ embedding_config: Optional[EmbeddingConfig] = Field(
241
+ None, description="Deprecated: Use `embedding` field instead. The embedding configuration used by the agent.", deprecated=True
242
+ )
243
+ model: Optional[str | ModelSettings] = Field( # TODO: make this required (breaking change)
225
244
  None,
226
- description="The LLM configuration handle used by the agent, specified in the format "
227
- "provider/model-name, as an alternative to specifying llm_config.",
245
+ description="The model handle or model settings for the agent to use, specified either by a handle or an object. See the model schema for more information.",
228
246
  )
229
- embedding: Optional[str] = Field(
247
+ embedding: Optional[str | EmbeddingModelSettings] = Field(
230
248
  None, description="The embedding configuration handle used by the agent, specified in the format provider/model-name."
231
249
  )
250
+
232
251
  context_window_limit: Optional[int] = Field(None, description="The context window limit used by the agent.")
233
- embedding_chunk_size: Optional[int] = Field(DEFAULT_EMBEDDING_CHUNK_SIZE, description="The embedding chunk size used by the agent.")
252
+ embedding_chunk_size: Optional[int] = Field(
253
+ DEFAULT_EMBEDDING_CHUNK_SIZE, description="Deprecated: No longer used. The embedding chunk size used by the agent.", deprecated=True
254
+ )
234
255
  max_tokens: Optional[int] = Field(
235
256
  None,
236
- description="The maximum number of tokens to generate, including reasoning step. If not set, the model will use its default value.",
257
+ description="Deprecated: Use `model` field to configure max output tokens instead. The maximum number of tokens to generate, including reasoning step.",
258
+ deprecated=True,
237
259
  )
238
260
  max_reasoning_tokens: Optional[int] = Field(
239
- None, description="The maximum number of tokens to generate for reasoning step. If not set, the model will use its default value."
261
+ None,
262
+ description="Deprecated: Use `model` field to configure reasoning tokens instead. The maximum number of tokens to generate for reasoning step.",
263
+ deprecated=True,
264
+ )
265
+ enable_reasoner: Optional[bool] = Field(
266
+ True,
267
+ description="Deprecated: Use `model` field to configure reasoning instead. Whether to enable internal extended thinking step for a reasoner model.",
268
+ deprecated=True,
269
+ )
270
+ reasoning: Optional[bool] = Field(
271
+ None,
272
+ description="Deprecated: Use `model` field to configure reasoning instead. Whether to enable reasoning for this agent.",
273
+ deprecated=True,
274
+ )
275
+ from_template: Optional[str] = Field(
276
+ None, description="Deprecated: please use the 'create agents from a template' endpoint instead.", deprecated=True
240
277
  )
241
- enable_reasoner: Optional[bool] = Field(True, description="Whether to enable internal extended thinking step for a reasoner model.")
242
- reasoning: Optional[bool] = Field(None, description="Whether to enable reasoning for this agent.")
243
- from_template: Optional[str] = Field(None, description="Deprecated: please use the 'create agents from a template' endpoint instead.")
244
- template: bool = Field(False, description="Deprecated: No longer used")
278
+ template: bool = Field(False, description="Deprecated: No longer used.", deprecated=True)
245
279
  project: Optional[str] = Field(
246
280
  None,
247
281
  deprecated=True,
248
- description="Deprecated: Project should now be passed via the X-Project header instead of in the request body. If using the sdk, this can be done via the new x_project field below.",
282
+ description="Deprecated: Project should now be passed via the X-Project header instead of in the request body. If using the SDK, this can be done via the x_project parameter.",
283
+ )
284
+ tool_exec_environment_variables: Optional[Dict[str, str]] = Field(
285
+ None, description="Deprecated: Use `secrets` field instead. Environment variables for tool execution.", deprecated=True
249
286
  )
250
- tool_exec_environment_variables: Optional[Dict[str, str]] = Field(None, description="Deprecated: use `secrets` field instead.")
251
287
  secrets: Optional[Dict[str, str]] = Field(None, description="The environment variables for tool execution specific to this agent.")
252
- memory_variables: Optional[Dict[str, str]] = Field(None, description="The variables that should be set for the agent.")
253
- project_id: Optional[str] = Field(None, description="The id of the project the agent belongs to.")
254
- template_id: Optional[str] = Field(None, description="The id of the template the agent belongs to.")
255
- base_template_id: Optional[str] = Field(None, description="The base template id of the agent.")
288
+ memory_variables: Optional[Dict[str, str]] = Field(
289
+ None,
290
+ description="Deprecated: Only relevant for creating agents from a template. Use the 'create agents from a template' endpoint instead.",
291
+ deprecated=True,
292
+ )
293
+ project_id: Optional[str] = Field(
294
+ None, description="Deprecated: No longer used. The id of the project the agent belongs to.", deprecated=True
295
+ )
296
+ template_id: Optional[str] = Field(
297
+ None, description="Deprecated: No longer used. The id of the template the agent belongs to.", deprecated=True
298
+ )
299
+ base_template_id: Optional[str] = Field(
300
+ None, description="Deprecated: No longer used. The base template id of the agent.", deprecated=True
301
+ )
256
302
  identity_ids: Optional[List[str]] = Field(None, description="The ids of the identities associated with this agent.")
257
303
  message_buffer_autoclear: bool = Field(
258
304
  False,
@@ -271,9 +317,14 @@ class CreateAgent(BaseModel, validate_assignment=True): #
271
317
  )
272
318
  hidden: Optional[bool] = Field(
273
319
  None,
274
- description="If set to True, the agent will be hidden.",
320
+ description="Deprecated: No longer used. If set to True, the agent will be hidden.",
321
+ deprecated=True,
322
+ )
323
+ parallel_tool_calls: Optional[bool] = Field(
324
+ False,
325
+ description="Deprecated: Use `model` field to configure parallel tool calls instead. If set to True, enables parallel tool calling.",
326
+ deprecated=True,
275
327
  )
276
- parallel_tool_calls: Optional[bool] = Field(False, description="If set to True, enables parallel tool calling. Defaults to False.")
277
328
 
278
329
  @field_validator("name")
279
330
  @classmethod
@@ -355,8 +406,6 @@ class UpdateAgent(BaseModel):
355
406
  tags: Optional[List[str]] = Field(None, description="The tags associated with the agent.")
356
407
  system: Optional[str] = Field(None, description="The system prompt used by the agent.")
357
408
  tool_rules: Optional[List[ToolRule]] = Field(None, description="The tool rules governing the agent.")
358
- llm_config: Optional[LLMConfig] = Field(None, description="The LLM configuration used by the agent.")
359
- embedding_config: Optional[EmbeddingConfig] = Field(None, description="The embedding configuration used by the agent.")
360
409
  message_ids: Optional[List[str]] = Field(None, description="The ids of the messages in the agent's in-context memory.")
361
410
  description: Optional[str] = Field(None, description="The description of the agent.")
362
411
  metadata: Optional[Dict] = Field(None, description="The metadata of the agent.")
@@ -370,22 +419,42 @@ class UpdateAgent(BaseModel):
370
419
  None,
371
420
  description="If set to True, the agent will not remember previous messages (though the agent will still retain state via core memory blocks and archival/recall memory). Not recommended unless you have an advanced use case.",
372
421
  )
373
- model: Optional[str] = Field(
422
+
423
+ # model configuration
424
+ model: Optional[str | ModelSettings] = Field(
374
425
  None,
375
- description="The LLM configuration handle used by the agent, specified in the format "
376
- "provider/model-name, as an alternative to specifying llm_config.",
426
+ description="The model used by the agent, specified either by a handle or an object. See the model schema for more information.",
377
427
  )
378
- embedding: Optional[str] = Field(
428
+ embedding: Optional[str | EmbeddingModelSettings] = Field(
379
429
  None, description="The embedding configuration handle used by the agent, specified in the format provider/model-name."
380
430
  )
381
431
  context_window_limit: Optional[int] = Field(None, description="The context window limit used by the agent.")
432
+ reasoning: Optional[bool] = Field(
433
+ None,
434
+ description="Deprecated: Use `model` field to configure reasoning instead. Whether to enable reasoning for this agent.",
435
+ deprecated=True,
436
+ )
437
+ llm_config: Optional[LLMConfig] = Field(
438
+ None, description="Deprecated: Use `model` field instead. The LLM configuration used by the agent.", deprecated=True
439
+ )
440
+ embedding_config: Optional[EmbeddingConfig] = Field(None, description="The embedding configuration used by the agent.")
441
+ parallel_tool_calls: Optional[bool] = Field(
442
+ False,
443
+ description="Deprecated: Use `model` field to configure parallel tool calls instead. If set to True, enables parallel tool calling.",
444
+ deprecated=True,
445
+ )
446
+ response_format: Optional[ResponseFormatUnion] = Field(
447
+ None,
448
+ description="Deprecated: Use `model` field to configure response format instead. The response format for the agent.",
449
+ deprecated=True,
450
+ )
382
451
  max_tokens: Optional[int] = Field(
383
452
  None,
384
- description="The maximum number of tokens to generate, including reasoning step. If not set, the model will use its default value.",
453
+ description="Deprecated: Use `model` field to configure max output tokens instead. The maximum number of tokens to generate, including reasoning step.",
454
+ deprecated=True,
385
455
  )
386
- reasoning: Optional[bool] = Field(None, description="Whether to enable reasoning for this agent.")
456
+
387
457
  enable_sleeptime: Optional[bool] = Field(None, description="If set to True, memory management will move to a background agent thread.")
388
- response_format: Optional[ResponseFormatUnion] = Field(None, description="The response format for the agent.")
389
458
  last_run_completion: Optional[datetime] = Field(None, description="The timestamp when the agent last completed a run.")
390
459
  last_run_duration_ms: Optional[int] = Field(None, description="The duration in milliseconds of the agent's last run.")
391
460
  timezone: Optional[str] = Field(None, description="The timezone of the agent (IANA format).")
@@ -401,7 +470,6 @@ class UpdateAgent(BaseModel):
401
470
  None,
402
471
  description="If set to True, the agent will be hidden.",
403
472
  )
404
- parallel_tool_calls: Optional[bool] = Field(False, description="If set to True, enables parallel tool calling. Defaults to False.")
405
473
 
406
474
  model_config = ConfigDict(extra="ignore") # Ignores extra fields
407
475
 
@@ -7,7 +7,7 @@ from pydantic import BaseModel, Field
7
7
  from letta.helpers.datetime_helpers import get_utc_time
8
8
  from letta.schemas.agent import AgentState, CreateAgent
9
9
  from letta.schemas.block import Block, CreateBlock
10
- from letta.schemas.enums import MessageRole
10
+ from letta.schemas.enums import MessageRole, PrimitiveType
11
11
  from letta.schemas.file import FileAgent, FileAgentBase, FileMetadata, FileMetadataBase
12
12
  from letta.schemas.group import Group, GroupCreate
13
13
  from letta.schemas.letta_message import ApprovalReturn
@@ -42,7 +42,7 @@ class ImportResult:
42
42
  class MessageSchema(MessageCreate):
43
43
  """Message with human-readable ID for agent file"""
44
44
 
45
- __id_prefix__ = "message"
45
+ __id_prefix__ = PrimitiveType.MESSAGE.value
46
46
  id: str = Field(..., description="Human-readable identifier for this message in the file")
47
47
 
48
48
  # Override the role field to accept all message roles, not just user/system/assistant
@@ -96,7 +96,7 @@ class MessageSchema(MessageCreate):
96
96
  class FileAgentSchema(FileAgentBase):
97
97
  """File-Agent relationship with human-readable ID for agent file"""
98
98
 
99
- __id_prefix__ = "file_agent"
99
+ __id_prefix__ = PrimitiveType.FILE_AGENT.value
100
100
  id: str = Field(..., description="Human-readable identifier for this file-agent relationship in the file")
101
101
 
102
102
  @classmethod
@@ -120,7 +120,7 @@ class FileAgentSchema(FileAgentBase):
120
120
  class AgentSchema(CreateAgent):
121
121
  """Agent with human-readable ID for agent file"""
122
122
 
123
- __id_prefix__ = "agent"
123
+ __id_prefix__ = PrimitiveType.AGENT.value
124
124
  id: str = Field(..., description="Human-readable identifier for this agent in the file")
125
125
  in_context_message_ids: List[str] = Field(
126
126
  default_factory=list, description="List of message IDs that are currently in the agent's context"
@@ -198,7 +198,7 @@ class AgentSchema(CreateAgent):
198
198
  class GroupSchema(GroupCreate):
199
199
  """Group with human-readable ID for agent file"""
200
200
 
201
- __id_prefix__ = "group"
201
+ __id_prefix__ = PrimitiveType.GROUP.value
202
202
  id: str = Field(..., description="Human-readable identifier for this group in the file")
203
203
 
204
204
  @classmethod
@@ -220,7 +220,7 @@ class GroupSchema(GroupCreate):
220
220
  class BlockSchema(CreateBlock):
221
221
  """Block with human-readable ID for agent file"""
222
222
 
223
- __id_prefix__ = "block"
223
+ __id_prefix__ = PrimitiveType.BLOCK.value
224
224
  id: str = Field(..., description="Human-readable identifier for this block in the file")
225
225
 
226
226
  @classmethod
@@ -246,7 +246,7 @@ class BlockSchema(CreateBlock):
246
246
  class FileSchema(FileMetadataBase):
247
247
  """File with human-readable ID for agent file"""
248
248
 
249
- __id_prefix__ = "file"
249
+ __id_prefix__ = PrimitiveType.FILE.value
250
250
  id: str = Field(..., description="Human-readable identifier for this file in the file")
251
251
 
252
252
  @classmethod
@@ -276,7 +276,7 @@ class FileSchema(FileMetadataBase):
276
276
  class SourceSchema(SourceCreate):
277
277
  """Source with human-readable ID for agent file"""
278
278
 
279
- __id_prefix__ = "source"
279
+ __id_prefix__ = PrimitiveType.SOURCE.value
280
280
  id: str = Field(..., description="Human-readable identifier for this source in the file")
281
281
 
282
282
  @classmethod
@@ -299,7 +299,7 @@ class SourceSchema(SourceCreate):
299
299
  class ToolSchema(Tool):
300
300
  """Tool with human-readable ID for agent file"""
301
301
 
302
- __id_prefix__ = "tool"
302
+ __id_prefix__ = PrimitiveType.TOOL.value
303
303
  id: str = Field(..., description="Human-readable identifier for this tool in the file")
304
304
 
305
305
  @classmethod
@@ -311,7 +311,7 @@ class ToolSchema(Tool):
311
311
  class MCPServerSchema(BaseModel):
312
312
  """MCP server schema for agent files with remapped ID."""
313
313
 
314
- __id_prefix__ = "mcp_server"
314
+ __id_prefix__ = PrimitiveType.MCP_SERVER.value
315
315
 
316
316
  id: str = Field(..., description="Human-readable MCP server ID")
317
317
  server_type: str
letta/schemas/block.py CHANGED
@@ -21,9 +21,9 @@ class BaseBlock(LettaBase, validate_assignment=True):
21
21
 
22
22
  project_id: Optional[str] = Field(None, description="The associated project id.")
23
23
  # template data (optional)
24
- template_name: Optional[str] = Field(None, description="Name of the block if it is a template.", alias="name")
24
+ template_name: Optional[str] = Field(None, description="Name of the block if it is a template.")
25
25
  is_template: bool = Field(False, description="Whether the block is a template (e.g. saved human/persona options).")
26
- template_id: Optional[str] = Field(None, description="The id of the template.", alias="name")
26
+ template_id: Optional[str] = Field(None, description="The id of the template.")
27
27
  base_template_id: Optional[str] = Field(None, description="The base template id of the block.")
28
28
  deployment_id: Optional[str] = Field(None, description="The id of the deployment.")
29
29
  entity_id: Optional[str] = Field(None, description="The id of the entity within the template.")
@@ -102,6 +102,25 @@ class Block(BaseBlock):
102
102
  last_updated_by_id: Optional[str] = Field(None, description="The id of the user that last updated this Block.")
103
103
 
104
104
 
105
+ class BlockResponse(Block):
106
+ id: str = Field(
107
+ ...,
108
+ description="The id of the block.",
109
+ )
110
+ template_name: Optional[str] = Field(
111
+ None, description="(Deprecated) The name of the block template (if it is a template).", deprecated=True
112
+ )
113
+ template_id: Optional[str] = Field(None, description="(Deprecated) The id of the template.", deprecated=True)
114
+ base_template_id: Optional[str] = Field(None, description="(Deprecated) The base template id of the block.", deprecated=True)
115
+ deployment_id: Optional[str] = Field(None, description="(Deprecated) The id of the deployment.", deprecated=True)
116
+ entity_id: Optional[str] = Field(None, description="(Deprecated) The id of the entity within the template.", deprecated=True)
117
+ preserve_on_migration: Optional[bool] = Field(
118
+ False, description="(Deprecated) Preserve the block on template migration.", deprecated=True
119
+ )
120
+ read_only: bool = Field(False, description="(Deprecated) Whether the agent has read-only access to the block.", deprecated=True)
121
+ hidden: Optional[bool] = Field(None, description="(Deprecated) If set to True, the block will be hidden.", deprecated=True)
122
+
123
+
105
124
  class FileBlock(Block):
106
125
  file_id: str = Field(..., description="Unique identifier of the file.")
107
126
  source_id: str = Field(..., description="Unique identifier of the source.")
@@ -149,7 +168,7 @@ class CreateBlock(BaseBlock):
149
168
  project_id: Optional[str] = Field(None, description="The associated project id.")
150
169
  # block templates
151
170
  is_template: bool = False
152
- template_name: Optional[str] = Field(None, description="Name of the block if it is a template.", alias="name")
171
+ template_name: Optional[str] = Field(None, description="Name of the block if it is a template.")
153
172
 
154
173
  @model_validator(mode="before")
155
174
  @classmethod
letta/schemas/enums.py CHANGED
@@ -26,6 +26,27 @@ class PrimitiveType(str, Enum):
26
26
  STEP = "step"
27
27
  IDENTITY = "identity"
28
28
 
29
+ # Infrastructure types
30
+ MCP_SERVER = "mcp_server"
31
+ MCP_OAUTH = "mcp-oauth"
32
+ FILE_AGENT = "file_agent"
33
+
34
+ # Configuration types
35
+ SANDBOX_ENV = "sandbox-env"
36
+ AGENT_ENV = "agent-env"
37
+
38
+ # Core entity types
39
+ USER = "user"
40
+ ORGANIZATION = "org"
41
+ TOOL_RULE = "tool_rule"
42
+
43
+ # Batch processing types
44
+ BATCH_ITEM = "batch_item"
45
+ BATCH_REQUEST = "batch_req"
46
+
47
+ # Telemetry types
48
+ PROVIDER_TRACE = "provider_trace"
49
+
29
50
 
30
51
  class ProviderType(str, Enum):
31
52
  anthropic = "anthropic"
@@ -2,6 +2,7 @@ from typing import Optional
2
2
 
3
3
  from pydantic import Field
4
4
 
5
+ from letta.schemas.enums import PrimitiveType
5
6
  from letta.schemas.letta_base import LettaBase, OrmMetadataBase
6
7
  from letta.schemas.secret import Secret
7
8
  from letta.settings import settings
@@ -52,7 +53,7 @@ class EnvironmentVariableUpdateBase(LettaBase):
52
53
 
53
54
  # Environment Variable
54
55
  class SandboxEnvironmentVariableBase(EnvironmentVariableBase):
55
- __id_prefix__ = "sandbox-env"
56
+ __id_prefix__ = PrimitiveType.SANDBOX_ENV.value
56
57
  sandbox_config_id: str = Field(..., description="The ID of the sandbox config this environment variable belongs to.")
57
58
 
58
59
 
@@ -70,7 +71,7 @@ class SandboxEnvironmentVariableUpdate(EnvironmentVariableUpdateBase):
70
71
 
71
72
  # Agent-Specific Environment Variable
72
73
  class AgentEnvironmentVariableBase(EnvironmentVariableBase):
73
- __id_prefix__ = "agent-env"
74
+ __id_prefix__ = PrimitiveType.AGENT_ENV.value
74
75
  agent_id: str = Field(..., description="The ID of the agent this environment variable belongs to.")
75
76
 
76
77
 
letta/schemas/group.py CHANGED
@@ -34,7 +34,7 @@ class Group(GroupBase):
34
34
  template_id: Optional[str] = Field(None, description="The id of the template.")
35
35
  base_template_id: Optional[str] = Field(None, description="The base template id.")
36
36
  deployment_id: Optional[str] = Field(None, description="The id of the deployment.")
37
- shared_block_ids: List[str] = Field([], description="")
37
+ shared_block_ids: List[str] = Field([], description="", deprecated=True)
38
38
  # Pattern fields
39
39
  manager_agent_id: Optional[str] = Field(None, description="")
40
40
  termination_token: Optional[str] = Field(None, description="")
@@ -174,7 +174,7 @@ class GroupCreate(BaseModel):
174
174
  description: str = Field(..., description="")
175
175
  manager_config: ManagerConfigUnion = Field(RoundRobinManager(), description="")
176
176
  project_id: Optional[str] = Field(None, description="The associated project id.")
177
- shared_block_ids: List[str] = Field([], description="")
177
+ shared_block_ids: List[str] = Field([], description="", deprecated=True)
178
178
  hidden: Optional[bool] = Field(
179
179
  None,
180
180
  description="If set to True, the group will be hidden.",
@@ -194,4 +194,4 @@ class GroupUpdate(BaseModel):
194
194
  description: Optional[str] = Field(None, description="")
195
195
  manager_config: Optional[ManagerConfigUpdateUnion] = Field(None, description="")
196
196
  project_id: Optional[str] = Field(None, description="The associated project id.")
197
- shared_block_ids: Optional[List[str]] = Field(None, description="")
197
+ shared_block_ids: Optional[List[str]] = Field(None, description="", deprecated=True)
@@ -4,11 +4,24 @@ import re
4
4
  from datetime import datetime
5
5
  from typing import List, Union
6
6
 
7
- from pydantic import BaseModel, Field
7
+ from pydantic import BaseModel, Field, RootModel
8
8
 
9
9
  from letta.helpers.json_helpers import json_dumps
10
10
  from letta.schemas.enums import JobStatus, MessageStreamStatus
11
- from letta.schemas.letta_message import LettaMessage, LettaMessageUnion
11
+ from letta.schemas.letta_message import (
12
+ ApprovalRequestMessage,
13
+ ApprovalResponseMessage,
14
+ AssistantMessage,
15
+ HiddenReasoningMessage,
16
+ LettaMessage,
17
+ LettaMessageUnion,
18
+ LettaPing,
19
+ ReasoningMessage,
20
+ SystemMessage,
21
+ ToolCallMessage,
22
+ ToolReturnMessage,
23
+ UserMessage,
24
+ )
12
25
  from letta.schemas.letta_stop_reason import LettaStopReason
13
26
  from letta.schemas.message import Message
14
27
  from letta.schemas.usage import LettaUsageStatistics
@@ -170,8 +183,27 @@ class LettaResponse(BaseModel):
170
183
  return html_output
171
184
 
172
185
 
173
- # The streaming response is either [DONE], [DONE_STEP], [DONE], an error, or a LettaMessage
174
- LettaStreamingResponse = Union[LettaMessage, MessageStreamStatus, LettaStopReason, LettaUsageStatistics]
186
+ # The streaming response can be any of the individual message types, plus metadata types
187
+ class LettaStreamingResponse(RootModel):
188
+ """
189
+ Streaming response type for Server-Sent Events (SSE) endpoints.
190
+ Each event in the stream will be one of these types.
191
+ """
192
+
193
+ root: Union[
194
+ SystemMessage,
195
+ UserMessage,
196
+ ReasoningMessage,
197
+ HiddenReasoningMessage,
198
+ ToolCallMessage,
199
+ ToolReturnMessage,
200
+ AssistantMessage,
201
+ ApprovalRequestMessage,
202
+ ApprovalResponseMessage,
203
+ LettaPing,
204
+ LettaStopReason,
205
+ LettaUsageStatistics,
206
+ ] = Field(..., discriminator="message_type")
175
207
 
176
208
 
177
209
  class LettaBatchResponse(BaseModel):
@@ -5,7 +5,7 @@ from anthropic.types.beta.messages import BetaMessageBatch, BetaMessageBatchIndi
5
5
  from pydantic import BaseModel, Field
6
6
 
7
7
  from letta.helpers import ToolRulesSolver
8
- from letta.schemas.enums import AgentStepStatus, JobStatus, ProviderType
8
+ from letta.schemas.enums import AgentStepStatus, JobStatus, PrimitiveType, ProviderType
9
9
  from letta.schemas.letta_base import OrmMetadataBase
10
10
  from letta.schemas.llm_config import LLMConfig
11
11
 
@@ -16,7 +16,7 @@ class AgentStepState(BaseModel):
16
16
 
17
17
 
18
18
  class LLMBatchItemBase(OrmMetadataBase, validate_assignment=True):
19
- __id_prefix__ = "batch_item"
19
+ __id_prefix__ = PrimitiveType.BATCH_ITEM.value
20
20
 
21
21
 
22
22
  class LLMBatchItem(LLMBatchItemBase, validate_assignment=True):
@@ -47,7 +47,7 @@ class LLMBatchJob(OrmMetadataBase, validate_assignment=True):
47
47
  Each job corresponds to one API call that sends multiple messages to the LLM provider, and aggregates responses across all agent submissions.
48
48
  """
49
49
 
50
- __id_prefix__ = "batch_req"
50
+ __id_prefix__ = PrimitiveType.BATCH_REQUEST.value
51
51
 
52
52
  id: Optional[str] = Field(None, description="The id of the batch job. Assigned by the database.")
53
53
  status: JobStatus = Field(..., description="The current status of the batch (e.g., created, in_progress, done).")