feat: make new message create type field optional [LET-4116] (#4319)

feat: make new message create type field optional
This commit is contained in:
cthomas
2025-08-29 15:22:34 -07:00
committed by GitHub
parent 83721679c6
commit 697be58b78
3 changed files with 14 additions and 26 deletions

View File

@@ -39,11 +39,18 @@ class LettaRequest(BaseModel):
@field_validator("messages", mode="before")
@classmethod
def add_default_type_to_messages(cls, v):
"""Add default 'message' type for backwards compatibility with older versions of SDK clients that don't send it"""
"""Handle union without discriminator - default to 'message' type if not specified"""
if isinstance(v, list):
for item in v:
if isinstance(item, dict) and "type" not in item:
item["type"] = "message"
if isinstance(item, dict):
# If type is not present, determine based on fields
if "type" not in item:
# If it has approval-specific fields, it's an approval
if "approval_request_id" in item or "approve" in item:
item["type"] = "approval"
else:
# Default to message
item["type"] = "message"
return v

View File

@@ -78,7 +78,9 @@ class MessageCreateBase(BaseModel):
class MessageCreate(MessageCreateBase):
"""Request to create a message"""
type: Literal[MessageCreateType.message] = Field(default=MessageCreateType.message, description="The message type to be created.")
type: Optional[Literal[MessageCreateType.message]] = Field(
default=MessageCreateType.message, description="The message type to be created."
)
# In the simplified format, only allow simple roles
role: Literal[
MessageRole.user,
@@ -113,26 +115,7 @@ class ApprovalCreate(MessageCreateBase):
reason: Optional[str] = Field(None, description="An optional explanation for the provided approval status")
MessageCreateUnion = Annotated[
Union[MessageCreate, ApprovalCreate],
Field(discriminator="type"),
]
def create_message_create_union_schema():
return {
"oneOf": [
{"$ref": "#/components/schemas/MessageCreate"},
{"$ref": "#/components/schemas/ApprovalCreate"},
],
"discriminator": {
"propertyName": "type",
"mapping": {
"message": "#/components/schemas/MessageCreate",
"approval": "#/components/schemas/ApprovalCreate",
},
},
}
MessageCreateUnion = Union[MessageCreate, ApprovalCreate]
class MessageUpdate(BaseModel):

View File

@@ -29,7 +29,6 @@ from letta.schemas.letta_message_content import (
create_letta_user_message_content_union_schema,
)
from letta.schemas.letta_ping import create_letta_ping_schema
from letta.schemas.message import create_message_create_union_schema
from letta.server.constants import REST_DEFAULT_PORT
from letta.server.db import db_registry
@@ -66,7 +65,6 @@ def generate_openapi_schema(app: FastAPI):
letta_docs["paths"] = {k: v for k, v in letta_docs["paths"].items() if not k.startswith("/openai")}
letta_docs["info"]["title"] = "Letta API"
letta_docs["components"]["schemas"]["LettaMessageUnion"] = create_letta_message_union_schema()
letta_docs["components"]["schemas"]["MessageCreateUnion"] = create_message_create_union_schema()
letta_docs["components"]["schemas"]["LettaMessageContentUnion"] = create_letta_message_content_union_schema()
letta_docs["components"]["schemas"]["LettaAssistantMessageContentUnion"] = create_letta_assistant_message_content_union_schema()
letta_docs["components"]["schemas"]["LettaUserMessageContentUnion"] = create_letta_user_message_content_union_schema()