use crate::common::{structured_output::Schema, tool::Tool, usage::Usage};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct Content {
#[serde(rename = "type")]
pub type_name: Option<String>,
pub text: Option<String>,
pub annotations: Option<Vec<String>>,
pub logprobs: Option<Vec<String>>,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct FileSearchCallResult {
pub attributes: Option<HashMap<String, String>>,
pub file_id: Option<String>,
pub filename: Option<String>,
pub score: Option<f64>,
pub text: Option<String>,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct Output {
pub id: Option<String>,
#[serde(rename = "type")]
pub type_name: Option<String>,
pub role: Option<String>,
pub status: Option<String>,
pub content: Option<Vec<Content>>,
pub arguments: Option<String>,
pub call_id: Option<String>,
pub name: Option<String>,
pub queries: Option<Vec<String>>,
pub results: Option<Vec<FileSearchCallResult>>,
pub action: Option<Value>,
pub pending_safety_checks: Option<Value>,
pub summary: Option<Value>,
pub encrypted_content: Option<String>,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct Reasoning {
pub effort: Option<String>,
pub summary: Option<String>,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct Text {
pub format: Schema,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct Response {
pub id: Option<String>,
pub object: Option<String>,
pub created_at: Option<usize>,
pub completed_at: Option<u64>,
pub status: Option<String>,
pub background: Option<bool>,
pub error: Option<Value>,
pub incomplete_details: Option<Value>,
pub instructions: Option<String>,
pub max_output_tokens: Option<usize>,
pub max_tool_calls: Option<usize>,
pub model: Option<String>,
pub output: Option<Vec<Output>>,
pub parallel_tool_calls: Option<bool>,
pub previous_response_id: Option<String>,
pub reasoning: Option<Reasoning>,
pub service_tier: Option<String>,
pub store: Option<bool>,
pub temperature: Option<f64>,
pub text: Option<Text>,
pub tool_choice: Option<String>,
pub tools: Option<Vec<Tool>>,
pub top_logprobs: Option<usize>,
pub top_p: Option<f64>,
pub truncation: Option<String>,
pub usage: Option<Usage>,
pub user: Option<String>,
pub metadata: Option<HashMap<String, String>>,
}
impl Response {
pub fn output_text(&self) -> Option<String> {
let output = if let Some(outputs) = &self.output {
let outputs =
outputs.iter().filter_map(|o| if o.type_name.as_deref() == Some("message") { Some(o.clone()) } else { None }).collect::<Vec<_>>();
if outputs.is_empty() {
tracing::warn!("No message outputs found in response");
return None;
}
outputs.first().unwrap().clone()
} else {
return None;
};
let content = if let Some(contents) = &output.content {
let contents = contents
.iter()
.filter_map(|c| if c.type_name.as_deref() == Some("output_text") { Some(c.clone()) } else { None })
.collect::<Vec<_>>();
if contents.is_empty() {
tracing::warn!("No output_text contents found in message output");
return None;
}
contents.first().unwrap().clone()
} else {
return None;
};
content.text.clone()
}
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct DeleteResponseResult {
pub id: String,
pub object: String,
pub deleted: bool,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct ResponseInputItem {
pub id: String,
#[serde(rename = "type")]
pub item_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct InputItemsListResponse {
pub object: String,
pub data: Vec<ResponseInputItem>,
#[serde(skip_serializing_if = "Option::is_none")]
pub first_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_id: Option<String>,
pub has_more: bool,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct CompactedResponse {
pub id: String,
pub object: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub output: Option<Vec<Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub usage: Option<Usage>,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct InputTokensResponse {
pub object: String,
pub input_tokens: u64,
}