MemGPT/letta/schemas/letta_message_content.py
cthomas 6495180ee2
chore: bump version 0.7.2 (#2584)
Co-authored-by: Matthew Zhou <mattzh1314@gmail.com>
Co-authored-by: Charles Packer <packercharles@gmail.com>
2025-04-23 15:23:09 -07:00

194 lines
6.4 KiB
Python

from enum import Enum
from typing import Annotated, Literal, Optional, Union
from pydantic import BaseModel, Field
class MessageContentType(str, Enum):
text = "text"
tool_call = "tool_call"
tool_return = "tool_return"
reasoning = "reasoning"
redacted_reasoning = "redacted_reasoning"
omitted_reasoning = "omitted_reasoning"
class MessageContent(BaseModel):
type: MessageContentType = Field(..., description="The type of the message.")
# -------------------------------
# User Content Types
# -------------------------------
class TextContent(MessageContent):
type: Literal[MessageContentType.text] = Field(MessageContentType.text, description="The type of the message.")
text: str = Field(..., description="The text content of the message.")
LettaUserMessageContentUnion = Annotated[
Union[TextContent],
Field(discriminator="type"),
]
def create_letta_user_message_content_union_schema():
return {
"oneOf": [
{"$ref": "#/components/schemas/TextContent"},
],
"discriminator": {
"propertyName": "type",
"mapping": {
"text": "#/components/schemas/TextContent",
},
},
}
def get_letta_user_message_content_union_str_json_schema():
return {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/components/schemas/LettaUserMessageContentUnion",
},
},
{"type": "string"},
],
}
# -------------------------------
# Assistant Content Types
# -------------------------------
LettaAssistantMessageContentUnion = Annotated[
Union[TextContent],
Field(discriminator="type"),
]
def create_letta_assistant_message_content_union_schema():
return {
"oneOf": [
{"$ref": "#/components/schemas/TextContent"},
],
"discriminator": {
"propertyName": "type",
"mapping": {
"text": "#/components/schemas/TextContent",
},
},
}
def get_letta_assistant_message_content_union_str_json_schema():
return {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/components/schemas/LettaAssistantMessageContentUnion",
},
},
{"type": "string"},
],
}
# -------------------------------
# Intermediate Step Content Types
# -------------------------------
class ToolCallContent(MessageContent):
type: Literal[MessageContentType.tool_call] = Field(
MessageContentType.tool_call, description="Indicates this content represents a tool call event."
)
id: str = Field(..., description="A unique identifier for this specific tool call instance.")
name: str = Field(..., description="The name of the tool being called.")
input: dict = Field(
..., description="The parameters being passed to the tool, structured as a dictionary of parameter names to values."
)
class ToolReturnContent(MessageContent):
type: Literal[MessageContentType.tool_return] = Field(
MessageContentType.tool_return, description="Indicates this content represents a tool return event."
)
tool_call_id: str = Field(..., description="References the ID of the ToolCallContent that initiated this tool call.")
content: str = Field(..., description="The content returned by the tool execution.")
is_error: bool = Field(..., description="Indicates whether the tool execution resulted in an error.")
class ReasoningContent(MessageContent):
type: Literal[MessageContentType.reasoning] = Field(
MessageContentType.reasoning, description="Indicates this is a reasoning/intermediate step."
)
is_native: bool = Field(..., description="Whether the reasoning content was generated by a reasoner model that processed this step.")
reasoning: str = Field(..., description="The intermediate reasoning or thought process content.")
signature: Optional[str] = Field(None, description="A unique identifier for this reasoning step.")
class RedactedReasoningContent(MessageContent):
type: Literal[MessageContentType.redacted_reasoning] = Field(
MessageContentType.redacted_reasoning, description="Indicates this is a redacted thinking step."
)
data: str = Field(..., description="The redacted or filtered intermediate reasoning content.")
class OmittedReasoningContent(MessageContent):
type: Literal[MessageContentType.omitted_reasoning] = Field(
MessageContentType.omitted_reasoning, description="Indicates this is an omitted reasoning step."
)
# NOTE: dropping because we don't track this kind of information for the other reasoning types
# tokens: int = Field(..., description="The reasoning token count for intermediate reasoning content.")
LettaMessageContentUnion = Annotated[
Union[TextContent, ToolCallContent, ToolReturnContent, ReasoningContent, RedactedReasoningContent, OmittedReasoningContent],
Field(discriminator="type"),
]
def create_letta_message_content_union_schema():
return {
"oneOf": [
{"$ref": "#/components/schemas/TextContent"},
{"$ref": "#/components/schemas/ToolCallContent"},
{"$ref": "#/components/schemas/ToolReturnContent"},
{"$ref": "#/components/schemas/ReasoningContent"},
{"$ref": "#/components/schemas/RedactedReasoningContent"},
{"$ref": "#/components/schemas/OmittedReasoningContent"},
],
"discriminator": {
"propertyName": "type",
"mapping": {
"text": "#/components/schemas/TextContent",
"tool_call": "#/components/schemas/ToolCallContent",
"tool_return": "#/components/schemas/ToolCallContent",
"reasoning": "#/components/schemas/ReasoningContent",
"redacted_reasoning": "#/components/schemas/RedactedReasoningContent",
"omitted_reasoning": "#/components/schemas/OmittedReasoningContent",
},
},
}
def get_letta_message_content_union_str_json_schema():
return {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/components/schemas/LettaMessageContentUnion",
},
},
{"type": "string"},
],
}