fix: fix pywright lint errors caused by bad use of pydantic (#3170)
This commit is contained in:
@@ -97,7 +97,7 @@ class LettaBase(BaseModel):
|
||||
|
||||
class OrmMetadataBase(LettaBase):
|
||||
# metadata fields
|
||||
created_by_id: Optional[str] = Field(None, description="The id of the user that made this object.")
|
||||
last_updated_by_id: Optional[str] = Field(None, description="The id of the user that made this object.")
|
||||
created_at: Optional[datetime] = Field(None, description="The timestamp when the object was created.")
|
||||
updated_at: Optional[datetime] = Field(None, description="The timestamp when the object was last updated.")
|
||||
created_by_id: Optional[str] = Field(default=None, description="The id of the user that made this object.")
|
||||
last_updated_by_id: Optional[str] = Field(default=None, description="The id of the user that made this object.")
|
||||
created_at: Optional[datetime] = Field(default=None, description="The timestamp when the object was created.")
|
||||
updated_at: Optional[datetime] = Field(default=None, description="The timestamp when the object was last updated.")
|
||||
|
||||
@@ -72,7 +72,7 @@ class SystemMessage(LettaMessage):
|
||||
content (str): The message content sent by the system
|
||||
"""
|
||||
|
||||
message_type: Literal[MessageType.system_message] = Field(MessageType.system_message, description="The type of the message.")
|
||||
message_type: Literal[MessageType.system_message] = Field(default=MessageType.system_message, description="The type of the message.")
|
||||
content: str = Field(..., description="The message content sent by the system")
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ class UserMessage(LettaMessage):
|
||||
content (Union[str, List[LettaUserMessageContentUnion]]): The message content sent by the user (can be a string or an array of multi-modal content parts)
|
||||
"""
|
||||
|
||||
message_type: Literal[MessageType.user_message] = Field(MessageType.user_message, description="The type of the message.")
|
||||
message_type: Literal[MessageType.user_message] = Field(default=MessageType.user_message, description="The type of the message.")
|
||||
content: Union[str, List[LettaUserMessageContentUnion]] = Field(
|
||||
...,
|
||||
description="The message content sent by the user (can be a string or an array of multi-modal content parts)",
|
||||
@@ -109,7 +109,9 @@ class ReasoningMessage(LettaMessage):
|
||||
signature (Optional[str]): The model-generated signature of the reasoning step
|
||||
"""
|
||||
|
||||
message_type: Literal[MessageType.reasoning_message] = Field(MessageType.reasoning_message, description="The type of the message.")
|
||||
message_type: Literal[MessageType.reasoning_message] = Field(
|
||||
default=MessageType.reasoning_message, description="The type of the message."
|
||||
)
|
||||
source: Literal["reasoner_model", "non_reasoner_model"] = "non_reasoner_model"
|
||||
reasoning: str
|
||||
signature: Optional[str] = None
|
||||
@@ -130,7 +132,7 @@ class HiddenReasoningMessage(LettaMessage):
|
||||
"""
|
||||
|
||||
message_type: Literal[MessageType.hidden_reasoning_message] = Field(
|
||||
MessageType.hidden_reasoning_message, description="The type of the message."
|
||||
default=MessageType.hidden_reasoning_message, description="The type of the message."
|
||||
)
|
||||
state: Literal["redacted", "omitted"]
|
||||
hidden_reasoning: Optional[str] = None
|
||||
@@ -170,7 +172,9 @@ class ToolCallMessage(LettaMessage):
|
||||
tool_call (Union[ToolCall, ToolCallDelta]): The tool call
|
||||
"""
|
||||
|
||||
message_type: Literal[MessageType.tool_call_message] = Field(MessageType.tool_call_message, description="The type of the message.")
|
||||
message_type: Literal[MessageType.tool_call_message] = Field(
|
||||
default=MessageType.tool_call_message, description="The type of the message."
|
||||
)
|
||||
tool_call: Union[ToolCall, ToolCallDelta]
|
||||
|
||||
def model_dump(self, *args, **kwargs):
|
||||
@@ -222,7 +226,9 @@ class ToolReturnMessage(LettaMessage):
|
||||
stderr (Optional[List(str)]): Captured stderr from the tool invocation
|
||||
"""
|
||||
|
||||
message_type: Literal[MessageType.tool_return_message] = Field(MessageType.tool_return_message, description="The type of the message.")
|
||||
message_type: Literal[MessageType.tool_return_message] = Field(
|
||||
default=MessageType.tool_return_message, description="The type of the message."
|
||||
)
|
||||
tool_return: str
|
||||
status: Literal["success", "error"]
|
||||
tool_call_id: str
|
||||
@@ -241,7 +247,9 @@ class AssistantMessage(LettaMessage):
|
||||
content (Union[str, List[LettaAssistantMessageContentUnion]]): The message content sent by the agent (can be a string or an array of content parts)
|
||||
"""
|
||||
|
||||
message_type: Literal[MessageType.assistant_message] = Field(MessageType.assistant_message, description="The type of the message.")
|
||||
message_type: Literal[MessageType.assistant_message] = Field(
|
||||
default=MessageType.assistant_message, description="The type of the message."
|
||||
)
|
||||
content: Union[str, List[LettaAssistantMessageContentUnion]] = Field(
|
||||
...,
|
||||
description="The message content sent by the agent (can be a string or an array of content parts)",
|
||||
|
||||
@@ -24,7 +24,7 @@ class MessageContent(BaseModel):
|
||||
|
||||
|
||||
class TextContent(MessageContent):
|
||||
type: Literal[MessageContentType.text] = Field(MessageContentType.text, description="The type of the message.")
|
||||
type: Literal[MessageContentType.text] = Field(default=MessageContentType.text, description="The type of the message.")
|
||||
text: str = Field(..., description="The text content of the message.")
|
||||
|
||||
|
||||
@@ -44,27 +44,27 @@ class ImageSource(BaseModel):
|
||||
|
||||
|
||||
class UrlImage(ImageSource):
|
||||
type: Literal[ImageSourceType.url] = Field(ImageSourceType.url, description="The source type for the image.")
|
||||
type: Literal[ImageSourceType.url] = Field(default=ImageSourceType.url, description="The source type for the image.")
|
||||
url: str = Field(..., description="The URL of the image.")
|
||||
|
||||
|
||||
class Base64Image(ImageSource):
|
||||
type: Literal[ImageSourceType.base64] = Field(ImageSourceType.base64, description="The source type for the image.")
|
||||
type: Literal[ImageSourceType.base64] = Field(default=ImageSourceType.base64, description="The source type for the image.")
|
||||
media_type: str = Field(..., description="The media type for the image.")
|
||||
data: str = Field(..., description="The base64 encoded image data.")
|
||||
detail: Optional[str] = Field(
|
||||
None,
|
||||
default=None,
|
||||
description="What level of detail to use when processing and understanding the image (low, high, or auto to let the model decide)",
|
||||
)
|
||||
|
||||
|
||||
class LettaImage(ImageSource):
|
||||
type: Literal[ImageSourceType.letta] = Field(ImageSourceType.letta, description="The source type for the image.")
|
||||
type: Literal[ImageSourceType.letta] = Field(default=ImageSourceType.letta, description="The source type for the image.")
|
||||
file_id: str = Field(..., description="The unique identifier of the image file persisted in storage.")
|
||||
media_type: Optional[str] = Field(None, description="The media type for the image.")
|
||||
data: Optional[str] = Field(None, description="The base64 encoded image data.")
|
||||
media_type: Optional[str] = Field(default=None, description="The media type for the image.")
|
||||
data: Optional[str] = Field(default=None, description="The base64 encoded image data.")
|
||||
detail: Optional[str] = Field(
|
||||
None,
|
||||
default=None,
|
||||
description="What level of detail to use when processing and understanding the image (low, high, or auto to let the model decide)",
|
||||
)
|
||||
|
||||
@@ -73,7 +73,7 @@ ImageSourceUnion = Annotated[Union[UrlImage, Base64Image, LettaImage], Field(dis
|
||||
|
||||
|
||||
class ImageContent(MessageContent):
|
||||
type: Literal[MessageContentType.image] = Field(MessageContentType.image, description="The type of the message.")
|
||||
type: Literal[MessageContentType.image] = Field(default=MessageContentType.image, description="The type of the message.")
|
||||
source: ImageSourceUnion = Field(..., description="The source of the image.")
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ def get_letta_assistant_message_content_union_str_json_schema():
|
||||
|
||||
class ToolCallContent(MessageContent):
|
||||
type: Literal[MessageContentType.tool_call] = Field(
|
||||
MessageContentType.tool_call, description="Indicates this content represents a tool call event."
|
||||
default=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.")
|
||||
@@ -175,7 +175,7 @@ class ToolCallContent(MessageContent):
|
||||
|
||||
class ToolReturnContent(MessageContent):
|
||||
type: Literal[MessageContentType.tool_return] = Field(
|
||||
MessageContentType.tool_return, description="Indicates this content represents a tool return event."
|
||||
default=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.")
|
||||
@@ -184,23 +184,23 @@ class ToolReturnContent(MessageContent):
|
||||
|
||||
class ReasoningContent(MessageContent):
|
||||
type: Literal[MessageContentType.reasoning] = Field(
|
||||
MessageContentType.reasoning, description="Indicates this is a reasoning/intermediate step."
|
||||
default=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.")
|
||||
signature: Optional[str] = Field(default=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."
|
||||
default=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."
|
||||
default=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.")
|
||||
|
||||
@@ -84,11 +84,11 @@ class MessageCreate(BaseModel):
|
||||
description="The content of the message.",
|
||||
json_schema_extra=get_letta_message_content_union_str_json_schema(),
|
||||
)
|
||||
name: Optional[str] = Field(None, description="The name of the participant.")
|
||||
otid: Optional[str] = Field(None, description="The offline threading id associated with this message")
|
||||
sender_id: Optional[str] = Field(None, description="The id of the sender of the message, can be an identity id or agent id")
|
||||
batch_item_id: Optional[str] = Field(None, description="The id of the LLMBatchItem that this message is associated with")
|
||||
group_id: Optional[str] = Field(None, description="The multi-agent group that the message was sent in")
|
||||
name: Optional[str] = Field(default=None, description="The name of the participant.")
|
||||
otid: Optional[str] = Field(default=None, description="The offline threading id associated with this message")
|
||||
sender_id: Optional[str] = Field(default=None, description="The id of the sender of the message, can be an identity id or agent id")
|
||||
batch_item_id: Optional[str] = Field(default=None, description="The id of the LLMBatchItem that this message is associated with")
|
||||
group_id: Optional[str] = Field(default=None, description="The multi-agent group that the message was sent in")
|
||||
|
||||
def model_dump(self, to_orm: bool = False, **kwargs) -> Dict[str, Any]:
|
||||
data = super().model_dump(**kwargs)
|
||||
@@ -101,9 +101,9 @@ class MessageCreate(BaseModel):
|
||||
class MessageUpdate(BaseModel):
|
||||
"""Request to update a message"""
|
||||
|
||||
role: Optional[MessageRole] = Field(None, description="The role of the participant.")
|
||||
role: Optional[MessageRole] = Field(default=None, description="The role of the participant.")
|
||||
content: Optional[Union[str, List[LettaMessageContentUnion]]] = Field(
|
||||
None,
|
||||
default=None,
|
||||
description="The content of the message.",
|
||||
json_schema_extra=get_letta_message_content_union_str_json_schema(),
|
||||
)
|
||||
@@ -112,11 +112,11 @@ class MessageUpdate(BaseModel):
|
||||
# agent_id: Optional[str] = Field(None, description="The unique identifier of the agent.")
|
||||
# NOTE: we probably shouldn't allow updating the model field, otherwise this loses meaning
|
||||
# model: Optional[str] = Field(None, description="The model used to make the function call.")
|
||||
name: Optional[str] = Field(None, description="The name of the participant.")
|
||||
name: Optional[str] = Field(default=None, description="The name of the participant.")
|
||||
# NOTE: we probably shouldn't allow updating the created_at field, right?
|
||||
# created_at: Optional[datetime] = Field(None, description="The time the message was created.")
|
||||
tool_calls: Optional[List[OpenAIToolCall,]] = Field(None, description="The list of tool calls requested.")
|
||||
tool_call_id: Optional[str] = Field(None, description="The id of the tool call.")
|
||||
tool_calls: Optional[List[OpenAIToolCall,]] = Field(default=None, description="The list of tool calls requested.")
|
||||
tool_call_id: Optional[str] = Field(default=None, description="The id of the tool call.")
|
||||
|
||||
def model_dump(self, to_orm: bool = False, **kwargs) -> Dict[str, Any]:
|
||||
data = super().model_dump(**kwargs)
|
||||
@@ -150,28 +150,28 @@ class Message(BaseMessage):
|
||||
"""
|
||||
|
||||
id: str = BaseMessage.generate_id_field()
|
||||
organization_id: Optional[str] = Field(None, description="The unique identifier of the organization.")
|
||||
agent_id: Optional[str] = Field(None, description="The unique identifier of the agent.")
|
||||
model: Optional[str] = Field(None, description="The model used to make the function call.")
|
||||
organization_id: Optional[str] = Field(default=None, description="The unique identifier of the organization.")
|
||||
agent_id: Optional[str] = Field(default=None, description="The unique identifier of the agent.")
|
||||
model: Optional[str] = Field(default=None, description="The model used to make the function call.")
|
||||
# Basic OpenAI-style fields
|
||||
role: MessageRole = Field(..., description="The role of the participant.")
|
||||
content: Optional[List[LettaMessageContentUnion]] = Field(None, description="The content of the message.")
|
||||
content: Optional[List[LettaMessageContentUnion]] = Field(default=None, description="The content of the message.")
|
||||
# NOTE: in OpenAI, this field is only used for roles 'user', 'assistant', and 'function' (now deprecated). 'tool' does not use it.
|
||||
name: Optional[str] = Field(
|
||||
None,
|
||||
default=None,
|
||||
description="For role user/assistant: the (optional) name of the participant. For role tool/function: the name of the function called.",
|
||||
)
|
||||
tool_calls: Optional[List[OpenAIToolCall]] = Field(
|
||||
None, description="The list of tool calls requested. Only applicable for role assistant."
|
||||
default=None, description="The list of tool calls requested. Only applicable for role assistant."
|
||||
)
|
||||
tool_call_id: Optional[str] = Field(None, description="The ID of the tool call. Only applicable for role tool.")
|
||||
tool_call_id: Optional[str] = Field(default=None, description="The ID of the tool call. Only applicable for role tool.")
|
||||
# Extras
|
||||
step_id: Optional[str] = Field(None, description="The id of the step that this message was created in.")
|
||||
otid: Optional[str] = Field(None, description="The offline threading id associated with this message")
|
||||
tool_returns: Optional[List[ToolReturn]] = Field(None, description="Tool execution return information for prior tool calls")
|
||||
group_id: Optional[str] = Field(None, description="The multi-agent group that the message was sent in")
|
||||
sender_id: Optional[str] = Field(None, description="The id of the sender of the message, can be an identity id or agent id")
|
||||
batch_item_id: Optional[str] = Field(None, description="The id of the LLMBatchItem that this message is associated with")
|
||||
step_id: Optional[str] = Field(default=None, description="The id of the step that this message was created in.")
|
||||
otid: Optional[str] = Field(default=None, description="The offline threading id associated with this message")
|
||||
tool_returns: Optional[List[ToolReturn]] = Field(default=None, description="Tool execution return information for prior tool calls")
|
||||
group_id: Optional[str] = Field(default=None, description="The multi-agent group that the message was sent in")
|
||||
sender_id: Optional[str] = Field(default=None, description="The id of the sender of the message, can be an identity id or agent id")
|
||||
batch_item_id: Optional[str] = Field(default=None, description="The id of the LLMBatchItem that this message is associated with")
|
||||
# This overrides the optional base orm schema, created_at MUST exist on all messages objects
|
||||
created_at: datetime = Field(default_factory=get_utc_time, description="The timestamp when the object was created.")
|
||||
|
||||
@@ -482,7 +482,9 @@ class Message(BaseMessage):
|
||||
# TODO(caren) implicit support for only non-parts/list content types
|
||||
if openai_message_dict["content"] is not None and type(openai_message_dict["content"]) is not str:
|
||||
raise ValueError(f"Invalid content type: {type(openai_message_dict['content'])}")
|
||||
content = [TextContent(text=openai_message_dict["content"])] if openai_message_dict["content"] else []
|
||||
content: List[LettaMessageContentUnion] = (
|
||||
[TextContent(text=openai_message_dict["content"])] if openai_message_dict["content"] else []
|
||||
)
|
||||
|
||||
# TODO(caren) bad assumption here that "reasoning_content" always comes before "redacted_reasoning_content"
|
||||
if "reasoning_content" in openai_message_dict and openai_message_dict["reasoning_content"]:
|
||||
@@ -491,14 +493,16 @@ class Message(BaseMessage):
|
||||
reasoning=openai_message_dict["reasoning_content"],
|
||||
is_native=True,
|
||||
signature=(
|
||||
openai_message_dict["reasoning_content_signature"] if openai_message_dict["reasoning_content_signature"] else None
|
||||
str(openai_message_dict["reasoning_content_signature"])
|
||||
if "reasoning_content_signature" in openai_message_dict
|
||||
else None
|
||||
),
|
||||
),
|
||||
)
|
||||
if "redacted_reasoning_content" in openai_message_dict and openai_message_dict["redacted_reasoning_content"]:
|
||||
content.append(
|
||||
RedactedReasoningContent(
|
||||
data=openai_message_dict["redacted_reasoning_content"] if "redacted_reasoning_content" in openai_message_dict else None,
|
||||
data=str(openai_message_dict["redacted_reasoning_content"]),
|
||||
),
|
||||
)
|
||||
if "omitted_reasoning_content" in openai_message_dict and openai_message_dict["omitted_reasoning_content"]:
|
||||
@@ -733,7 +737,7 @@ class Message(BaseMessage):
|
||||
else:
|
||||
warnings.warn(f"Using OpenAI with invalid 'name' field (name={self.name} role={self.role}).")
|
||||
|
||||
if parse_content_parts:
|
||||
if parse_content_parts and self.content is not None:
|
||||
for content in self.content:
|
||||
if isinstance(content, ReasoningContent):
|
||||
openai_message["reasoning_content"] = content.reasoning
|
||||
@@ -819,7 +823,7 @@ class Message(BaseMessage):
|
||||
}
|
||||
content = []
|
||||
# COT / reasoning / thinking
|
||||
if len(self.content) > 1:
|
||||
if self.content is not None and len(self.content) > 1:
|
||||
for content_part in self.content:
|
||||
if isinstance(content_part, ReasoningContent):
|
||||
content.append(
|
||||
@@ -1154,6 +1158,6 @@ class Message(BaseMessage):
|
||||
|
||||
class ToolReturn(BaseModel):
|
||||
status: Literal["success", "error"] = Field(..., description="The status of the tool call")
|
||||
stdout: Optional[List[str]] = Field(None, description="Captured stdout (e.g. prints, logs) from the tool invocation")
|
||||
stderr: Optional[List[str]] = Field(None, description="Captured stderr from the tool invocation")
|
||||
stdout: Optional[List[str]] = Field(default=None, description="Captured stdout (e.g. prints, logs) from the tool invocation")
|
||||
stderr: Optional[List[str]] = Field(default=None, description="Captured stderr from the tool invocation")
|
||||
# func_return: Optional[Any] = Field(None, description="The function return object")
|
||||
|
||||
Reference in New Issue
Block a user