use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ResponsesInputItem {
#[serde(rename = "message")]
Message {
role: ResponsesRole,
content: ResponsesMessageContent,
},
FunctionCall {
call_id: String,
name: String,
arguments: String,
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<String>,
},
FunctionCallOutput { call_id: String, output: Value },
Reasoning {
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
encrypted_content: Option<String>,
summary: Vec<ResponsesReasoningSummary>,
},
ItemReference { id: String },
CustomToolCall {
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<String>,
call_id: String,
name: String,
input: String,
},
CustomToolCallOutput { call_id: String, output: Value },
McpApprovalResponse {
approval_request_id: String,
approve: bool,
},
LocalShellCall {
id: String,
call_id: String,
action: LocalShellAction,
},
LocalShellCallOutput { call_id: String, output: String },
ShellCall {
id: String,
call_id: String,
status: String,
action: ShellAction,
},
ShellCallOutput {
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<String>,
call_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
status: Option<String>,
output: Vec<ShellOutputEntry>,
},
ApplyPatchCall {
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<String>,
call_id: String,
status: String,
operation: ApplyPatchOperation,
},
ApplyPatchCallOutput {
call_id: String,
status: String,
#[serde(skip_serializing_if = "Option::is_none")]
output: Option<String>,
},
ToolSearchCall {
id: String,
execution: String,
call_id: Option<String>,
status: String,
arguments: Value,
},
ToolSearchOutput {
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<String>,
execution: String,
call_id: Option<String>,
status: String,
tools: Vec<Value>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ResponsesRole {
System,
Developer,
User,
Assistant,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ResponsesMessageContent {
Text(String),
Parts(Vec<ResponsesContentPart>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ResponsesContentPart {
InputText {
text: String,
},
InputImage {
image_url: String,
},
InputFile {
file_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
file_id: Option<String>,
},
OutputText {
text: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResponsesReasoningSummary {
#[serde(rename = "type")]
pub summary_type: String,
pub text: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LocalShellAction {
#[serde(rename = "type")]
pub action_type: String,
pub command: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timeout_ms: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub working_directory: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub env: Option<std::collections::HashMap<String, String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ShellAction {
pub commands: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timeout_ms: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_output_length: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ShellOutputEntry {
pub stdout: String,
pub stderr: String,
pub outcome: ShellOutcome,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ShellOutcome {
Exit { exit_code: i32 },
Timeout,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ApplyPatchOperation {
CreateFile { path: String, diff: String },
DeleteFile { path: String },
UpdateFile { path: String, diff: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ResponsesTool {
Function {
name: String,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
parameters: Value,
#[serde(skip_serializing_if = "Option::is_none")]
strict: Option<bool>,
},
WebSearch {
#[serde(skip_serializing_if = "Option::is_none")]
search_context_size: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
user_location: Option<Value>,
},
#[serde(rename = "web_search_preview")]
WebSearchPreview {
#[serde(skip_serializing_if = "Option::is_none")]
search_context_size: Option<String>,
},
CodeInterpreter {
#[serde(skip_serializing_if = "Option::is_none")]
container: Option<Value>,
},
FileSearch {
vector_store_ids: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
max_num_results: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
filters: Option<Value>,
},
ImageGeneration {
#[serde(skip_serializing_if = "Option::is_none")]
model: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
quality: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
size: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
background: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
output_format: Option<String>,
},
Shell {
#[serde(skip_serializing_if = "Option::is_none")]
environment: Option<Value>,
},
LocalShell,
ApplyPatch,
Mcp {
server_label: String,
#[serde(skip_serializing_if = "Option::is_none")]
server_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
allowed_tools: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
headers: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
require_approval: Option<Value>,
},
Custom {
name: String,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
format: Option<Value>,
},
ToolSearch {
#[serde(skip_serializing_if = "Option::is_none")]
execution: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
},
}
#[derive(Debug, Clone, Serialize)]
pub struct ResponsesRequest {
pub model: String,
pub input: Vec<ResponsesInputItem>,
#[serde(skip_serializing_if = "Option::is_none")]
pub temperature: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub top_p: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_output_tokens: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<Vec<ResponsesTool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_choice: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reasoning: Option<ResponsesReasoningConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub previous_response_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub store: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub include: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stream: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub instructions: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub truncation: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service_tier: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResponsesReasoningConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub effort: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub summary: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesResponse {
pub id: String,
#[serde(default)]
pub output: Vec<ResponsesOutputItem>,
#[serde(default)]
pub usage: Option<ResponsesUsage>,
#[serde(default)]
pub error: Option<ResponsesError>,
#[serde(default)]
pub status: Option<String>,
#[serde(default)]
pub model: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesError {
pub message: String,
#[serde(default)]
pub code: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ResponsesOutputItem {
Message {
id: String,
content: Vec<ResponsesOutputContent>,
#[serde(default)]
phase: Option<String>,
},
FunctionCall {
id: String,
call_id: String,
name: String,
arguments: String,
},
Reasoning {
id: String,
summary: Vec<ResponsesReasoningSummary>,
#[serde(default)]
encrypted_content: Option<String>,
},
WebSearchCall {
id: String,
status: String,
#[serde(default)]
action: Option<Value>,
},
CodeInterpreterCall {
id: String,
#[serde(default)]
code: Option<String>,
#[serde(default)]
container_id: Option<String>,
#[serde(default)]
outputs: Option<Vec<Value>>,
},
ImageGenerationCall {
id: String,
#[serde(default)]
result: Option<String>,
},
FileSearchCall {
id: String,
#[serde(default)]
queries: Option<Vec<String>>,
#[serde(default)]
results: Option<Vec<Value>>,
},
ShellCall {
id: String,
call_id: String,
status: String,
action: ShellAction,
},
ShellCallOutput {
#[serde(default)]
id: Option<String>,
call_id: String,
output: Vec<ShellOutputEntry>,
},
ApplyPatchCall {
id: String,
call_id: String,
status: String,
operation: ApplyPatchOperation,
},
LocalShellCall {
id: String,
call_id: String,
action: LocalShellAction,
},
McpCall {
id: String,
status: String,
#[serde(default)]
name: Option<String>,
#[serde(default)]
server_label: Option<String>,
#[serde(default)]
arguments: Option<String>,
#[serde(default)]
output: Option<String>,
#[serde(default)]
error: Option<String>,
},
McpApprovalRequest { id: String },
CustomToolCall {
id: String,
call_id: String,
name: String,
input: String,
},
ToolSearchCall {
id: String,
execution: String,
#[serde(default)]
call_id: Option<String>,
status: String,
#[serde(default)]
arguments: Option<Value>,
},
ToolSearchOutput {
#[serde(default)]
id: Option<String>,
execution: String,
#[serde(default)]
call_id: Option<String>,
status: String,
tools: Vec<Value>,
},
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesOutputContent {
#[serde(rename = "type")]
pub content_type: String,
pub text: String,
#[serde(default)]
pub annotations: Vec<Value>,
#[serde(default)]
pub logprobs: Option<Vec<ResponsesLogprob>>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesLogprob {
pub token: String,
pub logprob: f64,
#[serde(default)]
pub top_logprobs: Vec<ResponsesTopLogprob>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesTopLogprob {
pub token: String,
pub logprob: f64,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesUsage {
pub input_tokens: u32,
pub output_tokens: u32,
#[serde(default)]
pub input_tokens_details: Option<ResponsesTokenDetails>,
#[serde(default)]
pub output_tokens_details: Option<ResponsesOutputTokenDetails>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesTokenDetails {
#[serde(default)]
pub cached_tokens: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesOutputTokenDetails {
#[serde(default)]
pub reasoning_tokens: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ResponsesStreamEvent {
#[serde(rename = "response.created")]
ResponseCreated {
response: ResponsesStreamCreatedData,
},
#[serde(rename = "response.completed")]
ResponseCompleted {
response: ResponsesStreamCompletedData,
},
#[serde(rename = "response.incomplete")]
ResponseIncomplete {
response: ResponsesStreamCompletedData,
},
#[serde(rename = "response.failed")]
ResponseFailed { response: ResponsesStreamFailedData },
#[serde(rename = "response.output_item.added")]
OutputItemAdded { output_index: u32, item: Value },
#[serde(rename = "response.output_item.done")]
OutputItemDone { output_index: u32, item: Value },
#[serde(rename = "response.output_text.delta")]
OutputTextDelta {
item_id: String,
delta: String,
#[serde(default)]
logprobs: Option<Vec<ResponsesLogprob>>,
},
#[serde(rename = "response.output_text.done")]
OutputTextDone { item_id: String, text: String },
#[serde(rename = "response.function_call_arguments.delta")]
FunctionCallArgumentsDelta {
item_id: String,
call_id: String,
delta: String,
},
#[serde(rename = "response.function_call_arguments.done")]
FunctionCallArgumentsDone {
item_id: String,
call_id: String,
arguments: String,
},
#[serde(rename = "response.reasoning_summary_text.delta")]
ReasoningSummaryTextDelta { item_id: String, delta: String },
#[serde(rename = "response.reasoning_summary_text.done")]
ReasoningSummaryTextDone { item_id: String, text: String },
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesStreamCreatedData {
pub id: String,
#[serde(default)]
pub model: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesStreamCompletedData {
#[serde(default)]
pub usage: Option<ResponsesUsage>,
#[serde(default)]
pub service_tier: Option<String>,
#[serde(default)]
pub incomplete_details: Option<Value>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ResponsesStreamFailedData {
#[serde(default)]
pub error: Option<ResponsesError>,
#[serde(default)]
pub usage: Option<ResponsesUsage>,
}