diff --git a/fern/openapi.json b/fern/openapi.json index e372aa48..35993dff 100644 --- a/fern/openapi.json +++ b/fern/openapi.json @@ -22319,15 +22319,46 @@ "description": "The message type to be created.", "default": "approval" }, + "approvals": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/ApprovalReturn" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Approvals", + "description": "The list of approval responses" + }, "approve": { - "type": "boolean", + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], "title": "Approve", - "description": "Whether the tool has been approved" + "description": "Whether the tool has been approved", + "deprecated": true }, "approval_request_id": { - "type": "string", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], "title": "Approval Request Id", - "description": "The message ID of the approval request" + "description": "The message ID of the approval request", + "deprecated": true }, "reason": { "anyOf": [ @@ -22339,11 +22370,11 @@ } ], "title": "Reason", - "description": "An optional explanation for the provided approval status" + "description": "An optional explanation for the provided approval status", + "deprecated": true } }, "type": "object", - "required": ["approve", "approval_request_id"], "title": "ApprovalCreate", "description": "Input to approve or deny a tool call request" }, @@ -22555,16 +22586,78 @@ ], "title": "Run Id" }, + "approvals": { + "anyOf": [ + { + "items": { + "$ref": "#/components/schemas/ApprovalReturn" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Approvals", + "description": "The list of approval responses" + }, + "approve": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Approve", + "description": "Whether the tool has been approved", + "deprecated": true + }, + "approval_request_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approval Request Id", + "description": "The message ID of the approval request", + "deprecated": true + }, + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reason", + "description": "An optional explanation for the provided approval status", + "deprecated": true + } + }, + "type": "object", + "required": ["id", "date"], + "title": "ApprovalResponseMessage", + "description": "A message representing a response form the user indicating whether a tool has been approved to run.\n\nArgs:\n id (str): The ID of the message\n date (datetime): The date the message was created in ISO format\n name (Optional[str]): The name of the sender of the message\n approve: (bool) Whether the tool has been approved\n approval_request_id: The ID of the approval request\n reason: (Optional[str]) An optional explanation for the provided approval status" + }, + "ApprovalReturn": { + "properties": { + "tool_call_id": { + "type": "string", + "title": "Tool Call Id", + "description": "The ID of the tool call that corresponds to this approval" + }, "approve": { "type": "boolean", "title": "Approve", "description": "Whether the tool has been approved" }, - "approval_request_id": { - "type": "string", - "title": "Approval Request Id", - "description": "The message ID of the approval request" - }, "reason": { "anyOf": [ { @@ -22579,9 +22672,8 @@ } }, "type": "object", - "required": ["id", "date", "approve", "approval_request_id"], - "title": "ApprovalResponseMessage", - "description": "A message representing a response form the user indicating whether a tool has been approved to run.\n\nArgs:\n id (str): The ID of the message\n date (datetime): The date the message was created in ISO format\n name (Optional[str]): The name of the sender of the message\n approve: (bool) Whether the tool has been approved\n approval_request_id: The ID of the approval request\n reason: (Optional[str]) An optional explanation for the provided approval status" + "required": ["tool_call_id", "approve"], + "title": "ApprovalReturn" }, "ArchivalMemorySearchResponse": { "properties": { diff --git a/letta/schemas/letta_message.py b/letta/schemas/letta_message.py index b3bf96e7..e67ba46a 100644 --- a/letta/schemas/letta_message.py +++ b/letta/schemas/letta_message.py @@ -285,6 +285,12 @@ class ApprovalRequestMessage(LettaMessage): tool_call: Union[ToolCall, ToolCallDelta] = Field(..., description="The tool call that has been requested by the llm to run") +class ApprovalReturn(BaseModel): + tool_call_id: str = Field(..., description="The ID of the tool call that corresponds to this approval") + approve: bool = Field(..., description="Whether the tool has been approved") + reason: Optional[str] = Field(None, description="An optional explanation for the provided approval status") + + class ApprovalResponseMessage(LettaMessage): """ A message representing a response form the user indicating whether a tool has been approved to run. @@ -301,9 +307,10 @@ class ApprovalResponseMessage(LettaMessage): message_type: Literal[MessageType.approval_response_message] = Field( default=MessageType.approval_response_message, description="The type of the message." ) - approve: bool = Field(..., description="Whether the tool has been approved") - approval_request_id: str = Field(..., description="The message ID of the approval request") - reason: Optional[str] = Field(None, description="An optional explanation for the provided approval status") + approvals: Optional[List[ApprovalReturn]] = Field(default=None, description="The list of approval responses") + approve: Optional[bool] = Field(None, description="Whether the tool has been approved", deprecated=True) + approval_request_id: Optional[str] = Field(None, description="The message ID of the approval request", deprecated=True) + reason: Optional[str] = Field(None, description="An optional explanation for the provided approval status", deprecated=True) class AssistantMessage(LettaMessage): diff --git a/letta/schemas/message.py b/letta/schemas/message.py index 7350cef0..4f456bfa 100644 --- a/letta/schemas/message.py +++ b/letta/schemas/message.py @@ -23,6 +23,7 @@ from letta.schemas.letta_base import OrmMetadataBase from letta.schemas.letta_message import ( ApprovalRequestMessage, ApprovalResponseMessage, + ApprovalReturn, AssistantMessage, HiddenReasoningMessage, LettaMessage, @@ -116,9 +117,22 @@ class ApprovalCreate(MessageCreateBase): """Input to approve or deny a tool call request""" type: Literal[MessageCreateType.approval] = Field(default=MessageCreateType.approval, description="The message type to be created.") - approve: bool = Field(..., description="Whether the tool has been approved") - approval_request_id: str = Field(..., description="The message ID of the approval request") - reason: Optional[str] = Field(None, description="An optional explanation for the provided approval status") + approvals: Optional[List[ApprovalReturn]] = Field(default=None, description="The list of approval responses") + approve: Optional[bool] = Field(None, description="Whether the tool has been approved", deprecated=True) + approval_request_id: Optional[str] = Field(None, description="The message ID of the approval request", deprecated=True) + reason: Optional[str] = Field(None, description="An optional explanation for the provided approval status", deprecated=True) + + @model_validator(mode="after") + def migrate_deprecated_fields(self): + if not self.approvals and self.approve is not None and self.approval_request_id is not None: + self.approvals = [ + ApprovalReturn( + tool_call_id=self.approval_request_id, + approve=self.approve, + reason=self.reason, + ) + ] + return self MessageCreateUnion = Union[MessageCreate, ApprovalCreate] @@ -334,6 +348,14 @@ class Message(BaseMessage): approve=self.approve, approval_request_id=self.approval_request_id, reason=self.denial_reason, + approvals=[ + # TODO: temporary workaround to populate from legacy fields + ApprovalReturn( + tool_call_id=self.approval_request_id, + approve=self.approve, + reason=self.denial_reason, + ) + ], run_id=self.run_id, ) messages.append(approval_response_message)