Skip to main content

openai_types/responses/
output.rs

1// MANUAL — hand-maintained. py2rust sync will not overwrite.
2// Output items — the typed output from a Response.
3
4use serde::{Deserialize, Serialize};
5
6use super::common::Role;
7use super::response::ResponseAnnotation;
8
9/// Content block within an output item.
10#[derive(Debug, Clone, Deserialize, Serialize)]
11#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
12pub struct ResponseOutputContent {
13    /// Content type (e.g. "output_text", "refusal").
14    #[serde(rename = "type")]
15    pub type_: String,
16    /// Text content (for output_text blocks).
17    #[serde(default)]
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub text: Option<String>,
20    /// Annotations on the text (citations, file paths, etc.).
21    #[serde(default)]
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub annotations: Option<Vec<ResponseAnnotation>>,
24}
25
26/// Output item in a response.
27///
28/// Covers multiple output types: `message`, `function_call`, `web_search_call`, etc.
29/// Uses a flat struct with optional fields rather than a tagged enum for maximum
30/// forward compatibility with new output types.
31#[derive(Debug, Clone, Deserialize, Serialize)]
32#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
33pub struct ResponseOutputItem {
34    /// Item type: "message", "function_call", "function_call_output", "web_search_call", etc.
35    #[serde(rename = "type")]
36    pub type_: String,
37    /// Unique ID of the output item.
38    #[serde(default)]
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub id: Option<String>,
41    /// Role (for message items).
42    #[serde(default)]
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub role: Option<Role>,
45    /// Content blocks (for message items).
46    #[serde(default)]
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub content: Option<Vec<ResponseOutputContent>>,
49    /// Item status: "in_progress", "completed", "incomplete".
50    #[serde(default)]
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub status: Option<String>,
53    /// Function name (for function_call items).
54    #[serde(default)]
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub name: Option<String>,
57    /// JSON-encoded arguments string (for function_call items).
58    #[serde(default)]
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub arguments: Option<String>,
61    /// Unique call ID for matching with function_call_output (for function_call items).
62    #[serde(default)]
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub call_id: Option<String>,
65}
66
67/// A typed output item enum (discriminated union).
68///
69/// Discriminated by the `type` field. Covers message, function_call, reasoning,
70/// and other output types. Used where stronger typing is preferred.
71#[derive(Debug, Clone, Serialize, Deserialize)]
72#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
73#[serde(tag = "type")]
74#[non_exhaustive]
75pub enum OutputItem {
76    /// Output message from the model.
77    #[serde(rename = "message")]
78    Message {
79        /// Unique ID.
80        #[serde(default)]
81        id: Option<String>,
82        /// Role — always "assistant".
83        #[serde(default)]
84        role: Option<Role>,
85        /// Content blocks.
86        #[serde(default)]
87        content: Option<Vec<ResponseOutputContent>>,
88        /// Item status.
89        #[serde(default)]
90        status: Option<String>,
91    },
92    /// Function call from the model.
93    #[serde(rename = "function_call")]
94    FunctionCall(FunctionToolCall),
95    /// Reasoning chain-of-thought.
96    #[serde(rename = "reasoning")]
97    Reasoning(ReasoningItem),
98    /// Web search call.
99    #[serde(rename = "web_search_call")]
100    WebSearchCall(serde_json::Value),
101    /// File search call.
102    #[serde(rename = "file_search_call")]
103    FileSearchCall(serde_json::Value),
104    /// Catch-all for unknown output item types.
105    #[serde(other)]
106    Other,
107}
108
109/// A function tool call from the model.
110///
111/// Maps to Python SDK `ResponseFunctionToolCall`.
112#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
113#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
114pub struct FunctionToolCall {
115    /// JSON-encoded arguments string.
116    pub arguments: String,
117    /// Unique call ID for matching with function_call_output.
118    pub call_id: String,
119    /// Function name.
120    pub name: String,
121    /// Unique ID of the function tool call (populated when returned via API).
122    #[serde(default)]
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub id: Option<String>,
125    /// Item status.
126    #[serde(default)]
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub status: Option<String>,
129}
130
131/// A reasoning chain-of-thought item.
132///
133/// Contains summary, optional content, and optional encrypted content for
134/// multi-turn replay. Maps to Python SDK `ResponseReasoningItem`.
135#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
136#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
137pub struct ReasoningItem {
138    /// Unique identifier.
139    pub id: String,
140    /// Reasoning summary parts.
141    pub summary: Vec<SummaryPart>,
142    /// Reasoning text content.
143    #[serde(default)]
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub content: Option<Vec<ReasoningContent>>,
146    /// Encrypted content for multi-turn replay.
147    #[serde(default)]
148    #[serde(skip_serializing_if = "Option::is_none")]
149    pub encrypted_content: Option<String>,
150    /// Item status.
151    #[serde(default)]
152    #[serde(skip_serializing_if = "Option::is_none")]
153    pub status: Option<String>,
154}
155
156/// A part of a reasoning summary.
157#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
158#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
159#[serde(tag = "type")]
160#[non_exhaustive]
161pub enum SummaryPart {
162    /// Summary text content.
163    #[serde(rename = "summary_text")]
164    SummaryText(SummaryTextContent),
165}
166
167/// Text content within a reasoning summary.
168#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
169#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
170pub struct SummaryTextContent {
171    /// The summary text.
172    pub text: String,
173}
174
175/// Reasoning text content within a reasoning item.
176#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
177#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
178pub struct ReasoningContent {
179    /// The reasoning text.
180    pub text: String,
181    /// Content type — always "reasoning_text".
182    #[serde(rename = "type")]
183    #[serde(default = "default_reasoning_text_type")]
184    pub type_: String,
185}
186
187fn default_reasoning_text_type() -> String {
188    "reasoning_text".to_string()
189}
190
191/// A function call extracted from response output.
192///
193/// Convenience struct with parsed JSON arguments.
194#[derive(Debug, Clone)]
195#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
196pub struct FunctionCall {
197    /// The call ID for matching with function_call_output.
198    pub call_id: String,
199    /// Function name.
200    pub name: String,
201    /// Parsed JSON arguments.
202    pub arguments: serde_json::Value,
203}