* feat: add ID format validation to group schemas Add ID format validation to GroupCreate, GroupUpdate, and manager config schemas using existing validator types from letta.validators. Changes: - GroupCreate/GroupUpdate: agent_ids → List[AgentId], shared_block_ids → List[BlockId] - SupervisorManager, DynamicManager, SleeptimeManager, VoiceSleeptimeManager: manager_agent_id → AgentId - Update variants: manager_agent_id → Optional[AgentId] This ensures malformed IDs are rejected with 422 validation errors instead of causing 500 database errors. 🤖 Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta <noreply@letta.com> * chore: regenerate API spec and SDK --------- Co-authored-by: Letta <noreply@letta.com>
199 lines
8.7 KiB
Python
199 lines
8.7 KiB
Python
from enum import Enum
|
|
from typing import Annotated, List, Literal, Optional, Union
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
from letta.schemas.enums import PrimitiveType
|
|
from letta.schemas.letta_base import LettaBase
|
|
from letta.validators import AgentId, BlockId
|
|
|
|
|
|
class ManagerType(str, Enum):
|
|
round_robin = "round_robin"
|
|
supervisor = "supervisor"
|
|
dynamic = "dynamic"
|
|
sleeptime = "sleeptime"
|
|
voice_sleeptime = "voice_sleeptime"
|
|
swarm = "swarm"
|
|
|
|
|
|
class ManagerConfig(BaseModel):
|
|
manager_type: ManagerType = Field(..., description="")
|
|
|
|
|
|
class GroupBase(LettaBase):
|
|
__id_prefix__ = PrimitiveType.GROUP.value
|
|
|
|
|
|
class Group(GroupBase):
|
|
id: str = Field(..., description="The id of the group. Assigned by the database.")
|
|
manager_type: ManagerType = Field(..., description="")
|
|
agent_ids: List[str] = Field(..., description="")
|
|
description: str = Field(..., description="")
|
|
project_id: Optional[str] = Field(None, description="The associated project id.")
|
|
# Template fields
|
|
template_id: Optional[str] = Field(None, description="The id of the template.")
|
|
base_template_id: Optional[str] = Field(None, description="The base template id.")
|
|
deployment_id: Optional[str] = Field(None, description="The id of the deployment.")
|
|
shared_block_ids: List[str] = Field([], description="", deprecated=True)
|
|
# Pattern fields
|
|
manager_agent_id: Optional[str] = Field(None, description="")
|
|
termination_token: Optional[str] = Field(None, description="")
|
|
max_turns: Optional[int] = Field(None, description="")
|
|
sleeptime_agent_frequency: Optional[int] = Field(None, description="")
|
|
turns_counter: Optional[int] = Field(None, description="")
|
|
last_processed_message_id: Optional[str] = Field(None, description="")
|
|
max_message_buffer_length: Optional[int] = Field(
|
|
None,
|
|
description="The desired maximum length of messages in the context window of the convo agent. This is a best effort, and may be off slightly due to user/assistant interleaving.",
|
|
)
|
|
min_message_buffer_length: Optional[int] = Field(
|
|
None,
|
|
description="The desired minimum length of messages in the context window of the convo agent. This is a best effort, and may be off-by-one due to user/assistant interleaving.",
|
|
)
|
|
hidden: Optional[bool] = Field(
|
|
None,
|
|
description="If set to True, the group will be hidden.",
|
|
)
|
|
|
|
@property
|
|
def manager_config(self) -> ManagerConfig:
|
|
match self.manager_type:
|
|
case ManagerType.round_robin:
|
|
return RoundRobinManager(max_turns=self.max_turns)
|
|
case ManagerType.supervisor:
|
|
return SupervisorManager(manager_agent_id=self.manager_agent_id)
|
|
case ManagerType.dynamic:
|
|
return DynamicManager(
|
|
manager_agent_id=self.manager_agent_id,
|
|
termination_token=self.termination_token,
|
|
max_turns=self.max_turns,
|
|
)
|
|
case ManagerType.sleeptime:
|
|
return SleeptimeManager(
|
|
manager_agent_id=self.manager_agent_id,
|
|
sleeptime_agent_frequency=self.sleeptime_agent_frequency,
|
|
)
|
|
case ManagerType.voice_sleeptime:
|
|
return VoiceSleeptimeManager(
|
|
manager_agent_id=self.manager_agent_id,
|
|
max_message_buffer_length=self.max_message_buffer_length,
|
|
min_message_buffer_length=self.min_message_buffer_length,
|
|
)
|
|
|
|
|
|
class RoundRobinManager(ManagerConfig):
|
|
manager_type: Literal[ManagerType.round_robin] = Field(ManagerType.round_robin, description="")
|
|
max_turns: Optional[int] = Field(None, description="")
|
|
|
|
|
|
class RoundRobinManagerUpdate(ManagerConfig):
|
|
manager_type: Literal[ManagerType.round_robin] = Field(ManagerType.round_robin, description="")
|
|
max_turns: Optional[int] = Field(None, description="")
|
|
|
|
|
|
class SupervisorManager(ManagerConfig):
|
|
manager_type: Literal[ManagerType.supervisor] = Field(ManagerType.supervisor, description="")
|
|
manager_agent_id: AgentId = Field(..., description="")
|
|
|
|
|
|
class SupervisorManagerUpdate(ManagerConfig):
|
|
manager_type: Literal[ManagerType.supervisor] = Field(ManagerType.supervisor, description="")
|
|
manager_agent_id: Optional[AgentId] = Field(..., description="")
|
|
|
|
|
|
class DynamicManager(ManagerConfig):
|
|
manager_type: Literal[ManagerType.dynamic] = Field(ManagerType.dynamic, description="")
|
|
manager_agent_id: AgentId = Field(..., description="")
|
|
termination_token: Optional[str] = Field("DONE!", description="")
|
|
max_turns: Optional[int] = Field(None, description="")
|
|
|
|
|
|
class DynamicManagerUpdate(ManagerConfig):
|
|
manager_type: Literal[ManagerType.dynamic] = Field(ManagerType.dynamic, description="")
|
|
manager_agent_id: Optional[AgentId] = Field(None, description="")
|
|
termination_token: Optional[str] = Field(None, description="")
|
|
max_turns: Optional[int] = Field(None, description="")
|
|
|
|
|
|
class SleeptimeManager(ManagerConfig):
|
|
manager_type: Literal[ManagerType.sleeptime] = Field(ManagerType.sleeptime, description="")
|
|
manager_agent_id: AgentId = Field(..., description="")
|
|
sleeptime_agent_frequency: Optional[int] = Field(None, description="")
|
|
|
|
|
|
class SleeptimeManagerUpdate(ManagerConfig):
|
|
manager_type: Literal[ManagerType.sleeptime] = Field(ManagerType.sleeptime, description="")
|
|
manager_agent_id: Optional[AgentId] = Field(None, description="")
|
|
sleeptime_agent_frequency: Optional[int] = Field(None, description="")
|
|
|
|
|
|
class VoiceSleeptimeManager(ManagerConfig):
|
|
manager_type: Literal[ManagerType.voice_sleeptime] = Field(ManagerType.voice_sleeptime, description="")
|
|
manager_agent_id: AgentId = Field(..., description="")
|
|
max_message_buffer_length: Optional[int] = Field(
|
|
None,
|
|
description="The desired maximum length of messages in the context window of the convo agent. This is a best effort, and may be off slightly due to user/assistant interleaving.",
|
|
)
|
|
min_message_buffer_length: Optional[int] = Field(
|
|
None,
|
|
description="The desired minimum length of messages in the context window of the convo agent. This is a best effort, and may be off-by-one due to user/assistant interleaving.",
|
|
)
|
|
|
|
|
|
class VoiceSleeptimeManagerUpdate(ManagerConfig):
|
|
manager_type: Literal[ManagerType.voice_sleeptime] = Field(ManagerType.voice_sleeptime, description="")
|
|
manager_agent_id: Optional[AgentId] = Field(None, description="")
|
|
max_message_buffer_length: Optional[int] = Field(
|
|
None,
|
|
description="The desired maximum length of messages in the context window of the convo agent. This is a best effort, and may be off slightly due to user/assistant interleaving.",
|
|
)
|
|
min_message_buffer_length: Optional[int] = Field(
|
|
None,
|
|
description="The desired minimum length of messages in the context window of the convo agent. This is a best effort, and may be off-by-one due to user/assistant interleaving.",
|
|
)
|
|
|
|
|
|
# class SwarmGroup(ManagerConfig):
|
|
# manager_type: Literal[ManagerType.swarm] = Field(ManagerType.swarm, description="")
|
|
|
|
|
|
ManagerConfigUnion = Annotated[
|
|
Union[RoundRobinManager, SupervisorManager, DynamicManager, SleeptimeManager, VoiceSleeptimeManager],
|
|
Field(discriminator="manager_type"),
|
|
]
|
|
|
|
|
|
ManagerConfigUpdateUnion = Annotated[
|
|
Union[RoundRobinManagerUpdate, SupervisorManagerUpdate, DynamicManagerUpdate, SleeptimeManagerUpdate, VoiceSleeptimeManagerUpdate],
|
|
Field(discriminator="manager_type"),
|
|
]
|
|
|
|
|
|
class GroupCreate(BaseModel):
|
|
agent_ids: List[AgentId] = Field(..., description="")
|
|
description: str = Field(..., description="")
|
|
manager_config: ManagerConfigUnion = Field(RoundRobinManager(), description="")
|
|
project_id: Optional[str] = Field(None, description="The associated project id.")
|
|
shared_block_ids: List[BlockId] = Field([], description="", deprecated=True)
|
|
hidden: Optional[bool] = Field(
|
|
None,
|
|
description="If set to True, the group will be hidden.",
|
|
)
|
|
|
|
|
|
class InternalTemplateGroupCreate(GroupCreate):
|
|
"""Used for Letta Cloud"""
|
|
|
|
base_template_id: str = Field(..., description="The id of the base template.")
|
|
template_id: str = Field(..., description="The id of the template.")
|
|
deployment_id: str = Field(..., description="The id of the deployment.")
|
|
|
|
|
|
class GroupUpdate(BaseModel):
|
|
agent_ids: Optional[List[AgentId]] = Field(None, description="")
|
|
description: Optional[str] = Field(None, description="")
|
|
manager_config: Optional[ManagerConfigUpdateUnion] = Field(None, description="")
|
|
project_id: Optional[str] = Field(None, description="The associated project id.")
|
|
shared_block_ids: Optional[List[BlockId]] = Field(None, description="", deprecated=True)
|