1use serde::{Deserialize, Serialize};
4
5use crate::prelude::*;
6
7use crate::common::Annotation;
8
9#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
11#[serde(tag = "type", rename_all = "snake_case")]
12pub enum Tool {
13 Function {
15 function: FunctionDefinition,
17 },
18 LiveSearch {
20 sources: Vec<crate::search::SearchSource>,
22 },
23}
24
25impl Default for Tool {
26 fn default() -> Self {
27 Tool::Function {
28 function: FunctionDefinition::default(),
29 }
30 }
31}
32
33#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
35pub struct FunctionDefinition {
36 pub name: String,
38
39 pub parameters: serde_json::Value,
41
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub description: Option<String>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
48 pub strict: Option<bool>,
49}
50
51#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
53pub struct ToolCall {
54 pub id: String,
56
57 pub function: Function,
59
60 #[serde(skip_serializing_if = "Option::is_none")]
62 pub index: Option<i32>,
63
64 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
66 pub tool_type: Option<String>,
67}
68
69#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
71pub struct Function {
72 pub name: String,
74
75 pub arguments: String,
77}
78
79#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
81pub struct FunctionChoice {
82 pub name: String,
84}
85
86#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
88#[serde(untagged)]
89pub enum ToolChoice {
90 Mode(String),
94 Specific {
96 #[serde(rename = "type")]
98 tool_type: String,
99 #[serde(skip_serializing_if = "Option::is_none")]
101 function: Option<FunctionChoice>,
102 },
103}
104
105impl Default for ToolChoice {
106 fn default() -> Self {
107 ToolChoice::Mode("auto".to_string())
108 }
109}
110
111#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
113pub struct FunctionToolCall {
114 #[serde(rename = "type")]
116 pub call_type: String,
117
118 pub call_id: String,
120
121 pub name: String,
123
124 pub arguments: String,
126
127 #[serde(skip_serializing_if = "Option::is_none")]
129 pub id: Option<String>,
130
131 #[serde(skip_serializing_if = "Option::is_none")]
133 pub status: Option<String>,
134}
135
136#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
138pub struct FunctionToolCallOutput {
139 #[serde(rename = "type")]
141 pub output_type: String,
142
143 pub call_id: String,
145
146 pub output: String,
148}
149
150#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
152pub struct WebSearchCall {
153 #[serde(rename = "type")]
155 pub call_type: String,
156
157 pub action: WebSearchAction,
159
160 #[serde(skip_serializing_if = "Option::is_none")]
162 pub id: Option<String>,
163
164 #[serde(skip_serializing_if = "Option::is_none")]
166 pub status: Option<String>,
167}
168
169#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
171#[serde(tag = "type", rename_all = "snake_case")]
172pub enum WebSearchAction {
173 Search {
175 query: String,
177 #[serde(skip_serializing_if = "Option::is_none")]
179 sources: Option<Vec<WebSearchSource>>,
180 },
181 OpenPage {
183 url: String,
185 },
186 Find {
188 source: WebSearchSource,
190 pattern: String,
192 },
193}
194
195impl Default for WebSearchAction {
196 fn default() -> Self {
197 WebSearchAction::Search {
198 query: String::new(),
199 sources: None,
200 }
201 }
202}
203
204#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
206pub struct WebSearchSource {
207 #[serde(rename = "type")]
209 pub source_type: String,
210
211 #[serde(skip_serializing_if = "Option::is_none")]
213 pub url: Option<String>,
214}
215
216#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
218pub struct WebSearchOptions {
219 #[serde(skip_serializing_if = "Option::is_none")]
221 pub search_context_size: Option<String>,
222
223 #[serde(skip_serializing_if = "Option::is_none")]
225 pub filters: Option<serde_json::Value>,
226
227 #[serde(skip_serializing_if = "Option::is_none")]
229 pub user_location: Option<serde_json::Value>,
230}
231
232#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
234pub struct WebSearchFilters {
235 #[serde(skip_serializing_if = "Option::is_none")]
237 pub allowed_domains: Option<Vec<String>>,
238
239 #[serde(skip_serializing_if = "Option::is_none")]
241 pub excluded_domains: Option<Vec<String>>,
242}
243
244#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
246pub struct FileSearchCall {
247 #[serde(rename = "type")]
249 pub call_type: String,
250
251 pub queries: Vec<String>,
253
254 pub results: Vec<FileSearchResult>,
256
257 #[serde(skip_serializing_if = "Option::is_none")]
259 pub id: Option<String>,
260
261 #[serde(skip_serializing_if = "Option::is_none")]
263 pub status: Option<String>,
264}
265
266#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
268pub struct FileSearchResult {
269 pub file_id: String,
271
272 pub filename: String,
274
275 pub score: f64,
277
278 pub text: String,
280}
281
282#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
284pub struct CodeInterpreterCall {
285 #[serde(rename = "type")]
287 pub call_type: String,
288
289 pub outputs: Vec<CodeInterpreterOutput>,
291
292 #[serde(skip_serializing_if = "Option::is_none")]
294 pub code: Option<String>,
295
296 #[serde(skip_serializing_if = "Option::is_none")]
298 pub id: Option<String>,
299
300 #[serde(skip_serializing_if = "Option::is_none")]
302 pub status: Option<String>,
303}
304
305#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
307#[serde(tag = "type", rename_all = "snake_case")]
308pub enum CodeInterpreterOutput {
309 Logs {
311 logs: String,
313 },
314 Image {
316 url: String,
318 },
319}
320
321impl Default for CodeInterpreterOutput {
322 fn default() -> Self {
323 CodeInterpreterOutput::Logs {
324 logs: String::new(),
325 }
326 }
327}
328
329#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
331pub struct McpCall {
332 #[serde(rename = "type")]
334 pub call_type: String,
335
336 pub name: String,
338
339 pub server_label: String,
341
342 pub arguments: String,
344
345 pub output: String,
347
348 #[serde(skip_serializing_if = "Option::is_none")]
350 pub id: Option<String>,
351
352 #[serde(skip_serializing_if = "Option::is_none")]
354 pub error: Option<String>,
355
356 #[serde(skip_serializing_if = "Option::is_none")]
358 pub status: Option<String>,
359}
360
361#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
363pub struct CustomToolCall {
364 #[serde(rename = "type")]
366 pub call_type: String,
367
368 pub call_id: String,
370
371 pub name: String,
373
374 pub id: String,
376
377 #[serde(skip_serializing_if = "Option::is_none")]
379 pub input: Option<String>,
380
381 #[serde(skip_serializing_if = "Option::is_none")]
383 pub status: Option<String>,
384}
385
386#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
388#[serde(tag = "type", rename_all = "snake_case")]
389pub enum ModelTool {
390 Function {
392 name: String,
394 parameters: serde_json::Value,
396 #[serde(skip_serializing_if = "Option::is_none")]
398 description: Option<String>,
399 #[serde(skip_serializing_if = "Option::is_none")]
401 strict: Option<bool>,
402 },
403 WebSearch {
405 #[serde(skip_serializing_if = "Option::is_none")]
407 allowed_domains: Option<Vec<String>>,
408 #[serde(skip_serializing_if = "Option::is_none")]
410 excluded_domains: Option<Vec<String>>,
411 #[serde(skip_serializing_if = "Option::is_none")]
413 enable_image_understanding: Option<bool>,
414 #[serde(skip_serializing_if = "Option::is_none")]
416 external_web_access: Option<bool>,
417 #[serde(skip_serializing_if = "Option::is_none")]
419 filters: Option<WebSearchFilters>,
420 #[serde(skip_serializing_if = "Option::is_none")]
422 search_context_size: Option<String>,
423 #[serde(skip_serializing_if = "Option::is_none")]
425 user_location: Option<serde_json::Value>,
426 },
427 XSearch {
429 #[serde(skip_serializing_if = "Option::is_none")]
431 allowed_x_handles: Option<Vec<String>>,
432 #[serde(skip_serializing_if = "Option::is_none")]
434 excluded_x_handles: Option<Vec<String>>,
435 #[serde(skip_serializing_if = "Option::is_none")]
437 enable_image_understanding: Option<bool>,
438 #[serde(skip_serializing_if = "Option::is_none")]
440 enable_video_understanding: Option<bool>,
441 #[serde(skip_serializing_if = "Option::is_none")]
443 from_date: Option<String>,
444 #[serde(skip_serializing_if = "Option::is_none")]
446 to_date: Option<String>,
447 },
448 FileSearch {
450 vector_store_ids: Vec<String>,
452 #[serde(skip_serializing_if = "Option::is_none")]
454 max_num_results: Option<i32>,
455 #[serde(skip_serializing_if = "Option::is_none")]
457 filters: Option<serde_json::Value>,
458 #[serde(skip_serializing_if = "Option::is_none")]
460 ranking_options: Option<serde_json::Value>,
461 },
462 CodeInterpreter {
464 #[serde(skip_serializing_if = "Option::is_none")]
466 container: Option<serde_json::Value>,
467 },
468 Mcp {
470 server_label: String,
472 server_url: String,
474 #[serde(skip_serializing_if = "Option::is_none")]
476 allowed_tools: Option<Vec<String>>,
477 #[serde(skip_serializing_if = "Option::is_none")]
479 authorization: Option<String>,
480 #[serde(skip_serializing_if = "Option::is_none")]
482 connector_id: Option<String>,
483 #[serde(skip_serializing_if = "Option::is_none")]
485 headers: Option<HashMap<String, String>>,
486 #[serde(skip_serializing_if = "Option::is_none")]
488 require_approval: Option<String>,
489 #[serde(skip_serializing_if = "Option::is_none")]
491 server_description: Option<String>,
492 },
493}
494
495impl Default for ModelTool {
496 fn default() -> Self {
497 ModelTool::Function {
498 name: String::new(),
499 parameters: serde_json::Value::Null,
500 description: None,
501 strict: None,
502 }
503 }
504}
505
506#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
508#[serde(untagged)]
509pub enum ModelToolChoice {
510 Mode(String),
512 Specific {
514 #[serde(rename = "type")]
516 tool_type: String,
517 name: String,
519 },
520}
521
522impl Default for ModelToolChoice {
523 fn default() -> Self {
524 ModelToolChoice::Mode("auto".to_string())
525 }
526}
527
528#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
530pub struct OutputText {
531 #[serde(rename = "type")]
533 pub output_type: String,
534
535 pub text: String,
537
538 pub annotations: Vec<Annotation>,
540
541 #[serde(skip_serializing_if = "Option::is_none")]
543 pub logprobs: Option<Vec<crate::chat::TokenLogProb>>,
544}
545
546#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
548pub struct OutputRefusal {
549 #[serde(rename = "type")]
551 pub output_type: String,
552
553 pub refusal: String,
555}
556
557#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
559#[serde(tag = "type", rename_all = "snake_case")]
560pub enum OutputMessageContent {
561 OutputText {
563 text: String,
565 annotations: Vec<Annotation>,
567 #[serde(skip_serializing_if = "Option::is_none")]
569 logprobs: Option<Vec<crate::chat::TokenLogProb>>,
570 },
571 Refusal {
573 refusal: String,
575 },
576}
577
578impl Default for OutputMessageContent {
579 fn default() -> Self {
580 OutputMessageContent::OutputText {
581 text: String::new(),
582 annotations: Vec::new(),
583 logprobs: None,
584 }
585 }
586}