Files
letta-server/letta/schemas/user.py
Kian Jones a206f7f345 feat: add ID format validation to agent and user schemas (#9151)
* feat: add ID format validation to agent and user schemas

Reuse existing validator types (ToolId, SourceId, BlockId, MessageId,
IdentityId, UserId) from letta.validators to enforce ID format validation
at the schema level. This ensures malformed IDs are rejected with a 422
validation error instead of causing 500 database errors.

Changes:
- CreateAgent: validate tool_ids, source_ids, folder_ids, block_ids, identity_ids
- UpdateAgent: validate tool_ids, source_ids, folder_ids, block_ids, message_ids, identity_ids
- UserUpdate: validate id

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* chore: regenerate API spec and SDK

* fix: override ID validation in AgentSchema for agent file portability

AgentSchema extends CreateAgent but needs to allow arbitrary short IDs
(e.g., tool-0, block-0) for portable agent files. Override the validated
ID fields to use plain List[str] instead of the validated types.

Also fix test_agent.af to use proper UUID-format IDs.

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* chore: regenerate API spec and SDK

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* fix: revert test_agent.af - short IDs are valid for agent files

🤖 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>

* fix openapi schema

---------

Co-authored-by: Letta <noreply@letta.com>
2026-02-24 10:52:06 -08:00

36 lines
1.4 KiB
Python

from datetime import datetime
from typing import Optional
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):
__id_prefix__ = PrimitiveType.USER.value
class User(UserBase):
"""Representation of a user."""
id: str = UserBase.generate_id_field()
organization_id: Optional[str] = Field(DEFAULT_ORG_ID, description="The organization id of the user")
name: str = Field(..., description="The name of the user.")
created_at: Optional[datetime] = Field(default_factory=datetime.utcnow, description="The creation date of the user.")
updated_at: Optional[datetime] = Field(default_factory=datetime.utcnow, description="The update date of the user.")
is_deleted: bool = Field(False, description="Whether this user is deleted or not.")
class UserCreate(UserBase):
name: str = Field(..., description="The name of the user.")
organization_id: str = Field(..., description="The organization id of the user.")
class UserUpdate(UserBase):
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.")