1#![allow(missing_docs)]
4
5use crate::_prelude::*;
7
8#[derive(Clone, Debug, Serialize, Deserialize)]
9pub struct ResponseMessage<T> {
10 pub content: T,
11 pub role: Role,
12}
13
14#[derive(Clone, Debug, Serialize, Deserialize)]
15pub struct ResponseOutputMessage {
16 #[serde(flatten)]
17 pub message: ResponseMessage<Vec<ResponseMessageOutputContent>>,
18 pub id: String,
19 pub status: Status3,
20}
21
22#[derive(Clone, Debug, Serialize, Deserialize)]
23#[serde(tag = "type", rename_all = "snake_case")]
24pub enum ResponseMessageOutputContent {
25 OutputText {
26 annotations: Vec<Annotation>,
27 text: String,
28 #[serde(skip_serializing_if = "Option::is_none")]
29 logprobs: Option<Vec<Logprobs>>,
30 },
31 Refusal(Refusal),
32}
33
34#[derive(Clone, Debug, Serialize, Deserialize)]
35#[serde(tag = "type", rename_all = "snake_case")]
36pub enum Annotation {
37 FileCitation {
38 file_id: String,
39 index: u32,
40 },
41 UrlCitation {
42 end_index: u32,
43 start_index: u32,
44 title: String,
45 url: String,
46 },
47 ContainerFileCitation {
48 container_id: String,
49 end_index: u32,
50 file_id: String,
51 start_index: u32,
52 },
53 FilePath {
54 file_id: String,
55 index: u32,
56 },
57}
58
59#[derive(Clone, Debug, Serialize, Deserialize)]
60pub struct Refusal {
61 pub refusal: String,
62}
63
64impl_serializable_deserializable_enum! {
65 Status3 {
66 InProgress => "in_progress",
67 Completed => "completed",
68 Incomplete => "incomplete",
69 }
70}
71impl Status3 {
72 pub fn in_progress(&self) -> bool {
73 matches!(self, Self::InProgress)
74 }
75
76 pub fn completed(&self) -> bool {
77 matches!(self, Self::Completed)
78 }
79
80 pub fn incomplete(&self) -> bool {
81 matches!(self, Self::Incomplete)
82 }
83}
84
85#[derive(Clone, Debug, Serialize, Deserialize)]
86pub struct FileSearchCall {
87 pub id: String,
88 pub queries: Vec<String>,
89 pub status: FileSearchToolCallStatus,
90 #[serde(skip_serializing_if = "Option::is_none")]
91 pub results: Option<Vec<FileSearchToolCallResult>>,
92}
93
94impl_serializable_deserializable_enum! {
95 FileSearchToolCallStatus {
96 InProgress => "in_progress",
97 Searching => "searching",
98 Incomplete => "incomplete",
99 Failed => "failed",
100 }
101}
102
103#[derive(Clone, Debug, Serialize, Deserialize)]
104pub struct FileSearchToolCallResult {
105 #[serde(skip_serializing_if = "Option::is_none")]
106 pub attributes: Option<Map>,
107 #[serde(skip_serializing_if = "Option::is_none")]
108 pub file_id: Option<String>,
109 #[serde(skip_serializing_if = "Option::is_none")]
110 pub filename: Option<String>,
111 #[serde(skip_serializing_if = "Option::is_none")]
112 pub score: Option<f32>,
113 #[serde(skip_serializing_if = "Option::is_none")]
114 pub text: Option<String>,
115}
116
117#[derive(Clone, Debug, Serialize, Deserialize)]
118pub struct ComputerCall {
119 pub action: ComputerToolCallAction,
120 pub call_id: String,
121 pub id: String,
122 pub pending_safety_checks: Vec<PendingSafetyCheck>,
123 pub status: Status3,
124}
125
126#[derive(Clone, Debug, Serialize, Deserialize)]
127#[serde(tag = "type", rename_all = "snake_case")]
128pub enum ComputerToolCallAction {
129 Click {
130 button: Button,
131 #[serde(flatten)]
132 coordinate: Coordinate,
133 },
134 DoubleClick {
135 #[serde(flatten)]
136 coordinate: Coordinate,
137 },
138 Drag {
139 path: Vec<Coordinate>,
140 },
141 Keypress {
142 keys: Vec<String>,
144 },
145 Move {
146 #[serde(flatten)]
147 coordinate: Coordinate,
148 },
149 Screenshot,
150 Scroll {
151 scroll_x: i32,
152 scroll_y: i32,
153 #[serde(flatten)]
154 coordinate: Coordinate,
155 },
156 Type {
157 text: String,
158 },
159 Wait,
160}
161
162impl_serializable_deserializable_enum! {
163 Button {
164 Left => "left",
165 Right => "right",
166 Wheel => "wheel",
167 Back => "back",
168 Forward => "forward",
169 }
170}
171
172#[derive(Clone, Debug, Serialize, Deserialize)]
173pub struct Coordinate {
174 pub x: u32,
175 pub y: u32,
176}
177
178#[derive(Clone, Debug, Serialize, Deserialize)]
179pub struct PendingSafetyCheck {
180 pub code: String,
181 pub id: String,
182 pub message: String,
183}
184
185#[derive(Clone, Debug, Serialize, Deserialize)]
186pub struct WebSearchCall {
187 pub id: String,
188 pub status: String,
189}
190
191#[derive(Clone, Debug, Serialize, Deserialize)]
192pub struct FunctionCall {
193 pub arguments: Value,
194 pub call_id: String,
195 pub name: String,
196 #[serde(skip_serializing_if = "Option::is_none")]
197 pub id: Option<String>,
198 #[serde(skip_serializing_if = "Option::is_none")]
199 pub status: Option<Status3>,
200}
201
202#[derive(Clone, Debug, Serialize, Deserialize)]
203pub struct ReasoningItem {
204 pub id: String,
205 pub summary: Vec<SummaryText>,
206 #[serde(skip_serializing_if = "Option::is_none")]
207 pub encrypted_content: Option<String>,
208 #[serde(skip_serializing_if = "Option::is_none")]
209 pub status: Option<Status3>,
210}
211
212#[derive(Clone, Debug, Serialize, Deserialize)]
213pub struct SummaryText {
214 pub text: String,
215 pub r#type: ConstSummaryText,
216}
217
218impl_const_str! {
219 SummaryText => "summary_text",
220}
221
222#[derive(Clone, Debug, Serialize, Deserialize)]
223pub struct ImageGenerationCall {
224 pub id: String,
225 pub result: Option<String>,
227 pub status: String,
228}
229
230#[derive(Clone, Debug, Serialize, Deserialize)]
231pub struct CodeInterpreterCall {
232 pub code: String,
233 pub id: String,
234 pub results: Vec<CodeInterpreterCallOutput>,
235 pub status: String,
236 #[serde(skip_serializing_if = "Option::is_none")]
237 pub container_id: Option<String>,
238}
239
240#[derive(Clone, Debug, Serialize, Deserialize)]
241#[serde(tag = "type", rename_all = "snake_case")]
242pub enum CodeInterpreterCallOutput {
243 Logs { logs: String },
244 Files { files: Vec<FileOutput> },
245}
246
247#[derive(Clone, Debug, Serialize, Deserialize)]
248pub struct FileOutput {
249 pub file_id: String,
250 pub mime_type: String,
251}
252
253#[derive(Clone, Debug, Serialize, Deserialize)]
254pub struct LocalShellCall {
255 pub action: ShellAction,
256 pub call_id: String,
257 pub id: String,
258 pub status: String,
259}
260
261#[derive(Clone, Debug, Serialize, Deserialize)]
262pub struct ShellAction {
263 pub command: Vec<String>,
264 pub env: Value,
265 pub r#type: ConstExec,
266 #[serde(skip_serializing_if = "Option::is_none")]
267 pub timeout_ms: Option<u64>,
268 #[serde(skip_serializing_if = "Option::is_none")]
269 pub user: Option<String>,
270 #[serde(skip_serializing_if = "Option::is_none")]
271 pub working_directory: Option<String>,
272}
273
274impl_const_str! {
275 Exec => "exec",
276}
277
278#[derive(Clone, Debug, Serialize, Deserialize)]
279pub struct McpListTools {
280 pub id: String,
281 pub server_label: String,
282 pub tools: Vec<ToolInfo>,
283 #[serde(skip_serializing_if = "Option::is_none")]
284 pub error: Option<String>,
285}
286
287#[derive(Clone, Debug, Serialize, Deserialize)]
288pub struct ToolInfo {
289 pub input_schema: Value,
290 pub name: String,
291 #[serde(skip_serializing_if = "Option::is_none")]
292 pub annotations: Option<Value>,
293 #[serde(skip_serializing_if = "Option::is_none")]
294 pub description: Option<String>,
295}
296
297#[derive(Clone, Debug, Serialize, Deserialize)]
298pub struct McpApprovalRequest {
299 pub arguments: Value,
300 pub id: String,
301 pub name: String,
302 pub server_label: String,
303}
304
305#[derive(Clone, Debug, Serialize, Deserialize)]
306pub struct McpCall {
307 pub arguments: Value,
308 pub id: String,
309 pub name: String,
310 pub server_label: String,
311 #[serde(skip_serializing_if = "Option::is_none")]
312 pub error: Option<String>,
313 #[serde(skip_serializing_if = "Option::is_none")]
314 pub output: Option<String>,
315}
316
317#[derive(Clone, Debug, Serialize, Deserialize)]
318pub struct Reasoning {
319 #[serde(skip_serializing_if = "Option::is_none")]
320 pub effort: Option<ReasoningEffort>,
321 #[serde(skip_serializing_if = "Option::is_none")]
322 pub summary: Option<Summary>,
323}
324
325impl_serializable_deserializable_enum! {
326 Summary {
327 Auto => "auto",
328 Concise => "concise",
329 Detailed => "detailed"
330 }
331}
332
333#[derive(Clone, Debug, Serialize, Deserialize)]
334pub struct Text {
335 #[serde(skip_serializing_if = "Option::is_none")]
336 pub format: Option<ResponseTextFormat>,
337}
338
339#[derive(Clone, Debug, Serialize, Deserialize)]
340#[serde(tag = "type", rename_all = "snake_case")]
341pub enum ResponseTextFormat {
342 Text,
343 JsonSchema {
344 name: String,
345 schema: Value,
346 #[serde(skip_serializing_if = "Option::is_none")]
347 description: Option<String>,
348 #[serde(skip_serializing_if = "Option::is_none")]
349 strict: Option<bool>,
350 },
351 JsonObject,
352}
353
354#[derive(Clone, Debug, Serialize, Deserialize)]
355#[serde(untagged)]
356pub enum ToolChoice {
357 Mode(ToolChoiceMode),
358 HostedTool { r#type: HostedTool },
359 FunctionTool { name: String, r#type: ConstFunction },
360}
361
362impl_serializable_deserializable_enum! {
363 ToolChoiceMode {
364 None => "none",
365 Auto => "auto",
366 Required => "required",
367 }
368}
369
370impl_serializable_deserializable_enum! {
371 HostedTool {
372 FileSearch => "file_search",
373 WebSearchPreview => "web_search_preview",
374 WebSearchPreview20250311 => "web_search_preview_2025_03_11",
375 ComputerUsePreview => "computer_use_preview",
376 CodeInterpreter => "code_interpreter",
377 Mcp => "mcp",
378 ImageGeneration => "image_generation",
379 }
380}
381
382#[derive(Clone, Debug, Serialize, Deserialize)]
383#[serde(tag = "type", rename_all = "snake_case")]
384pub enum Tool {
385 Function {
386 name: String,
387 parameters: Value,
388 strict: bool,
389 #[serde(skip_serializing_if = "Option::is_none")]
390 description: Option<String>,
391 },
392 FileSearch {
393 vector_store_ids: Vec<String>,
394 #[serde(skip_serializing_if = "Option::is_none")]
395 filters: Option<FileSearchFilters>,
396 #[serde(skip_serializing_if = "Option::is_none")]
397 max_num_results: Option<u32>,
398 #[serde(skip_serializing_if = "Option::is_none")]
399 ranking_options: Option<RankingOptions>,
400 },
401 WebSearchPreview {
402 #[serde(skip_serializing_if = "Option::is_none")]
403 search_context_size: Option<SearchContextSize>,
404 #[serde(skip_serializing_if = "Option::is_none")]
405 user_location: Option<Location>,
406 },
407 ComputerUsePreview {
408 display_height: u32,
409 display_width: u32,
410 environment: String,
411 },
412 Mcp {
413 server_label: String,
414 server_url: String,
415 #[serde(skip_serializing_if = "Option::is_none")]
416 allowed_tools: Option<Either<Vec<String>, McpFilter>>,
417 #[serde(skip_serializing_if = "Option::is_none")]
418 headers: Option<Value>,
419 #[serde(skip_serializing_if = "Option::is_none")]
420 require_approval: Option<Either<McpApprovalFilter, McpApprovalSetting>>,
421 },
422 CodeInterpreter {
423 container: Either<String, CodeInterpreterContainer>,
424 },
425 ImageGeneration {
426 #[serde(skip_serializing_if = "Option::is_none")]
427 background: Option<ImageBackground>,
428 #[serde(skip_serializing_if = "Option::is_none")]
429 input_image_mask: Option<InputImageMask>,
430 #[serde(skip_serializing_if = "Option::is_none")]
431 model: Option<Model>,
432 #[serde(skip_serializing_if = "Option::is_none")]
433 moderation: Option<String>,
434 #[serde(skip_serializing_if = "Option::is_none")]
435 output_compression: Option<u8>,
436 #[serde(skip_serializing_if = "Option::is_none")]
437 output_format: Option<ImageFormat>,
438 #[serde(skip_serializing_if = "Option::is_none")]
439 partial_images: Option<u8>,
440 #[serde(skip_serializing_if = "Option::is_none")]
441 quality: Option<ImageQuality>,
442 #[serde(skip_serializing_if = "Option::is_none")]
443 size: Option<ImageSize>,
444 },
445 LocalShell,
446}
447
448#[derive(Clone, Debug, Serialize, Deserialize)]
449#[serde(tag = "type", rename_all = "snake_case")]
450pub enum FileSearchFilters {
451 Eq(ComparisonFilter),
452 Ne(ComparisonFilter),
453 Gt(ComparisonFilter),
454 Gte(ComparisonFilter),
455 Lt(ComparisonFilter),
456 Lte(ComparisonFilter),
457 And { filters: Vec<FileSearchFilters> },
458 Or { filters: Vec<FileSearchFilters> },
459}
460
461#[derive(Clone, Debug, Serialize, Deserialize)]
462pub struct ComparisonFilter {
463 pub key: String,
464 pub value: ComparisonValue,
465}
466
467#[derive(Clone, Debug, Serialize, Deserialize)]
468#[serde(untagged)]
469pub enum ComparisonValue {
470 String(String),
471 Number(f64),
472 Boolean(bool),
473}
474
475#[derive(Clone, Debug, Serialize, Deserialize)]
476pub struct RankingOptions {
477 #[serde(skip_serializing_if = "Option::is_none")]
478 pub ranker: Option<String>,
479 #[serde(skip_serializing_if = "Option::is_none")]
480 pub score_threshold: Option<f32>,
481}
482
483impl_serializable_deserializable_enum! {
484 SearchContextSize {
485 Low => "low",
486 Medium => "medium",
487 High => "high",
488 }
489}
490
491#[derive(Clone, Debug, Serialize, Deserialize)]
492pub struct Location {
493 pub r#type: ConstApproximate,
494 #[serde(skip_serializing_if = "Option::is_none")]
495 pub city: Option<String>,
496 #[serde(skip_serializing_if = "Option::is_none")]
498 pub country: Option<String>,
499 #[serde(skip_serializing_if = "Option::is_none")]
500 pub region: Option<String>,
501 #[serde(skip_serializing_if = "Option::is_none")]
502 pub timezone: Option<String>,
503}
504
505impl_const_str! {
506 Approximate => "approximate",
507}
508
509#[derive(Clone, Debug, Serialize, Deserialize)]
510pub struct McpFilter {
511 #[serde(skip_serializing_if = "Option::is_none")]
512 pub tool_names: Option<Vec<String>>,
513}
514
515#[derive(Clone, Debug, Serialize, Deserialize)]
516pub struct McpApprovalFilter {
517 #[serde(skip_serializing_if = "Option::is_none")]
518 pub always: Option<McpFilter>,
519 #[serde(skip_serializing_if = "Option::is_none")]
520 pub never: Option<McpFilter>,
521}
522
523impl_serializable_deserializable_enum! {
524 McpApprovalSetting {
525 Always => "always",
526 Never => "never",
527 }
528}
529
530#[derive(Clone, Debug, Serialize, Deserialize)]
531pub struct CodeInterpreterContainer {
532 pub r#type: ConstAuto,
533 #[serde(skip_serializing_if = "Option::is_none")]
534 pub file_ids: Option<Vec<String>>,
535}
536
537impl_const_str! {
538 Auto => "auto",
539}
540
541impl_serializable_deserializable_enum! {
542 ImageBackground {
543 Transparent => "transparent",
544 Opaque => "opaque",
545 Auto => "auto",
546 }
547}
548
549#[derive(Clone, Debug, Serialize, Deserialize)]
550pub struct InputImageMask {
551 #[serde(skip_serializing_if = "Option::is_none")]
552 pub file_id: Option<String>,
553 #[serde(skip_serializing_if = "Option::is_none")]
554 pub image_url: Option<String>,
555}
556
557impl_serializable_deserializable_enum! {
558 ImageFormat {
559 Png => "png",
560 Webp => "webp",
561 Jpeg => "jpeg",
562 }
563}
564
565impl_serializable_deserializable_enum! {
566 ImageQuality {
567 Low => "low",
568 Medium => "medium",
569 High => "high",
570 Auto => "auto",
571 }
572}
573
574impl_serializable_deserializable_enum! {
575 ImageSize {
576 W1024H1024 => "1024x1024",
577 W1024H1536 => "1024x1536",
578 W1536H1024 => "1536x1024",
579 Auto => "auto",
580 }
581}
582
583impl_serializable_deserializable_enum! {
584 Truncation {
585 Auto => "auto",
586 Disabled => "disabled",
587 }
588}