allms/
domain.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5use crate::enums::{OpenAIAssistantRole, OpenAIRunStatus, OpenAIToolTypes};
6
7//OpenAI API response type format for Completions API
8#[derive(Deserialize, Serialize, Debug, Clone)]
9pub struct OpenAPICompletionsResponse {
10    pub id: Option<String>,
11    pub object: Option<String>,
12    pub created: Option<u32>,
13    pub model: Option<String>,
14    pub choices: Option<Vec<OpenAPICompletionsChoices>>,
15    pub usage: Option<OpenAPIUsage>,
16}
17
18#[derive(Deserialize, Serialize, Debug, Clone)]
19pub struct OpenAPICompletionsChoices {
20    pub text: Option<String>,
21    pub index: Option<u32>,
22    pub logprobs: Option<u32>,
23    pub finish_reason: Option<String>,
24}
25
26//OpenAI API response type format for Chat API
27#[derive(Deserialize, Serialize, Debug, Clone)]
28pub struct OpenAPIChatResponse {
29    pub id: Option<String>,
30    pub object: Option<String>,
31    pub created: Option<u32>,
32    pub model: Option<String>,
33    pub choices: Option<Vec<OpenAPIChatChoices>>,
34    pub usage: Option<OpenAPIUsage>,
35}
36
37#[derive(Deserialize, Serialize, Debug, Clone)]
38pub struct OpenAPIChatChoices {
39    pub message: OpenAPIChatMessage,
40    pub index: Option<u32>,
41    pub finish_reason: Option<String>,
42}
43
44#[derive(Deserialize, Serialize, Debug, Clone)]
45pub struct OpenAPIChatMessage {
46    pub role: String,
47    pub content: Option<String>,
48    pub function_call: Option<OpenAPIChatFunctionCall>,
49}
50
51#[derive(Deserialize, Serialize, Debug, Clone)]
52pub struct OpenAPIChatFunctionCall {
53    pub(crate) name: String,
54    pub(crate) arguments: String,
55}
56
57#[derive(Deserialize, Serialize, Debug, Clone)]
58pub struct OpenAPIUsage {
59    prompt_tokens: Option<u32>,
60    completion_tokens: Option<u32>,
61    total_tokens: Option<u32>,
62}
63
64#[derive(Deserialize, Serialize, Debug, Clone)]
65pub struct RateLimit {
66    pub tpm: usize, // tokens-per-minute
67    pub rpm: usize, // requests-per-minute
68}
69
70#[derive(Deserialize, Serialize, Debug, Clone, JsonSchema)]
71pub struct OpenAIDataResponse<T: JsonSchema> {
72    pub data: T,
73}
74
75#[derive(Deserialize, Serialize, Debug, Clone)]
76pub struct OpenAIAssistantResp {
77    pub id: String,
78    pub object: String,
79    pub created_at: u32,
80    pub name: Option<String>,
81    pub description: Option<String>,
82    pub instructions: Option<String>,
83    pub model: String,
84    pub tools: Vec<OpenAITools>,
85    pub file_ids: Option<Vec<String>>,
86}
87
88#[derive(Deserialize, Serialize, Debug, Clone)]
89pub struct OpenAITools {
90    #[serde(rename(deserialize = "type", serialize = "type"))]
91    tool_type: OpenAIToolTypes,
92}
93
94#[derive(Deserialize, Serialize, Debug, Clone)]
95pub struct OpenAIThreadResp {
96    pub id: String,
97    pub object: String,
98    pub created_at: u32,
99}
100
101#[derive(Deserialize, Serialize, Debug, Clone)]
102pub struct OpenAIMessageListResp {
103    pub object: String,
104    pub data: Vec<OpenAIMessageResp>,
105}
106
107#[derive(Deserialize, Serialize, Debug, Clone)]
108pub struct OpenAIMessageResp {
109    pub id: String,
110    pub object: String,
111    pub created_at: u32,
112    pub thread_id: String,
113    pub role: OpenAIAssistantRole,
114    pub content: Vec<OpenAIContent>,
115    pub attachments: Option<Vec<OpenAIMessageAttachment>>,
116    //Other fields omitted as no use for now
117}
118
119#[derive(Deserialize, Serialize, Debug, Clone)]
120pub struct OpenAIContent {
121    #[serde(rename(deserialize = "type", serialize = "type"))]
122    pub content_type: String,
123    pub text: Option<OpenAIContentText>,
124}
125
126#[derive(Deserialize, Serialize, Debug, Clone)]
127pub struct OpenAIContentText {
128    pub value: String,
129}
130
131#[derive(Deserialize, Serialize, Debug, Clone)]
132pub struct OpenAIMessageAttachment {
133    pub file_id: String,
134    pub tools: Vec<OpenAIMessageAttachmentTools>,
135}
136
137#[derive(Deserialize, Serialize, Debug, Clone)]
138pub struct OpenAIMessageAttachmentTools {
139    #[serde(rename(deserialize = "type", serialize = "type"))]
140    pub tool_type: OpenAIToolTypes,
141}
142
143#[derive(Deserialize, Serialize, Debug, Clone)]
144pub struct OpenAIRunResp {
145    pub id: String,
146    pub object: String,
147    pub created_at: u32,
148    pub status: OpenAIRunStatus,
149}
150
151//Anthropic API response type format for Text Completions API
152#[derive(Deserialize, Serialize, Debug, Clone)]
153pub struct AnthropicAPICompletionsResponse {
154    pub id: String,
155    #[serde(rename(deserialize = "type", serialize = "type"))]
156    pub request_type: String,
157    pub completion: String,
158    pub stop_reason: String,
159    pub model: String,
160}
161
162//Anthropic API response type format for Messages API
163#[derive(Deserialize, Serialize, Debug, Clone)]
164pub struct AnthropicAPIMessagesResponse {
165    pub id: String,
166    #[serde(rename(deserialize = "type", serialize = "type"))]
167    pub request_type: String,
168    pub role: String,
169    pub content: Vec<AnthropicAPIMessagesContent>,
170    pub model: String,
171    pub stop_reason: Option<String>,
172    pub stop_sequence: Option<String>,
173    pub usage: AnthropicAPIMessagesUsage,
174}
175
176#[derive(Deserialize, Serialize, Debug, Clone)]
177pub struct AnthropicAPIMessagesContent {
178    #[serde(rename(deserialize = "type", serialize = "type"))]
179    pub content_type: String,
180    pub text: Option<String>,
181}
182
183#[derive(Deserialize, Serialize, Debug, Clone)]
184pub struct AnthropicAPIMessagesUsage {
185    pub input_tokens: i32,
186    pub output_tokens: i32,
187}
188
189//Mistral API response type format for Chat Completions API
190#[derive(Deserialize, Serialize, Debug, Clone)]
191pub struct MistralAPICompletionsResponse {
192    pub id: Option<String>,
193    pub object: Option<String>,
194    pub created: Option<usize>,
195    pub model: Option<String>,
196    pub choices: Vec<MistralAPICompletionsChoices>,
197    pub usage: Option<MistralAPICompletionsUsage>,
198}
199
200//Mistral API response type format for Chat Completions API
201#[derive(Deserialize, Serialize, Debug, Clone)]
202pub struct MistralAPICompletionsChoices {
203    pub index: usize,
204    pub message: Option<MistralAPICompletionsMessage>,
205    pub finish_reason: String,
206}
207
208//Mistral API response type format for Chat Completions API
209#[derive(Deserialize, Serialize, Debug, Clone)]
210pub struct MistralAPICompletionsMessage {
211    pub role: Option<String>,
212    pub content: Option<String>,
213}
214
215//Mistral API response type format for Chat Completions API
216#[derive(Deserialize, Serialize, Debug, Clone)]
217pub struct MistralAPICompletionsUsage {
218    pub prompt_tokens: usize,
219    pub completion_tokens: usize,
220    pub total_tokens: usize,
221}
222
223// Mistral Agents API response type format
224#[derive(Deserialize, Serialize, Debug, Clone)]
225pub struct MistralAPIConversationsResponse {
226    pub conversation_id: String,
227    pub object: String,
228    pub outputs: Vec<MistralAPIConversationsOutput>,
229    pub usage: Option<MistralAPIConversationsUsage>,
230}
231
232/// Mistral Conversations API output entry types
233/// Can be MessageOutputEntry | ToolExecutionEntry | FunctionCallEntry | AgentHandoffEntry
234#[derive(Deserialize, Serialize, Debug, Clone)]
235#[serde(tag = "type")]
236#[allow(clippy::large_enum_variant)]
237pub enum MistralAPIConversationsOutput {
238    #[serde(rename = "message.output")]
239    MistralAPIConversationsMessageOutput(MistralAPIConversationsMessageOutput),
240    #[serde(rename = "tool.execution")]
241    MistralAPIConversationsToolExecution(MistralAPIConversationsToolExecution),
242    // TODO: Add other entry types when needed
243    // MistralAPIConversationsFunctionCall(MistralAPIConversationsFunctionCall),
244    // MistralAPIConversationsAgentHandoff(MistralAPIConversationsAgentHandoff),
245}
246
247/// MessageOutputEntry for Mistral Conversations API
248#[derive(Deserialize, Serialize, Debug, Clone)]
249pub struct MistralAPIConversationsMessageOutput {
250    pub object: Option<String>,
251    #[serde(rename = "type", skip_deserializing)]
252    pub entry_type: Option<String>,
253    pub role: Option<String>,
254    pub id: Option<String>,
255    pub created_at: Option<String>,
256    pub agent_id: Option<String>,
257    pub completed_at: Option<String>,
258    pub model: Option<String>,
259    pub content: Option<MistralAPIConversationsMessageOutputContent>,
260}
261
262/// Content can be a string or array of chunk types (TextChunk, ImageURLChunk, etc.)
263#[derive(Deserialize, Serialize, Debug, Clone)]
264#[serde(untagged)]
265pub enum MistralAPIConversationsMessageOutputContent {
266    MistralAPIConversationsMessageOutputContentString(String),
267    MistralAPIConversationsMessageOutputContentChunks(Vec<MistralAPIConversationsChunk>),
268}
269
270/// Chunk types for Mistral Conversations API content
271#[derive(Deserialize, Serialize, Debug, Clone)]
272#[serde(tag = "type", rename_all = "snake_case")]
273pub enum MistralAPIConversationsChunk {
274    #[serde(rename = "text")]
275    MistralAPIConversationsChunkText(MistralAPIConversationsChunkText),
276    // TODO: Add other chunk types when needed
277    // ImageURL(ImageURLChunk),
278    // ToolFile(ToolFileChunk),
279    // DocumentURL(DocumentURLChunk),
280    // Think(ThinkChunk),
281    // ToolReference(ToolReferenceChunk),
282}
283
284/// TextChunk for Mistral Conversations API
285#[derive(Deserialize, Serialize, Debug, Clone)]
286pub struct MistralAPIConversationsChunkText {
287    pub text: String,
288    #[serde(rename = "type")]
289    #[serde(default = "default_text_chunk_type")]
290    pub chunk_type: String,
291}
292
293fn default_text_chunk_type() -> String {
294    "text".to_string()
295}
296
297/// ToolExecutionEntry for Mistral Conversations API
298#[derive(Deserialize, Serialize, Debug, Clone)]
299pub struct MistralAPIConversationsToolExecution {
300    pub arguments: String,
301    pub completed_at: Option<String>,
302    pub created_at: String,
303    pub id: String,
304    pub info: Value,
305    pub name: MistralAPIConversationsToolName,
306    #[serde(default = "default_entry_object")]
307    pub object: String,
308    #[serde(
309        rename = "type",
310        skip_deserializing,
311        default = "default_tool_execution_type"
312    )]
313    pub entry_type: String,
314    pub function: Option<String>,
315}
316
317/// Tool name enum for Mistral Conversations API
318#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
319#[serde(rename_all = "snake_case")]
320pub enum MistralAPIConversationsToolName {
321    #[serde(rename = "web_search")]
322    WebSearch,
323    #[serde(rename = "web_search_premium")]
324    WebSearchPremium,
325    #[serde(rename = "code_interpreter")]
326    CodeInterpreter,
327    #[serde(rename = "image_generation")]
328    ImageGeneration,
329    #[serde(rename = "document_library")]
330    DocumentLibrary,
331}
332
333fn default_entry_object() -> String {
334    "entry".to_string()
335}
336
337fn default_tool_execution_type() -> String {
338    "tool.execution".to_string()
339}
340
341// Mistral API response type format for Conversations API
342#[derive(Deserialize, Serialize, Debug, Clone)]
343pub struct MistralAPIConversationsUsage {
344    pub completion_tokens: usize,
345    pub connector_tokens: usize,
346    pub prompt_tokens: usize,
347    pub total_tokens: usize,
348    #[serde(default)]
349    pub connectors: Option<Value>,
350}
351
352///Google GeminiPro API response deserialization structs
353#[derive(Debug, Serialize, Deserialize)]
354pub struct GoogleGeminiProApiResp {
355    pub candidates: Vec<GoogleGeminiProCandidate>,
356    #[serde(rename = "usageMetadata")]
357    pub usage_metadata: Option<GoogleGeminiProUsageMetadata>,
358}
359
360#[derive(Debug, Serialize, Deserialize)]
361pub struct GoogleGeminiProCandidate {
362    pub content: GoogleGeminiProContent,
363    #[serde(rename = "finishReason")]
364    pub finish_reason: Option<String>,
365    #[serde(rename = "safetyRatings")]
366    pub safety_ratings: Option<Vec<GoogleGeminiProSafetyRating>>,
367    #[serde(rename = "citationMetadata")]
368    pub citation_metadata: Option<GoogleGeminiProCitationMetadata>,
369}
370
371#[derive(Debug, Serialize, Deserialize)]
372pub struct GoogleGeminiProContent {
373    pub parts: Vec<GoogleGeminiProPart>,
374    pub role: Option<String>,
375}
376
377#[derive(Debug, Serialize, Deserialize)]
378pub struct GoogleGeminiProPart {
379    pub text: Option<String>,
380    #[serde(rename = "executableCode")]
381    pub executable_code: Option<GoogleGeminiExecutableCode>,
382    #[serde(rename = "codeExecutionResult")]
383    pub code_execution_result: Option<GoogleGeminiCodeExecutionResult>,
384}
385
386#[derive(Debug, Serialize, Deserialize)]
387pub struct GoogleGeminiExecutableCode {
388    pub language: String,
389    pub code: String,
390}
391
392#[derive(Debug, Serialize, Deserialize)]
393pub struct GoogleGeminiCodeExecutionResult {
394    pub outcome: String,
395    pub output: Option<String>,
396}
397
398#[derive(Debug, Serialize, Deserialize)]
399pub struct GoogleGeminiProSafetyRating {
400    pub category: String,
401    pub probability: String,
402    pub blocked: Option<bool>,
403}
404
405#[derive(Debug, Serialize, Deserialize)]
406pub struct GoogleGeminiProCitationMetadata {
407    pub citations: Vec<GoogleGeminiProCitation>,
408}
409
410#[derive(Debug, Serialize, Deserialize)]
411pub struct GoogleGeminiProCitation {
412    #[serde(rename = "startIndex")]
413    pub start_index: i32,
414    #[serde(rename = "endIndex")]
415    pub end_index: i32,
416    pub uri: String,
417    pub title: Option<String>,
418    pub license: Option<String>,
419    #[serde(rename = "publicationDate")]
420    pub publication_date: Option<GoogleGeminiProDate>,
421}
422
423#[derive(Debug, Serialize, Deserialize)]
424pub struct GoogleGeminiProDate {
425    pub year: i32,
426    pub month: i32,
427    pub day: i32,
428}
429
430#[derive(Debug, Serialize, Deserialize)]
431pub struct GoogleGeminiProUsageMetadata {
432    #[serde(rename = "promptTokenCount")]
433    pub prompt_token_count: Option<i32>,
434    #[serde(rename = "candidatesTokenCount")]
435    pub candidates_token_count: Option<i32>,
436    #[serde(rename = "totalTokenCount")]
437    pub total_token_count: Option<i32>,
438}
439
440#[derive(Debug, Serialize, Deserialize)]
441pub struct AllmsError {
442    #[serde(rename = "crate")]
443    pub crate_name: String,
444    pub module: String,
445    pub error_message: String,
446    pub error_detail: String,
447}
448
449// Perplexity API response type format for Chat Completions API
450#[derive(Deserialize, Serialize, Debug, Clone)]
451pub struct PerplexityAPICompletionsResponse {
452    pub id: Option<String>,
453    pub model: Option<String>,
454    pub object: Option<String>,
455    pub created: Option<usize>,
456    pub choices: Vec<PerplexityAPICompletionsChoices>,
457    pub citations: Option<Vec<String>>,
458    pub usage: Option<PerplexityAPICompletionsUsage>,
459}
460
461// Perplexity API response type format for Chat Completions API
462#[derive(Deserialize, Serialize, Debug, Clone)]
463pub struct PerplexityAPICompletionsChoices {
464    pub index: usize,
465    pub message: Option<PerplexityAPICompletionsMessage>,
466    pub delta: Option<PerplexityAPICompletionsMessage>,
467    pub finish_reason: String,
468}
469
470// Perplexity API response type format for Chat Completions API
471#[derive(Deserialize, Serialize, Debug, Clone)]
472pub struct PerplexityAPICompletionsMessage {
473    pub role: Option<String>,
474    pub content: Option<String>,
475}
476
477// Perplexity API response type format for Chat Completions API
478#[derive(Deserialize, Serialize, Debug, Clone)]
479pub struct PerplexityAPICompletionsUsage {
480    pub prompt_tokens: usize,
481    pub completion_tokens: usize,
482    pub total_tokens: usize,
483}
484
485// DeepSeek API response type format for Chat Completions API
486#[derive(Deserialize, Serialize, Debug, Clone)]
487pub struct DeepSeekAPICompletionsResponse {
488    pub id: Option<String>,
489    pub choices: Vec<DeepSeekAPICompletionsChoices>,
490    pub created: Option<usize>,
491    pub model: Option<String>,
492    pub system_fingerprint: Option<String>,
493    pub object: Option<String>,
494    pub usage: Option<DeepSeekAPICompletionsUsage>,
495}
496
497#[derive(Deserialize, Serialize, Debug, Clone)]
498pub struct DeepSeekAPICompletionsChoices {
499    pub index: usize,
500    pub finish_reason: String,
501    pub message: Option<DeepSeekAPICompletionsMessage>,
502}
503
504#[derive(Deserialize, Serialize, Debug, Clone)]
505pub struct DeepSeekAPICompletionsMessage {
506    pub role: Option<String>,
507    pub content: Option<String>,
508}
509
510#[derive(Deserialize, Serialize, Debug, Clone)]
511pub struct DeepSeekAPICompletionsUsage {
512    pub completion_tokens: usize,
513    pub prompt_tokens: usize,
514    pub prompt_cache_hit_tokens: usize,
515    pub prompt_cache_miss_tokens: usize,
516    pub total_tokens: usize,
517    pub completion_tokens_details: Option<DeepSeekAPICompletionsReasoningUsage>,
518}
519
520#[derive(Deserialize, Serialize, Debug, Clone)]
521pub struct DeepSeekAPICompletionsReasoningUsage {
522    pub reasoning_tokens: usize,
523}
524
525/***************************************************************************************************
526*
527* OpenAI Responses API
528*
529***************************************************************************************************/
530#[derive(Deserialize, Serialize, Debug)]
531pub struct OpenAPIResponsesResponse {
532    pub id: Option<String>,
533    pub object: Option<String>,
534    pub created_at: Option<i64>,
535    pub status: Option<OpenAPIResponsesStatus>,
536    pub error: Option<OpenAPIResponsesError>,
537    pub incomplete_details: Option<OpenAPIResponsesIncompleteDetails>,
538    pub instructions: Option<String>,
539    pub max_output_tokens: Option<i32>,
540    pub model: String,
541    pub output: Vec<OpenAPIResponsesOutput>,
542    // pub previous_response_id: Option<String>,
543    // pub reasoning: Option<OpenAPIResponsesReasoning>,
544    pub temperature: Option<f32>,
545    pub text: Option<OpenAPIResponsesTextFormat>,
546    // pub tool_choice: OpenAPIResponsesToolChoice,
547    // pub tools: Vec<OpenAPIResponsesTool>,
548    pub top_p: Option<f32>,
549    pub usage: OpenAPIResponsesUsage,
550    pub user: Option<String>,
551}
552
553#[derive(Deserialize, Serialize, Debug)]
554pub struct OpenAPIResponsesError {
555    pub code: Option<String>,
556    pub message: Option<String>,
557}
558
559#[derive(Deserialize, Serialize, Debug)]
560pub struct OpenAPIResponsesIncompleteDetails {
561    pub reason: Option<String>,
562}
563
564#[derive(Deserialize, Serialize, Debug)]
565pub struct OpenAPIResponsesOutput {
566    pub r#type: Option<OpenAPIResponsesOutputType>,
567    pub id: Option<String>,
568    pub status: Option<OpenAPIResponsesMessageStatus>,
569    pub role: Option<OpenAPIResponsesRole>,
570    pub content: Option<Vec<OpenAPIResponsesContent>>,
571}
572
573#[derive(Deserialize, Serialize, Debug)]
574#[serde(rename_all = "snake_case")]
575pub enum OpenAPIResponsesOutputType {
576    Message,
577    FileSearchCall,
578    FunctionCall,
579    WebSearchCall,
580    ComputerCall,
581    Reasoning,
582    CodeInterpreterCall,
583}
584
585#[derive(Deserialize, Serialize, Debug)]
586#[serde(rename_all = "snake_case")]
587pub enum OpenAPIResponsesMessageStatus {
588    InProgress,
589    Completed,
590    Incomplete,
591}
592
593#[derive(Deserialize, Serialize, Debug)]
594#[serde(rename_all = "snake_case")]
595pub enum OpenAPIResponsesRole {
596    Assistant,
597    User,
598    System,
599}
600
601#[derive(Deserialize, Serialize, Debug)]
602pub struct OpenAPIResponsesContent {
603    pub r#type: OpenAPIResponsesContentType,
604    pub text: Option<String>,
605    pub annotations: Option<Vec<OpenAPIResponsesAnnotation>>,
606    pub refusal: Option<String>,
607}
608
609#[derive(Deserialize, Serialize, Debug)]
610#[serde(rename_all = "snake_case")]
611pub enum OpenAPIResponsesContentType {
612    OutputText,
613    Refusal,
614}
615
616#[derive(Deserialize, Serialize, Debug)]
617pub struct OpenAPIResponsesAnnotation {
618    pub r#type: Option<String>,
619    pub text: Option<String>,
620    pub start_index: Option<i32>,
621    pub end_index: Option<i32>,
622}
623
624#[derive(Deserialize, Serialize, Debug)]
625pub struct OpenAPIResponsesReasoning {
626    pub effort: Option<String>,
627    pub summary: Option<String>,
628    pub service_tier: Option<OpenAPIResponsesServiceTier>,
629}
630
631#[derive(Deserialize, Serialize, Debug)]
632#[serde(rename_all = "snake_case")]
633pub enum OpenAPIResponsesServiceTier {
634    Auto,
635    Default,
636    Flex,
637}
638
639#[derive(Deserialize, Serialize, Debug)]
640pub struct OpenAPIResponsesTextFormat {
641    pub format: Option<OpenAPIResponsesFormat>,
642}
643
644#[derive(Deserialize, Serialize, Debug)]
645pub struct OpenAPIResponsesFormat {
646    pub r#type: Option<OpenAPIResponsesFormatType>,
647    pub name: Option<String>,
648    pub schema: Option<serde_json::Value>,
649    pub description: Option<String>,
650    pub strict: Option<bool>,
651}
652
653#[derive(Deserialize, Serialize, Debug)]
654#[serde(rename_all = "snake_case")]
655pub enum OpenAPIResponsesFormatType {
656    Text,
657    JsonSchema,
658    JsonObject,
659}
660
661#[derive(Deserialize, Serialize, Debug)]
662#[serde(untagged)]
663#[allow(dead_code)]
664pub enum OpenAPIResponsesToolChoice {
665    String(String),
666    Object(OpenAPIResponsesToolChoiceObject),
667}
668
669#[derive(Deserialize, Serialize, Debug)]
670#[allow(dead_code)]
671pub struct OpenAPIResponsesToolChoiceObject {
672    pub r#type: Option<String>,
673    pub function: Option<OpenAPIResponsesToolChoiceFunction>,
674}
675
676#[derive(Deserialize, Serialize, Debug)]
677#[allow(dead_code)]
678pub struct OpenAPIResponsesToolChoiceFunction {
679    pub name: Option<String>,
680}
681
682#[derive(Deserialize, Serialize, Debug)]
683pub struct OpenAPIResponsesTool {
684    pub r#type: Option<OpenAPIResponsesToolType>,
685    pub function: Option<OpenAPIResponsesToolFunction>,
686}
687
688#[derive(Deserialize, Serialize, Debug)]
689#[serde(rename_all = "snake_case")]
690pub enum OpenAPIResponsesToolType {
691    Function,
692    FileSearch,
693    WebSearch,
694    Computer,
695    CodeInterpreter,
696}
697
698#[derive(Deserialize, Serialize, Debug)]
699pub struct OpenAPIResponsesToolFunction {
700    pub name: Option<String>,
701    pub description: Option<String>,
702    pub parameters: Option<serde_json::Value>,
703}
704
705#[derive(Deserialize, Serialize, Debug)]
706#[serde(rename_all = "snake_case")]
707pub enum OpenAPIResponsesTruncationStrategy {
708    Auto,
709    Disabled,
710}
711
712#[derive(Deserialize, Serialize, Debug)]
713pub struct OpenAPIResponsesUsage {
714    pub input_tokens: i32,
715    pub input_tokens_details: OpenAPIResponsesTokenDetails,
716    pub output_tokens: i32,
717    pub output_tokens_details: OpenAPIResponsesOutputTokenDetails,
718    pub total_tokens: i32,
719}
720
721#[derive(Deserialize, Serialize, Debug)]
722pub struct OpenAPIResponsesTokenDetails {
723    pub cached_tokens: i32,
724}
725
726#[derive(Deserialize, Serialize, Debug)]
727pub struct OpenAPIResponsesOutputTokenDetails {
728    pub reasoning_tokens: i32,
729}
730
731#[derive(Deserialize, Serialize, Debug)]
732#[serde(rename_all = "snake_case")]
733pub enum OpenAPIResponsesStatus {
734    Completed,
735    Failed,
736    InProgress,
737    Incomplete,
738}
739
740/***************************************************************************************************
741*
742* xAI
743*
744***************************************************************************************************/
745///
746/// xAI API Request
747///
748#[derive(Serialize, Deserialize)]
749pub struct XAIChatRequest {
750    pub model: String,
751    pub messages: Vec<XAIChatMessage>,
752    pub temperature: Option<f32>,
753    pub max_completion_tokens: Option<usize>,
754    pub response_format: Option<XAIResponseFormat>,
755    pub search_parameters: Option<XAIWebSearchConfig>,
756    pub tools: Option<Vec<XAITool>>,
757    // TODO: Future implementations
758    // pub tool_choice: Option<XAIToolChoice>, // Controls which (if any) tool is called by the model. `none` is the default when no tools are present. `auto`` is the default if tools are present.
759    // pub parallel_tool_calls: Option<bool>, // If set to false, the model can perform maximum one tool call.
760    // pub reasoning_effort: Option<String>, // Can be added later via Reasoning Tool
761}
762
763#[derive(Serialize, Deserialize, Default)]
764pub struct XAIChatMessage {
765    pub role: XAIRole,
766    pub content: Option<XAIContentContent>,
767    pub reasoning_content: Option<String>,
768    pub tool_calls: Option<Vec<XAIToolCall>>,
769    pub tool_call_id: Option<String>,
770}
771
772impl XAIChatMessage {
773    pub fn new(role: XAIRole, content: String) -> Self {
774        Self {
775            role,
776            content: Some(XAIContentContent::String(content)),
777            ..Default::default()
778        }
779    }
780}
781
782#[derive(Serialize, Deserialize, Default)]
783#[serde(rename_all = "snake_case")]
784pub enum XAIRole {
785    System,
786    #[default]
787    User,
788    Assistant,
789    Tool,
790    Function,
791}
792
793#[derive(Serialize, Deserialize)]
794#[serde(untagged)]
795pub enum XAIContentContent {
796    String(String),
797    Parts(Vec<XAIContentPart>),
798}
799
800#[derive(Serialize, Deserialize)]
801pub struct XAIContentPart {
802    #[serde(rename = "type")]
803    pub content_type: XAIContentType,
804    pub text: Option<String>,
805    pub image_url: Option<XAIContentImageUrl>,
806    pub text_file: Option<String>,
807    pub detail: Option<String>,
808}
809
810#[derive(Serialize, Deserialize)]
811#[serde(rename_all = "snake_case")]
812pub enum XAIContentType {
813    Text,
814    ImageUrl,
815    TextFile,
816}
817
818#[derive(Serialize, Deserialize)]
819pub struct XAIContentImageUrl {
820    pub url: String,
821    pub detail: Option<String>,
822}
823
824#[derive(Serialize, Deserialize)]
825pub struct XAIToolCall {
826    pub function: XAIToolFunction,
827    pub id: String,
828    pub index: Option<u32>,
829    #[serde(rename = "type")]
830    pub tool_type: Option<String>,
831}
832
833#[derive(Serialize, Deserialize)]
834pub struct XAIToolFunction {
835    pub name: String,
836    pub arguments: String,
837}
838
839#[derive(Debug, Serialize, Deserialize)]
840#[serde(rename_all = "snake_case")]
841pub struct XAIResponseFormat {
842    #[serde(rename = "type")]
843    pub r#type: XAIResponseFormatType,
844    pub json_schema: Option<Value>,
845}
846
847#[derive(Debug, Serialize, Deserialize)]
848#[serde(rename_all = "snake_case")]
849pub enum XAIResponseFormatType {
850    Text,
851    JsonObject,
852    JsonSchema,
853}
854
855#[derive(Serialize, Deserialize)]
856pub struct XAIResponseFormatJsonObject {
857    pub r#type: String,
858}
859
860#[derive(Serialize, Deserialize)]
861pub struct XAIResponseFormatJsonSchema {
862    pub r#type: String,
863    pub json_schema: serde_json::Value,
864}
865
866#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
867#[serde(rename_all = "snake_case")]
868pub struct XAIWebSearchConfig {
869    pub from_date: Option<String>,
870    pub to_date: Option<String>,
871    pub max_search_results: Option<usize>,
872    pub mode: Option<XAISearchMode>,
873    pub return_citations: Option<bool>,
874    pub sources: Option<Vec<XAISearchSource>>,
875}
876
877#[derive(Debug, Serialize, Deserialize, Default, Clone, Eq, PartialEq)]
878#[serde(rename_all = "snake_case")]
879pub enum XAISearchMode {
880    On,
881    Off,
882    #[default]
883    Auto,
884}
885
886#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
887#[serde(tag = "type", rename_all = "snake_case")]
888pub enum XAISearchSource {
889    Web(WebSource),
890    X(XSource),
891    News(NewsSource),
892    Rss(RssSource),
893}
894
895#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
896pub struct WebSource {
897    pub allowed_websites: Option<Vec<String>>,
898    pub excluded_websites: Option<Vec<String>>,
899    pub country: Option<String>,
900    pub safe_search: Option<bool>,
901}
902
903#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
904pub struct XSource {
905    pub included_x_handles: Option<Vec<String>>,
906    pub excluded_x_handles: Option<Vec<String>>,
907    pub post_favorite_count: Option<usize>,
908    pub post_view_count: Option<usize>,
909}
910
911#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
912pub struct NewsSource {
913    pub excluded_websites: Option<Vec<String>>,
914    pub country: Option<String>,
915    pub safe_search: Option<bool>,
916}
917
918#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
919pub struct RssSource {
920    pub links: Vec<String>,
921}
922
923#[derive(Serialize, Deserialize)]
924pub struct XAITool {
925    #[serde(rename = "type")]
926    pub tool_type: XAIToolType,
927    pub function: Option<XAIToolDefFunction>,
928}
929
930#[derive(Serialize, Deserialize)]
931#[serde(rename_all = "snake_case")]
932pub enum XAIToolType {
933    Function,
934}
935
936#[derive(Serialize, Deserialize)]
937pub struct XAIToolDefFunction {
938    pub name: String,
939    pub description: Option<String>,
940    pub parameters: serde_json::Value,
941}
942
943///
944/// xAI API Response
945///
946#[derive(Debug, Serialize, Deserialize)]
947pub struct XAIChatResponse {
948    pub id: String,
949    pub object: Option<String>, // should be "chat.completion"
950    pub created: Option<u64>,
951    pub model: Option<String>,
952    pub choices: Vec<XAIChatChoice>,
953    pub usage: Option<XAIUsage>,
954    pub citations: Option<Vec<String>>,
955    pub debug_output: Option<Value>,
956    pub system_fingerprint: Option<String>,
957}
958
959#[derive(Debug, Serialize, Deserialize)]
960pub struct XAIChatChoice {
961    pub index: u32,
962    pub message: XAIAssistantMessage,
963    pub finish_reason: Option<String>,
964    pub logprobs: Option<Value>, // You can replace with a struct if you want structured access
965}
966
967#[derive(Debug, Serialize, Deserialize)]
968pub struct XAIAssistantMessage {
969    pub role: XAIAssistantMessageRole,
970    pub content: Option<String>,
971    pub reasoning_content: Option<String>,
972    pub refusal: Option<String>,
973    pub tool_calls: Option<Vec<XAIAssistantMessageToolCall>>,
974}
975
976#[derive(Debug, Serialize, Deserialize, Default, PartialEq, Eq)]
977#[serde(rename_all = "snake_case")]
978pub enum XAIAssistantMessageRole {
979    #[default]
980    Assistant,
981}
982
983#[derive(Debug, Serialize, Deserialize)]
984pub struct XAIAssistantMessageToolCall {
985    pub id: String,
986    pub index: Option<u32>,
987    #[serde(rename = "type")]
988    pub call_type: XAIAssistantMessageToolCallType,
989    pub function: XAIAssistantMessageToolFunction,
990}
991
992#[derive(Debug, Serialize, Deserialize, Default)]
993#[serde(rename_all = "snake_case")]
994pub enum XAIAssistantMessageToolCallType {
995    #[default]
996    Function,
997}
998
999#[derive(Debug, Serialize, Deserialize)]
1000pub struct XAIAssistantMessageToolFunction {
1001    pub name: String,
1002    pub arguments: String,
1003}
1004
1005#[derive(Debug, Serialize, Deserialize)]
1006pub struct XAIUsage {
1007    pub prompt_tokens: Option<u32>,
1008    pub completion_tokens: Option<u32>,
1009    pub total_tokens: Option<u32>,
1010    pub completion_tokens_details: Option<XAICompletionTokenDetails>,
1011    pub prompt_tokens_details: Option<XAIPromptTokenDetails>,
1012    pub num_sources_used: Option<u32>,
1013}
1014
1015#[derive(Debug, Serialize, Deserialize)]
1016pub struct XAICompletionTokenDetails {
1017    pub accepted_prediction_tokens: Option<u32>,
1018    pub audio_tokens: Option<u32>,
1019    pub reasoning_tokens: Option<u32>,
1020    pub rejected_prediction_tokens: Option<u32>,
1021}
1022
1023#[derive(Debug, Serialize, Deserialize)]
1024pub struct XAIPromptTokenDetails {
1025    pub audio_tokens: Option<u32>,
1026    pub cached_tokens: Option<u32>,
1027    pub image_tokens: Option<u32>,
1028    pub text_tokens: Option<u32>,
1029}