#[cfg(feature = "stream")]
use super::items::{LogProbs, ReasoningSummaryPart};
use super::{
items::{
CodeInterpreterCall, ComputerToolCall, CustomToolCall, FileSearchToolCall,
FunctionToolCall, ImageGenerationCall, LocalShellCall, McpApprovalRequest, McpListTools,
McpToolCall, Reasoning, WebSearchToolCall,
},
shared::{
Annotation, ResponseFormat, ResponseTool, ResponseToolChoice, ResponseUsage,
TruncationStrategy,
},
};
use crate::v1::resources::shared::ReasoningEffort;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ResponseObject {
pub created_at: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<ResponseError>,
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub incomplete_details: Option<IncompleteDetails>,
#[serde(skip_serializing_if = "Option::is_none")]
pub instruction: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_output_tokens: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<HashMap<String, String>>,
pub model: String,
pub object: String,
pub output: Vec<ResponseOutput>,
#[serde(skip_serializing_if = "Option::is_none")]
pub parallel_tool_calls: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub previous_response_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning: Option<ResponseReasoning>,
pub status: ReasoningStatus,
#[serde(skip_serializing_if = "Option::is_none")]
pub temperature: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<ResponseText>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_choice: Option<ResponseToolChoice>,
pub tools: Vec<ResponseTool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub top_p: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub top_logprobs: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub truncation: Option<TruncationStrategy>,
#[serde(skip_serializing_if = "Option::is_none")]
pub usage: Option<ResponseUsage>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ResponseError {
pub code: String,
pub message: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct IncompleteDetails {
pub reason: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ResponseOutput {
Message(OutputMessage),
#[serde(rename = "function_call")]
FunctionToolCall(FunctionToolCall),
#[serde(rename = "file_search_call")]
FileSearchToolCall(FileSearchToolCall),
#[serde(rename = "web_search_call")]
WebSearchToolCall(WebSearchToolCall),
#[serde(rename = "computer_call")]
ComputerToolCall(ComputerToolCall),
Reasoning(Reasoning),
#[serde(rename = "image_generation_call")]
ImageGenerationCall(ImageGenerationCall),
#[serde(rename = "code_interpreter_call")]
CodeInterpreterCall(CodeInterpreterCall),
#[serde(rename = "local_shell_call")]
LocalShellCall(LocalShellCall),
#[serde(rename = "mcp_call")]
McpToolCall(McpToolCall),
#[serde(rename = "mcp_list_tools")]
McpListTools(McpListTools),
#[serde(rename = "mcp_approval_request")]
McpApprovalRequest(McpApprovalRequest),
#[serde(rename = "custom_tool_call")]
CustomToolCall(CustomToolCall),
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct OutputMessage {
pub id: String,
pub role: Role,
pub status: MessageStatus,
pub content: Vec<OutputContent>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ResponseReasoning {
#[serde(skip_serializing_if = "Option::is_none")]
pub effort: Option<ReasoningEffort>,
pub summary: Option<ReasoningSummary>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct ResponseText {
pub format: ResponseFormat,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ReasoningSummary {
Auto,
Concise,
Detailed,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ReasoningStatus {
Completed,
Failed,
InProgress,
Incomplete,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum Role {
User,
System,
Assistant,
Developer,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum MessageStatus {
InProgress,
Completed,
Incomplete,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(tag = "type")]
pub enum OutputContent {
#[serde(rename = "output_text")]
Text {
text: String,
annotations: Vec<Annotation>,
},
#[serde(rename = "reasoning_text")]
ReasoningText { text: String },
#[serde(rename = "refusal")]
Refusal { refusal: String },
}
#[cfg(feature = "stream")]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(tag = "type")]
pub enum ResponseStreamEvent {
#[serde(rename = "response.created")]
ResponseCreated {
sequence_number: u32,
response: ResponseObject,
},
#[serde(rename = "response.queued")]
ResponseQueued {
sequence_number: u32,
response: ResponseObject,
},
#[serde(rename = "response.in_progress")]
ResponseInProgress {
sequence_number: u32,
response: ResponseObject,
},
#[serde(rename = "response.completed")]
ResponseCompleted {
sequence_number: u32,
response: ResponseObject,
},
#[serde(rename = "response.failed")]
ResponseFailed {
sequence_number: u32,
response: ResponseObject,
},
#[serde(rename = "response.incomplete")]
ResponseIncomplete {
sequence_number: u32,
response: ResponseObject,
},
#[serde(rename = "response.output_item.added")]
ResponseOutputItemAdded {
sequence_number: u32,
output_index: usize,
item: ResponseOutput,
},
#[serde(rename = "response.output_item.done")]
ResponseOutputItemDone {
sequence_number: u32,
output_index: usize,
item: ResponseOutput,
},
#[serde(rename = "response.content_part.added")]
ResponseContentPartAdded {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
part: OutputContent,
},
#[serde(rename = "response.content_part.done")]
ResponseContentPartDone {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
part: OutputContent,
},
#[serde(rename = "response.reasoning_part.added")]
ResponseReasoningPartAdded {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
part: OutputContent,
},
#[serde(rename = "response.reasoning_part.done")]
ResponseReasoningPartDone {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
part: OutputContent,
},
#[serde(rename = "response.output_text.delta")]
ResponseOutputTextDelta {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
delta: String,
#[serde(skip_serializing_if = "Option::is_none")]
logprobs: Option<Vec<LogProbs>>,
},
#[serde(rename = "response.output_text.done")]
ResponseOutputTextDone {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
text: String,
#[serde(skip_serializing_if = "Option::is_none")]
logprobs: Option<Vec<LogProbs>>,
},
#[serde(rename = "response.output_text.annotation.added")]
ResponseOutputTextAnnotationAdded {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
annotation_index: usize,
annotation: Annotation,
},
#[serde(rename = "response.refusal.delta")]
ResponseRefusalDelta {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
delta: String,
},
#[serde(rename = "response.refusal.done")]
ResponseRefusalDone {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
refusal: String,
},
#[serde(rename = "response.function_call_arguments.delta")]
ResponseFunctionCallArgumentsDelta {
sequence_number: u32,
item_id: String,
output_index: usize,
delta: String,
},
#[serde(rename = "response.function_call_arguments.done")]
ResponseFunctionCallArgumentsDone {
sequence_number: u32,
item_id: String,
output_index: usize,
name: String,
arguments: String,
},
#[serde(rename = "response.file_search_call.in_progress")]
ResponseFileSearchCallInProgress {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.file_search_call.searching")]
ResponseFileSearchCallSearching {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.file_search_call.completed")]
ResponseFileSearchCallCompleted {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.web_search_call.in_progress")]
ResponseWebSearchCallInProgress {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.web_search_call.searching")]
ResponseWebSearchCallSearching {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.web_search_call.completed")]
ResponseWebSearchCallCompleted {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.reasoning_text.delta")]
ResponseReasoningTextDelta {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
delta: String,
},
#[serde(rename = "response.reasoning_text.done")]
ResponseReasoningTextDone {
sequence_number: u32,
item_id: String,
output_index: usize,
content_index: usize,
text: String,
},
#[serde(rename = "response.reasoning_summary_part.added")]
ResponseReasoningSummaryPartAdded {
sequence_number: u32,
item_id: String,
output_index: usize,
summary_index: usize,
part: ReasoningSummaryPart,
},
#[serde(rename = "response.reasoning_summary_part.done")]
ResponseReasoningSummaryPartDone {
sequence_number: u32,
item_id: String,
output_index: usize,
summary_index: usize,
part: ReasoningSummaryPart,
},
#[serde(rename = "response.reasoning_summary_text.delta")]
ResponseReasoningSummaryTextDelta {
sequence_number: u32,
item_id: String,
output_index: usize,
summary_index: usize,
delta: String,
},
#[serde(rename = "response.reasoning_summary_text.done")]
ResponseReasoningSummaryTextDone {
sequence_number: u32,
item_id: String,
output_index: usize,
summary_index: usize,
text: String,
},
#[serde(rename = "response.image_generation_call.in_progress")]
ResponseImageGenerationCallInProgress {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.image_generation_call.generating")]
ResponseImageGenerationCallGenerating {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.image_generation_call.partial_image")]
ResponseImageGenerationCallPartialImage {
sequence_number: u32,
item_id: String,
output_index: usize,
partial_image_index: usize,
partial_image_b64: String,
},
#[serde(rename = "response.image_generation_call.completed")]
ResponseImageGenerationCallCompleted {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.mcp_call.in_progress")]
ResponseMcpCallInProgress {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.mcp_call.completed")]
ResponseMcpCallCompleted {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.mcp_call.failed")]
ResponseMcpCallFailed {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.mcp_call_arguments.delta")]
ResponseMcpCallArgumentsDelta {
sequence_number: u32,
item_id: String,
output_index: usize,
delta: String,
},
#[serde(rename = "response.mcp_call_arguments.done")]
ResponseMcpCallArgumentsDone {
sequence_number: u32,
item_id: String,
output_index: usize,
arguments: String,
},
#[serde(rename = "response.mcp_list_tools.in_progress")]
ResponseMcpListToolsInProgress {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.mcp_list_tools.completed")]
ResponseMcpListToolsCompleted {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.mcp_list_tools.failed")]
ResponseMcpListToolsFailed {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.code_interpreter_call.in_progress")]
ResponseCodeInterpreterCallInProgress {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.code_interpreter_call.interpreting")]
ResponseCodeInterpreterCallInterpreting {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.code_interpreter_call.completed")]
ResponseCodeInterpreterCallCompleted {
sequence_number: u32,
item_id: String,
output_index: usize,
},
#[serde(rename = "response.code_interpreter_call_code.delta")]
ResponseCodeInterpreterCallCodeDelta {
sequence_number: u32,
item_id: String,
output_index: usize,
delta: String,
},
#[serde(rename = "response.code_interpreter_call_code.done")]
ResponseCodeInterpreterCallCodeDone {
sequence_number: u32,
item_id: String,
output_index: usize,
code: String,
},
#[serde(rename = "response.custom_tool_call_input.delta")]
ResponseCustomToolCallInputDelta {
sequence_number: u32,
item_id: String,
output_index: usize,
delta: String,
},
#[serde(rename = "response.custom_tool_call_input.done")]
ResponseCustomToolCallInputDone {
sequence_number: u32,
item_id: String,
output_index: usize,
input: String,
},
#[serde(rename = "keepalive")]
Keepalive { sequence_number: u32 },
#[serde(rename = "error")]
Error {
sequence_number: u32,
code: String,
message: String,
#[serde(skip_serializing_if = "Option::is_none")]
param: Option<String>,
},
}
#[cfg(feature = "stream")]
impl ResponseStreamEvent {
pub fn event_name(&self) -> &'static str {
match self {
Self::ResponseCreated { .. } => "response.created",
Self::ResponseQueued { .. } => "response.queued",
Self::ResponseInProgress { .. } => "response.in_progress",
Self::ResponseCompleted { .. } => "response.completed",
Self::ResponseFailed { .. } => "response.failed",
Self::ResponseIncomplete { .. } => "response.incomplete",
Self::ResponseOutputItemAdded { .. } => "response.output_item.added",
Self::ResponseOutputItemDone { .. } => "response.output_item.done",
Self::ResponseContentPartAdded { .. } => "response.content_part.added",
Self::ResponseContentPartDone { .. } => "response.content_part.done",
Self::ResponseReasoningPartAdded { .. } => "response.reasoning_part.added",
Self::ResponseReasoningPartDone { .. } => "response.reasoning_part.done",
Self::ResponseOutputTextDelta { .. } => "response.output_text.delta",
Self::ResponseOutputTextDone { .. } => "response.output_text.done",
Self::ResponseOutputTextAnnotationAdded { .. } => {
"response.output_text.annotation.added"
}
Self::ResponseRefusalDelta { .. } => "response.refusal.delta",
Self::ResponseRefusalDone { .. } => "response.refusal.done",
Self::ResponseFunctionCallArgumentsDelta { .. } => {
"response.function_call_arguments.delta"
}
Self::ResponseFunctionCallArgumentsDone { .. } => {
"response.function_call_arguments.done"
}
Self::ResponseFileSearchCallInProgress { .. } => {
"response.file_search_call.in_progress"
}
Self::ResponseFileSearchCallSearching { .. } => "response.file_search_call.searching",
Self::ResponseFileSearchCallCompleted { .. } => "response.file_search_call.completed",
Self::ResponseWebSearchCallInProgress { .. } => "response.web_search_call.in_progress",
Self::ResponseWebSearchCallSearching { .. } => "response.web_search_call.searching",
Self::ResponseWebSearchCallCompleted { .. } => "response.web_search_call.completed",
Self::ResponseReasoningTextDelta { .. } => "response.reasoning_text.delta",
Self::ResponseReasoningTextDone { .. } => "response.reasoning_text.done",
Self::ResponseReasoningSummaryPartAdded { .. } => {
"response.reasoning_summary_part.added"
}
Self::ResponseReasoningSummaryPartDone { .. } => "response.reasoning_summary_part.done",
Self::ResponseReasoningSummaryTextDelta { .. } => {
"response.reasoning_summary_text.delta"
}
Self::ResponseReasoningSummaryTextDone { .. } => "response.reasoning_summary_text.done",
Self::ResponseImageGenerationCallInProgress { .. } => {
"response.image_generation_call.in_progress"
}
Self::ResponseImageGenerationCallGenerating { .. } => {
"response.image_generation_call.generating"
}
Self::ResponseImageGenerationCallPartialImage { .. } => {
"response.image_generation_call.partial_image"
}
Self::ResponseImageGenerationCallCompleted { .. } => {
"response.image_generation_call.completed"
}
Self::ResponseMcpCallInProgress { .. } => "response.mcp_call.in_progress",
Self::ResponseMcpCallCompleted { .. } => "response.mcp_call.completed",
Self::ResponseMcpCallFailed { .. } => "response.mcp_call.failed",
Self::ResponseMcpCallArgumentsDelta { .. } => "response.mcp_call_arguments.delta",
Self::ResponseMcpCallArgumentsDone { .. } => "response.mcp_call_arguments.done",
Self::ResponseMcpListToolsInProgress { .. } => "response.mcp_list_tools.in_progress",
Self::ResponseMcpListToolsCompleted { .. } => "response.mcp_list_tools.completed",
Self::ResponseMcpListToolsFailed { .. } => "response.mcp_list_tools.failed",
Self::ResponseCodeInterpreterCallInProgress { .. } => {
"response.code_interpreter_call.in_progress"
}
Self::ResponseCodeInterpreterCallInterpreting { .. } => {
"response.code_interpreter_call.interpreting"
}
Self::ResponseCodeInterpreterCallCompleted { .. } => {
"response.code_interpreter_call.completed"
}
Self::ResponseCodeInterpreterCallCodeDelta { .. } => {
"response.code_interpreter_call_code.delta"
}
Self::ResponseCodeInterpreterCallCodeDone { .. } => {
"response.code_interpreter_call_code.done"
}
Self::ResponseCustomToolCallInputDelta { .. } => {
"response.custom_tool_call_input.delta"
}
Self::ResponseCustomToolCallInputDone { .. } => "response.custom_tool_call_input.done",
Self::Keepalive { .. } => "keepalive",
Self::Error { .. } => "error",
}
}
}