outfox_openai/spec/realtime/
conversation_item.rs1use serde::{Deserialize, Serialize};
2
3use crate::spec::mcp::MCPListToolsTool;
4use crate::spec::realtime::{ErrorCodeMessage, ErrorMessage};
5
6#[derive(Debug, Serialize, Deserialize, Clone)]
7pub struct SystemMessageContent {
8 pub text: String,
10 pub kind: String,
12}
13
14#[derive(Debug, Serialize, Deserialize, Clone)]
15pub struct RealtimeConversationItemMessageSystem {
16 pub content: Vec<SystemMessageContent>,
18
19 pub id: Option<String>,
21
22 pub object: Option<String>,
25
26 pub status: Option<String>,
28}
29
30#[derive(Debug, Serialize, Deserialize, Clone)]
31pub struct UserMessageContentInputText {
32 pub text: String,
34}
35
36#[derive(Debug, Serialize, Deserialize, Clone)]
37pub struct UserMessageContentInputAudio {
38 pub audio: String,
42 pub transcript: String,
45}
46
47#[derive(Debug, Serialize, Deserialize, Clone, Default)]
48#[serde(rename_all = "snake_case")]
49pub enum ImageDetail {
50 #[default]
51 Auto,
52 Low,
53 High,
54}
55
56#[derive(Debug, Serialize, Deserialize, Clone)]
57pub struct UserMessageContentInputImage {
58 pub image_url: String,
62 pub detail: ImageDetail,
64}
65
66#[derive(Debug, Serialize, Deserialize, Clone)]
67#[serde(tag = "type")]
68#[serde(rename_all = "snake_case")]
69pub enum UserMessageContent {
70 InputText(UserMessageContentInputText),
71 InputAudio(UserMessageContentInputAudio),
72 InputImage(UserMessageContentInputImage),
73}
74
75#[derive(Debug, Serialize, Deserialize, Clone)]
76pub struct RealtimeConversationItemMessageUser {
77 pub content: Vec<UserMessageContent>,
79
80 #[serde(skip_serializing_if = "Option::is_none")]
82 pub id: Option<String>,
83
84 #[serde(skip_serializing_if = "Option::is_none")]
87 pub object: Option<String>,
88
89 #[serde(skip_serializing_if = "Option::is_none")]
91 pub status: Option<String>,
92}
93
94#[derive(Debug, Serialize, Deserialize, Clone)]
95pub struct AssistantMessageContentOutputText {
96 pub text: String,
98}
99
100#[derive(Debug, Serialize, Deserialize, Clone)]
101pub struct AssistantMessageContentOutputAudio {
102 pub audio: Option<String>,
106 pub transcript: String,
109}
110
111#[derive(Debug, Serialize, Deserialize, Clone)]
112#[serde(tag = "type")]
113#[serde(rename_all = "snake_case")]
114pub enum AssistantMessageContent {
115 OutputText(AssistantMessageContentOutputText),
116 OutputAudio(AssistantMessageContentOutputAudio),
117}
118
119#[derive(Debug, Serialize, Deserialize, Clone)]
120pub struct RealtimeConversationItemMessageAssistant {
121 pub content: Vec<AssistantMessageContent>,
123
124 #[serde(skip_serializing_if = "Option::is_none")]
126 pub id: Option<String>,
127
128 #[serde(skip_serializing_if = "Option::is_none")]
131 pub object: Option<String>,
132
133 #[serde(skip_serializing_if = "Option::is_none")]
135 pub status: Option<String>,
136}
137
138#[derive(Debug, Serialize, Deserialize, Clone)]
139#[serde(tag = "role")]
140#[serde(rename_all = "lowercase")]
141pub enum RealtimeConversationItemMessage {
142 System(RealtimeConversationItemMessageSystem),
143 User(RealtimeConversationItemMessageUser),
144 Assistant(RealtimeConversationItemMessageAssistant),
145}
146
147#[derive(Debug, Serialize, Deserialize, Clone)]
148pub struct RealtimeConversationItemFunctionCall {
149 pub arguments: String,
152
153 pub name: String,
155
156 pub call_id: String,
158
159 #[serde(skip_serializing_if = "Option::is_none")]
161 pub id: Option<String>,
162
163 #[serde(skip_serializing_if = "Option::is_none")]
166 pub object: Option<String>,
167
168 pub status: String,
170}
171
172#[derive(Debug, Serialize, Deserialize, Clone)]
173pub struct RealtimeConversationItemFunctionCallOutput {
174 pub call_id: String,
176
177 pub output: String,
180
181 #[serde(skip_serializing_if = "Option::is_none")]
183 pub id: Option<String>,
184
185 #[serde(skip_serializing_if = "Option::is_none")]
188 pub object: Option<String>,
189
190 pub status: String,
192}
193
194#[derive(Debug, Serialize, Deserialize, Clone)]
195pub struct RealtimeMCPApprovalResponse {
196 pub approval_request_id: String,
198
199 pub approved: bool,
201
202 pub id: String,
204
205 pub reason: Option<String>,
207}
208
209#[derive(Debug, Serialize, Deserialize, Clone)]
210pub struct RealtimeMCPListTools {
211 pub server_label: String,
213
214 pub tools: Vec<MCPListToolsTool>,
216
217 pub id: String,
219}
220
221#[derive(Debug, Serialize, Deserialize, Clone)]
222pub struct RealtimeMCPApprovalRequest {
223 pub arguments: String,
225
226 pub id: String,
228
229 pub name: String,
231
232 pub server_label: String,
234}
235
236#[derive(Debug, Serialize, Deserialize, Clone)]
237pub struct RealtimeMCPProtocolError {}
238
239#[derive(Debug, Serialize, Deserialize, Clone)]
240#[serde(tag = "type", rename_all = "snake_case")]
241pub enum RealtimeMCPToolCallError {
242 ProtocolError(ErrorCodeMessage),
243 ToolExecutionError(ErrorMessage),
244 HttpError(ErrorCodeMessage),
245}
246
247#[derive(Debug, Serialize, Deserialize, Clone)]
248pub struct RealtimeMCPToolCall {
249 pub arguments: String,
251
252 pub id: String,
254
255 pub name: String,
257
258 pub server_label: String,
260
261 pub approval_request_id: Option<String>,
263
264 pub error: Option<RealtimeMCPToolCallError>,
266
267 pub output: Option<String>,
269}
270
271#[derive(Debug, Serialize, Deserialize, Clone)]
272#[serde(tag = "type", rename_all = "snake_case")]
273pub enum RealtimeConversationItem {
274 Message(RealtimeConversationItemMessage),
275 FunctionCall(RealtimeConversationItemFunctionCall),
276 FunctionCallOutput(RealtimeConversationItemFunctionCallOutput),
277 McpApprovalResponse(RealtimeMCPApprovalResponse),
278 McpListTools(RealtimeMCPListTools),
279 McpCall(RealtimeMCPToolCall),
280 McpApprovalRequest(RealtimeMCPApprovalRequest),
281}
282
283impl TryFrom<serde_json::Value> for RealtimeConversationItem {
284 type Error = serde_json::Error;
285
286 fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
287 serde_json::from_value(value)
288 }
289}