diff --git a/fern/openapi.json b/fern/openapi.json index dace1b4a..18c2b474 100644 --- a/fern/openapi.json +++ b/fern/openapi.json @@ -30546,7 +30546,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 41, + "minLength": 41, + "pattern": "^tool-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the tool in the format 'tool-'", + "examples": ["tool-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -30561,7 +30566,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 43, + "minLength": 43, + "pattern": "^source-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the source in the format 'source-'", + "examples": ["source-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -30577,7 +30587,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 43, + "minLength": 43, + "pattern": "^source-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the source in the format 'source-'", + "examples": ["source-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -30592,7 +30607,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 42, + "minLength": 42, + "pattern": "^block-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the block in the format 'block-'", + "examples": ["block-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -31093,7 +31113,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 45, + "minLength": 45, + "pattern": "^identity-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the identity in the format 'identity-'", + "examples": ["identity-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -34958,7 +34983,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 41, + "minLength": 41, + "pattern": "^tool-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the tool in the format 'tool-'", + "examples": ["tool-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -34973,7 +35003,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 43, + "minLength": 43, + "pattern": "^source-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the source in the format 'source-'", + "examples": ["source-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -34989,7 +35024,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 43, + "minLength": 43, + "pattern": "^source-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the source in the format 'source-'", + "examples": ["source-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -35004,7 +35044,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 42, + "minLength": 42, + "pattern": "^block-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the block in the format 'block-'", + "examples": ["block-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -35489,7 +35534,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 45, + "minLength": 45, + "pattern": "^identity-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the identity in the format 'identity-'", + "examples": ["identity-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -44947,7 +44997,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 41, + "minLength": 41, + "pattern": "^tool-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the tool in the format 'tool-'", + "examples": ["tool-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -44962,7 +45017,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 43, + "minLength": 43, + "pattern": "^source-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the source in the format 'source-'", + "examples": ["source-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -44978,7 +45038,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 43, + "minLength": 43, + "pattern": "^source-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the source in the format 'source-'", + "examples": ["source-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -44993,7 +45058,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 42, + "minLength": 42, + "pattern": "^block-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the block in the format 'block-'", + "examples": ["block-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -45092,7 +45162,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 44, + "minLength": 44, + "pattern": "^message-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the message in the format 'message-'", + "examples": ["message-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -45198,7 +45273,12 @@ "anyOf": [ { "items": { - "type": "string" + "type": "string", + "maxLength": 45, + "minLength": 45, + "pattern": "^identity-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", + "description": "The ID of the identity in the format 'identity-'", + "examples": ["identity-123e4567-e89b-42d3-8456-426614174000"] }, "type": "array" }, @@ -46051,8 +46131,12 @@ "properties": { "id": { "type": "string", + "maxLength": 41, + "minLength": 41, + "pattern": "^user-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", "title": "Id", - "description": "The id of the user to update." + "description": "The id of the user to update.", + "examples": ["user-123e4567-e89b-42d3-8456-426614174000"] }, "name": { "anyOf": [ @@ -46468,8 +46552,7 @@ } ], "title": "Source Ids", - "description": "Deprecated: Use `folder_ids` field instead. The ids of the sources used by the agent.", - "deprecated": true + "description": "The ids of the sources used by the agent." }, "folder_ids": { "anyOf": [ diff --git a/letta/schemas/agent.py b/letta/schemas/agent.py index 0e40f1fe..6aa43f88 100644 --- a/letta/schemas/agent.py +++ b/letta/schemas/agent.py @@ -32,6 +32,7 @@ from letta.schemas.tool import Tool from letta.schemas.tool_rule import ToolRule from letta.services.summarizer.summarizer_config import CompactionSettings from letta.utils import calculate_file_defaults_based_on_context_window, create_random_username +from letta.validators import BlockId, IdentityId, MessageId, SourceId, ToolId # TODO: Remove this upon next OSS release, there's a duplicate AgentType in enums @@ -215,12 +216,12 @@ class CreateAgent(BaseModel, validate_assignment=True): # ) # TODO: This is a legacy field and should be removed ASAP to force `tool_ids` usage tools: Optional[List[str]] = Field(None, description="The tools used by the agent.") - tool_ids: Optional[List[str]] = Field(None, description="The ids of the tools used by the agent.") - source_ids: Optional[List[str]] = Field( + tool_ids: Optional[List[ToolId]] = Field(None, description="The ids of the tools used by the agent.") + source_ids: Optional[List[SourceId]] = Field( None, description="Deprecated: Use `folder_ids` field instead. The ids of the sources used by the agent.", deprecated=True ) - folder_ids: Optional[List[str]] = Field(None, description="The ids of the folders used by the agent.") - block_ids: Optional[List[str]] = Field(None, description="The ids of the blocks used by the agent.") + folder_ids: Optional[List[SourceId]] = Field(None, description="The ids of the folders used by the agent.") + block_ids: Optional[List[BlockId]] = Field(None, description="The ids of the blocks used by the agent.") tool_rules: Optional[List[ToolRule]] = Field(None, description="The tool rules governing the agent.") tags: Optional[List[str]] = Field(None, description="The tags associated with the agent.") system: Optional[str] = Field(None, description="The system prompt used by the agent.") @@ -311,7 +312,7 @@ class CreateAgent(BaseModel, validate_assignment=True): # base_template_id: Optional[str] = Field( None, description="Deprecated: No longer used. The base template id of the agent.", deprecated=True ) - identity_ids: Optional[List[str]] = Field(None, description="The ids of the identities associated with this agent.") + identity_ids: Optional[List[IdentityId]] = Field(None, description="The ids of the identities associated with this agent.") message_buffer_autoclear: bool = Field( False, 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.", @@ -444,16 +445,16 @@ class InternalTemplateAgentCreate(CreateAgent): class UpdateAgent(BaseModel): name: Optional[str] = Field(None, description="The name of the agent.") - tool_ids: Optional[List[str]] = Field(None, description="The ids of the tools used by the agent.") - source_ids: Optional[List[str]] = Field( + tool_ids: Optional[List[ToolId]] = Field(None, description="The ids of the tools used by the agent.") + source_ids: Optional[List[SourceId]] = Field( None, description="Deprecated: Use `folder_ids` field instead. The ids of the sources used by the agent.", deprecated=True ) - folder_ids: Optional[List[str]] = Field(None, description="The ids of the folders used by the agent.") - block_ids: Optional[List[str]] = Field(None, description="The ids of the blocks used by the agent.") + folder_ids: Optional[List[SourceId]] = Field(None, description="The ids of the folders used by the agent.") + block_ids: Optional[List[BlockId]] = Field(None, description="The ids of the blocks used by the agent.") tags: Optional[List[str]] = Field(None, description="The tags associated with the agent.") system: Optional[str] = Field(None, description="The system prompt used by the agent.") tool_rules: Optional[List[ToolRule]] = Field(None, description="The tool rules governing the agent.") - message_ids: Optional[List[str]] = Field(None, description="The ids of the messages in the agent's in-context memory.") + message_ids: Optional[List[MessageId]] = Field(None, description="The ids of the messages in the agent's in-context memory.") description: Optional[str] = Field(None, description="The description of the agent.") metadata: Optional[Dict] = Field(None, description="The metadata of the agent.") tool_exec_environment_variables: Optional[Dict[str, str]] = Field(None, description="Deprecated: use `secrets` field instead") @@ -461,7 +462,7 @@ class UpdateAgent(BaseModel): project_id: Optional[str] = Field(None, description="The id of the project the agent belongs to.") template_id: Optional[str] = Field(None, description="The id of the template the agent belongs to.") base_template_id: Optional[str] = Field(None, description="The base template id of the agent.") - identity_ids: Optional[List[str]] = Field(None, description="The ids of the identities associated with this agent.") + identity_ids: Optional[List[IdentityId]] = Field(None, description="The ids of the identities associated with this agent.") message_buffer_autoclear: Optional[bool] = Field( None, 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.", diff --git a/letta/schemas/agent_file.py b/letta/schemas/agent_file.py index 2e35f30b..c2e8a0a8 100644 --- a/letta/schemas/agent_file.py +++ b/letta/schemas/agent_file.py @@ -135,6 +135,12 @@ class AgentSchema(CreateAgent): files_agents: List[FileAgentSchema] = Field(default_factory=list, description="List of file-agent relationships for this agent") group_ids: List[str] = Field(default_factory=list, description="List of groups that the agent manages") + tool_ids: Optional[List[str]] = Field(None, description="The ids of the tools used by the agent.") + source_ids: Optional[List[str]] = Field(None, description="The ids of the sources used by the agent.") + folder_ids: Optional[List[str]] = Field(None, description="The ids of the folders used by the agent.") + block_ids: Optional[List[str]] = Field(None, description="The ids of the blocks used by the agent.") + identity_ids: Optional[List[str]] = Field(None, description="The ids of the identities associated with this agent.") + @classmethod async def from_agent_state( cls, agent_state: AgentState, message_manager: MessageManager, files_agents: List[FileAgent], actor: User diff --git a/letta/schemas/user.py b/letta/schemas/user.py index 45aa871e..283d75b6 100644 --- a/letta/schemas/user.py +++ b/letta/schemas/user.py @@ -6,6 +6,7 @@ from pydantic import Field from letta.constants import DEFAULT_ORG_ID from letta.schemas.enums import PrimitiveType from letta.schemas.letta_base import LettaBase +from letta.validators import UserId class UserBase(LettaBase): @@ -29,6 +30,6 @@ class UserCreate(UserBase): class UserUpdate(UserBase): - id: str = Field(..., description="The id of the user to update.") + id: UserId = Field(..., description="The id of the user to update.") name: Optional[str] = Field(None, description="The new name of the user.") organization_id: Optional[str] = Field(None, description="The new organization id of the user.") diff --git a/tests/managers/test_agent_manager.py b/tests/managers/test_agent_manager.py index 4a9e8598..3849fb28 100644 --- a/tests/managers/test_agent_manager.py +++ b/tests/managers/test_agent_manager.py @@ -691,7 +691,7 @@ async def test_update_agent(server: SyncServer, comprehensive_test_agent_fixture system="train system", llm_config=LLMConfig.default_config("gpt-4o-mini"), embedding_config=EmbeddingConfig.default_config(model_name="letta"), - message_ids=["10", "20"], + message_ids=[f"message-{uuid.uuid4()}", f"message-{uuid.uuid4()}"], metadata={"train_key": "train_value"}, tool_exec_environment_variables={"test_env_var_key_a": "a", "new_tool_exec_key": "n"}, message_buffer_autoclear=False,