Skip to main content

aha/params/
chat.rs

1use super::shared::{ReasoningEffort, WebSearchContextSize};
2use crate::params::shared::StopToken;
3use crate::params::shared::{FinishReason, Usage};
4use derive_builder::Builder;
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use std::collections::HashMap;
8use std::fmt::Display;
9
10#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
11pub struct ChatCompletionResponse {
12    /// A unique identifier for the chat completion.
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub id: Option<String>,
15    /// A list of chat completion choices. Can be more than one if n is greater than 1.
16    pub choices: Vec<ChatCompletionChoice>,
17    /// The Unix timestamp (in seconds) of when the chat completion was created.
18    pub created: u32,
19    /// The model used for the chat completion.
20    pub model: String,
21    /// The service tier used for processing the request.
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub service_tier: Option<String>,
24    /// This fingerprint represents the backend configuration that the model runs with.
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub system_fingerprint: Option<String>,
27    /// The object type, which is always chat.completion.
28    pub object: String,
29    /// Usage statistics for the completion request.
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub usage: Option<Usage>,
32}
33
34#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
35pub struct ChatCompletionChunkResponse {
36    /// A unique identifier for the chat completion. Each chunk has the same ID.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub id: Option<String>,
39    /// A list of chat completion choices. Can be more than one if n is greater than 1.
40    pub choices: Vec<ChatCompletionChunkChoice>,
41    /// The Unix timestamp (in seconds) of when the chat completion was created. Each chunk has the same timestamp.
42    pub created: u32,
43    /// The model to generate the completion.
44    pub model: String,
45    /// This fingerprint represents the backend configuration that the model runs with.
46    /// Can be used in conjunction with the seed request parameter to understand when backend changes have been made that might impact determinism.
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub system_fingerprint: Option<String>,
49    /// The object type, which is always chat.completion.chunk.
50    pub object: String,
51    /// An optional field that will only be present when you set stream_options: {"include_usage": true} in your request. When present, it contains a null value except for the last chunk which contains the token usage statistics for the entire request.
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub usage: Option<Usage>,
54}
55
56#[derive(Serialize, Deserialize, Debug, Default, Builder, Clone, PartialEq)]
57#[builder(name = "ChatCompletionParametersBuilder")]
58#[builder(setter(into, strip_option), default)]
59pub struct ChatCompletionParameters {
60    /// A list of messages comprising the conversation so far.
61    pub messages: Vec<ChatMessage>,
62    /// ID of the model to use.
63    pub model: String,
64    /// Whether or not to store the output of this chat completion request for use in our model distillation or evals products.
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub store: Option<bool>,
67    /// Constrains effort on reasoning for reasoning models.
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub reasoning_effort: Option<ReasoningEffort>,
70    /// Developer-defined tags and values used for filtering completions in the dashboard.
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub metadata: Option<HashMap<String, String>>,
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub enable_thinking: Option<bool>,
75    /// Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far,
76    /// decreasing the model's likelihood to repeat the same line verbatim.
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub frequency_penalty: Option<f32>,
79    /// Modify the likelihood of specified tokens appearing in the completion.
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub logit_bias: Option<HashMap<String, i32>>,
82    /// Whether to return log probabilities of the output tokens or not.
83    /// If true, returns the log probabilities of each output token returned in the 'content' of 'message'.
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub logprobs: Option<bool>,
86    /// An integer between 0 and 5 specifying the number of most likely tokens to return at each token position,
87    /// each with an associated log probability. 'logprobs' must be set to 'true' if this parameter is used.
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub top_logprobs: Option<u32>,
90    /// Max completion tokens, deprecated (still used by vllm)
91    #[serde(skip_serializing_if = "Option::is_none")]
92    pub max_tokens: Option<u32>,
93    /// An upper bound for the number of tokens that can be generated for a completion, including visible output tokens and reasoning tokens.
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub max_completion_tokens: Option<u32>,
96    /// How many chat completion choices to generate for each input message.
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub n: Option<u32>,
99    /// Output types that you would like the model to generate for this request.
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub modalities: Option<Vec<Modality>>,
102    /// Configuration for a Predicted Output, which can greatly improve response times when large parts of the model response are known ahead of time.
103    /// This is most common when you are regenerating a file with only minor changes to most of the content.
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub prediction: Option<PredictedOutput>,
106    /// Parameters for audio output. Required when audio output is requested with modalities: ["audio"].
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub audio: Option<AudioParameters>,
109    /// Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far,
110    /// increasing the model's likelihood to talk about new topics.
111    #[serde(skip_serializing_if = "Option::is_none")]
112    pub presence_penalty: Option<f32>,
113    /// An object specifying the format that the model must output.
114    /// Compatible with GPT-4o, GPT-4o mini, GPT-4 Turbo and all GPT-3.5 Turbo models newer than gpt-3.5-turbo-1106.
115    /// Setting to { "type": "json_schema", "json_schema": {...} } enables Structured Outputs which ensures the model will match your supplied JSON schema.
116    /// Setting to { "type": "json_object" } enables JSON mode, which ensures the message the model generates is valid JSON.
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub response_format: Option<ChatCompletionResponseFormat>,
119    /// Deprecated (still used by vllm)
120    /// This feature is in Beta. If specified, our system will make a best effort to sample deterministically,
121    /// such that repeated requests with the same seed and parameters should return the same result.
122    /// Determinism is not guaranteed, and you should refer to the system_fingerprint response parameter to monitor changes in the backend.
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub seed: Option<u32>,
125    /// Up to 4 sequences where the API will stop generating further tokens.
126    #[serde(skip_serializing_if = "Option::is_none")]
127    pub stop: Option<StopToken>,
128    /// If set, partial messages will be sent, like in ChatGPT. Tokens will be sent as data-only server-sent events
129    /// as they become available, with the stream terminated by a data: [DONE] message.
130    #[serde(skip_serializing_if = "Option::is_none")]
131    pub stream: Option<bool>,
132    /// Options for streaming response. Only set this when you set stream: true.
133    #[serde(skip_serializing_if = "Option::is_none")]
134    pub stream_options: Option<ChatCompletionStreamOptions>,
135    /// What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random,
136    /// while lower values like 0.2 will make it more focused and deterministic.
137    #[serde(skip_serializing_if = "Option::is_none")]
138    pub temperature: Option<f32>,
139    /// An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass.
140    /// So 0.1 means only the tokens comprising the top 10% probability mass are considered.
141    #[serde(skip_serializing_if = "Option::is_none")]
142    pub top_p: Option<f32>,
143    #[serde(skip_serializing_if = "Option::is_none")]
144    pub top_k: Option<usize>,
145    /// Penalize repetition of token sequences, helping to prevent the model from getting stuck in loops.
146    /// Values > 1.0 penalize repetitions, values < 1.0 encourage them.
147    /// For example, a value of 1.2 means that tokens that have already appeared will be less likely to appear again.
148    #[serde(skip_serializing_if = "Option::is_none")]
149    pub repeat_penalty: Option<f32>,
150    /// The number of previous tokens to consider when applying repeat penalty.
151    /// Only the last N tokens in the conversation history will be used to calculate the penalty.
152    /// A larger value considers more history for penalizing repetitions, while 0 applies no penalty.
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub repeat_last_n: Option<usize>,
155    /// A list of tools the model may call. Currently, only functions are supported as a tool.
156    /// Use this to provide a list of functions the model may generate JSON inputs for.
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub tools: Option<Vec<ChatCompletionTool>>,
159    /// Controls which (if any) tool is called by the model. none means the model will not call any tool and instead generates a message.
160    /// auto means the model can pick between generating a message or calling one or more tools.
161    /// required means the model must call one or more tools.
162    /// Specifying a particular tool via {"type": "function", "function": {"name": "my_function"}} forces the model to call that tool.
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub tool_choice: Option<ChatCompletionToolChoice>,
165    /// Whether to enable parallel function calling during tool use.
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub parallel_tool_calls: Option<bool>,
168    /// A stable identifier used to help detect users of your application that may be violating OpenAI's usage policies.
169    #[serde(skip_serializing_if = "Option::is_none")]
170    pub safety_identifier: Option<String>,
171    /// Used by OpenAI to cache responses for similar requests to optimize your cache hit rates.
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub prompt_cache_key: Option<String>,
174    /// This tool searches the web for relevant results to use in a response.
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub web_search_options: Option<WebSearchOptions>,
177    /// Allows to pass arbitrary json as an extra_body parameter, for specific features/openai-compatible endpoints.
178    #[serde(flatten)]
179    #[serde(skip_serializing_if = "Option::is_none")]
180    pub extra_body: Option<Value>,
181    /// Azure OpenAI and some other providers may require special query parameters to be set on the request URL.
182    /// This field allows you to specify those query parameters.
183    #[serde(skip_serializing_if = "Option::is_none")]
184    pub query_params: Option<HashMap<String, String>>,
185}
186
187#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
188pub struct ChatCompletionStreamOptions {
189    /// If set, an additional chunk will be streamed before the data: [DONE] message.
190    pub include_usage: Option<bool>,
191    #[serde(skip_serializing_if = "Option::is_none")]
192    pub continuous_usage_stats: Option<bool>,
193}
194
195#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
196pub struct ChatCompletionToolChoiceFunction {
197    /// The type of the tool. Currently, only 'function' is supported.
198    #[serde(skip_serializing_if = "Option::is_none")]
199    pub r#type: Option<ChatCompletionToolType>,
200    /// Name of the function.
201    pub function: ChatCompletionToolChoiceFunctionName,
202}
203
204#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
205pub struct ChatCompletionToolChoiceFunctionName {
206    /// Name of the function.
207    pub name: String,
208}
209
210#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
211pub struct ChatCompletionFunction {
212    /// Name of the function.
213    pub name: String,
214    /// Optional description of the function.
215    #[serde(skip_serializing_if = "Option::is_none")]
216    pub description: Option<String>,
217    /// The parameters the function takes. The model will generate JSON inputs for these parameters.
218    pub parameters: serde_json::Value,
219}
220
221#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
222#[serde(tag = "type", rename_all = "snake_case")]
223pub enum ChatCompletionResponseFormat {
224    Text,
225    JsonObject,
226    JsonSchema { json_schema: JsonSchema },
227}
228
229#[derive(Serialize, Deserialize, Debug, Default, Builder, Clone, PartialEq)]
230#[builder(name = "JsonSchemaBuilder")]
231#[builder(setter(into, strip_option), default)]
232pub struct JsonSchema {
233    /// A description of what the response format is for, used by the model to determine how to respond in the format.
234    #[serde(skip_serializing_if = "Option::is_none")]
235    description: Option<String>,
236    /// The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.
237    name: String,
238    /// The schema for the response format, described as a JSON Schema object.
239    #[serde(skip_serializing_if = "Option::is_none")]
240    schema: Option<serde_json::Value>,
241    /// Whether to enable strict schema adherence when generating the output.
242    #[serde(skip_serializing_if = "Option::is_none")]
243    strict: Option<bool>,
244}
245
246#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
247pub struct ChatCompletionTool {
248    /// The type of the tool. Currently, only 'function' is supported.
249    pub r#type: ChatCompletionToolType,
250    /// The name of the function to call.
251    pub function: ChatCompletionFunction,
252}
253
254#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
255#[serde(tag = "role", rename_all = "snake_case")]
256pub enum ChatMessage {
257    Developer {
258        /// The contents of the developer message.
259        content: ChatMessageContent,
260        /// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
261        #[serde(skip_serializing_if = "Option::is_none")]
262        name: Option<String>,
263    },
264    System {
265        /// The contents of the system message.
266        content: ChatMessageContent,
267        /// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
268        #[serde(skip_serializing_if = "Option::is_none")]
269        name: Option<String>,
270    },
271    User {
272        /// The contents of the user message.
273        content: ChatMessageContent,
274        /// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
275        #[serde(skip_serializing_if = "Option::is_none")]
276        name: Option<String>,
277    },
278    Assistant {
279        /// The contents of the assistant message. Required unless tool_calls is specified.
280        #[serde(skip_serializing_if = "Option::is_none")]
281        content: Option<ChatMessageContent>,
282        /// The reasoning content by the assistant. (DeepSeek API only)
283        #[serde(skip_serializing_if = "Option::is_none")]
284        reasoning_content: Option<String>,
285        /// The refusal message by the assistant.
286        #[serde(skip_serializing_if = "Option::is_none")]
287        refusal: Option<String>,
288        /// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
289        #[serde(skip_serializing_if = "Option::is_none")]
290        name: Option<String>,
291        /// Data about a previous audio response from the model.
292        #[serde(skip_serializing_if = "Option::is_none")]
293        audio: Option<AudioDataIdParameter>,
294        /// The tool calls generated by the model, such as function calls.
295        #[serde(skip_serializing_if = "Option::is_none")]
296        tool_calls: Option<Vec<ToolCall>>,
297    },
298    Tool {
299        /// The contents of the tool message.
300        content: ChatMessageContent,
301        /// Tool call that this message is responding to.
302        tool_call_id: String,
303    },
304}
305
306impl ChatMessage {
307    /// Get the ChatMessageContent data, if it exists.
308    pub fn message(&self) -> Option<&ChatMessageContent> {
309        match self {
310            ChatMessage::Developer { content, .. }
311            | ChatMessage::System { content, .. }
312            | ChatMessage::User { content, .. }
313            | ChatMessage::Assistant {
314                content: Some(content),
315                ..
316            } => Some(content),
317            ChatMessage::Assistant { content: None, .. } => None,
318            ChatMessage::Tool { .. } => None,
319        }
320    }
321
322    /// Get the content of the message as text, if it is a simple text message.
323    pub fn text(&self) -> Option<&str> {
324        match self {
325            ChatMessage::Developer { content, .. }
326            | ChatMessage::System { content, .. }
327            | ChatMessage::User { content, .. }
328            | ChatMessage::Tool { content, .. }
329            | ChatMessage::Assistant {
330                content: Some(content),
331                ..
332            } => {
333                if let ChatMessageContent::Text(text) = content {
334                    Some(text)
335                } else {
336                    None
337                }
338            }
339            ChatMessage::Assistant { content: None, .. } => None,
340        }
341    }
342
343    /// Get the name of the message sender, if it exists.
344    pub fn name(&self) -> Option<&str> {
345        match self {
346            ChatMessage::Developer { name, .. }
347            | ChatMessage::System { name, .. }
348            | ChatMessage::User { name, .. }
349            | ChatMessage::Assistant { name, .. } => name.as_deref(),
350            ChatMessage::Tool { .. } => None,
351        }
352    }
353}
354
355#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
356#[serde(tag = "role", rename_all = "snake_case")]
357pub enum DeltaChatMessage {
358    Developer {
359        /// The contents of the developer message.
360        content: ChatMessageContent,
361        /// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
362        #[serde(skip_serializing_if = "Option::is_none")]
363        name: Option<String>,
364    },
365    System {
366        /// The contents of the system message.
367        content: ChatMessageContent,
368        /// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
369        #[serde(skip_serializing_if = "Option::is_none")]
370        name: Option<String>,
371    },
372    User {
373        /// The contents of the user message.
374        content: ChatMessageContent,
375        /// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
376        #[serde(skip_serializing_if = "Option::is_none")]
377        name: Option<String>,
378    },
379    Assistant {
380        /// The contents of the assistant message. Required unless tool_calls is specified.
381        #[serde(skip_serializing_if = "Option::is_none")]
382        content: Option<ChatMessageContent>,
383        /// The reasoning content by the assistant. (DeepSeek API only)
384        #[serde(skip_serializing_if = "Option::is_none")]
385        reasoning_content: Option<String>,
386        /// The refusal message by the assistant.
387        #[serde(skip_serializing_if = "Option::is_none")]
388        refusal: Option<String>,
389        /// An optional name for the participant. Provides the model information to differentiate between participants of the same role.
390        #[serde(skip_serializing_if = "Option::is_none")]
391        name: Option<String>,
392        /// The tool calls generated by the model, such as function calls.
393        #[serde(skip_serializing_if = "Option::is_none")]
394        tool_calls: Option<Vec<DeltaToolCall>>,
395    },
396    Tool {
397        /// The contents of the tool message.
398        content: String,
399        /// Tool call that this message is responding to.
400        tool_call_id: String,
401    },
402    #[serde(untagged)]
403    Untagged {
404        #[serde(skip_serializing_if = "Option::is_none")]
405        content: Option<ChatMessageContent>,
406        #[serde(skip_serializing_if = "Option::is_none")]
407        reasoning_content: Option<String>,
408        #[serde(skip_serializing_if = "Option::is_none")]
409        refusal: Option<String>,
410        #[serde(skip_serializing_if = "Option::is_none")]
411        name: Option<String>,
412        #[serde(skip_serializing_if = "Option::is_none")]
413        tool_calls: Option<Vec<DeltaToolCall>>,
414        #[serde(skip_serializing_if = "Option::is_none")]
415        tool_call_id: Option<String>,
416    },
417}
418
419#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
420pub struct ToolCall {
421    /// The ID of the tool call.
422    pub id: String,
423    /// The type of the tool. Currently, only function is supported.
424    pub r#type: String,
425    /// The function that the model called.
426    pub function: Function,
427}
428
429#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
430pub struct DeltaToolCall {
431    /// The index of the tool call in the list of tool calls.
432    #[serde(skip_serializing_if = "Option::is_none")]
433    pub index: Option<u32>,
434    /// /// The ID of the tool call.
435    #[serde(skip_serializing_if = "Option::is_none")]
436    pub id: Option<String>,
437    /// The type of the tool. Currently, only 'function' is supported.
438    #[serde(skip_serializing_if = "Option::is_none")]
439    pub r#type: Option<String>,
440    /// The function that the model called.
441    pub function: DeltaFunction,
442}
443
444#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
445pub struct Function {
446    /// The name of the function to call.
447    pub name: String,
448    /// The arguments to call the function with, as generated by the model in JSON format.
449    pub arguments: String,
450}
451
452#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
453pub struct DeltaFunction {
454    /// The name of the function to call.
455    #[serde(skip_serializing_if = "Option::is_none")]
456    pub name: Option<String>,
457    /// The arguments to call the function with, as generated by the model in JSON format.
458    #[serde(skip_serializing_if = "Option::is_none")]
459    pub arguments: Option<String>,
460}
461
462#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
463pub struct ChatCompletionChoice {
464    /// The index of the choice in the list of choices.
465    pub index: u32,
466    /// A chat completion message generated by the model.
467    pub message: ChatMessage,
468    /// The reason the model stopped generating tokens.
469    #[serde(skip_serializing_if = "Option::is_none")]
470    pub finish_reason: Option<FinishReason>,
471    /// Log probability information for the choice.
472    #[serde(skip_serializing_if = "Option::is_none")]
473    pub logprobs: Option<LogProps>,
474}
475
476#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
477pub struct AudioDataIdParameter {
478    /// Unique identifier for a previous audio response from the model.
479    pub id: String,
480}
481
482#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
483pub struct AudioParameters {
484    /// The voice the model uses to respond.
485    pub voice: Voice,
486    /// Specifies the output audio format.
487    pub format: AudioFormat,
488}
489
490#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
491pub struct LogProps {
492    /// A list of message content tokens with log probability information.
493    #[serde(skip_serializing_if = "Option::is_none")]
494    pub content: Option<Vec<LogPropsContent>>,
495    /// A list of message refusal tokens with log probability information.
496    #[serde(skip_serializing_if = "Option::is_none")]
497    pub refusal: Option<Vec<LogPropsContent>>,
498}
499
500#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
501pub struct LogPropsContent {
502    /// Token information
503    #[serde(flatten)]
504    pub token_info: LogProbsContentInfo,
505    /// List of the most likely tokens and their log probability, at this token position.
506    pub top_logprobs: Vec<LogProbsContentInfo>,
507}
508
509#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
510pub struct LogProbsContentInfo {
511    /// The token.
512    pub token: String,
513    /// The log probability of this token, if it is within the top 20 most likely tokens.
514    /// Otherwise, the value -9999.0 is used to signify that the token is very unlikely.
515    pub logprob: f32,
516    /// A list of integers representing the UTF-8 bytes representation of the token.
517    pub bytes: Option<Vec<u8>>,
518}
519
520#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
521pub struct ChatCompletionChunkChoice {
522    /// The index of the choice in the list of choices.
523    pub index: Option<u32>,
524    /// A chat completion delta generated by streamed model responses.
525    pub delta: DeltaChatMessage,
526    /// The reason the model stopped generating tokens.
527    #[serde(skip_serializing_if = "Option::is_none")]
528    pub finish_reason: Option<FinishReason>,
529    /// Log probability information for the choice.
530    #[serde(skip_serializing_if = "Option::is_none")]
531    pub logprobs: Option<LogProps>,
532}
533
534#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
535pub struct ImageUrlType {
536    /// Either a URL of the image or the base64 encoded image data.
537    pub url: String,
538    /// Specifies the detail level of the image.
539    #[serde(skip_serializing_if = "Option::is_none")]
540    pub detail: Option<ImageUrlDetail>,
541}
542
543#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
544pub struct AudioUrlType {
545    /// audio  URL or base64
546    pub url: String,
547}
548
549#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
550pub struct VideoUrlType {
551    /// video  URL
552    pub url: String,
553}
554
555#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
556pub struct PredictedOutput {
557    /// The type of the predicted content you want to provide.
558    pub r#type: PredictedOutputType,
559    /// The content that should be matched when generating a model response.
560    /// If generated tokens would match this content, the entire model response can be returned much more quickly.
561    pub content: PredictedOutputContent,
562}
563
564#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
565#[serde(untagged)]
566pub enum PredictedOutputContent {
567    String(String),
568    Array(Vec<PredictedOutputArrayPart>),
569}
570
571#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
572pub struct PredictedOutputArrayPart {
573    /// The type of the content part.
574    pub r#type: String,
575    /// The text content.
576    pub text: String,
577}
578
579#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
580#[serde(rename_all = "snake_case")]
581pub enum PredictedOutputType {
582    Content,
583}
584
585#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
586#[serde(rename_all = "snake_case")]
587pub enum Modality {
588    Text,
589    Audio,
590}
591
592#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
593#[serde(rename_all = "snake_case")]
594pub enum ImageUrlDetail {
595    Auto,
596    High,
597    Low,
598}
599
600#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
601#[serde(untagged)]
602pub enum ChatMessageContent {
603    Text(String),
604    ContentPart(Vec<ChatMessageContentPart>),
605    None,
606}
607
608#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
609#[serde(untagged)]
610pub enum ChatMessageContentPart {
611    Text(ChatMessageTextContentPart),
612    Image(ChatMessageImageContentPart),
613    Audio(ChatMessageAudioContentPart),
614    Video(ChatMessageVideoContentPart),
615}
616
617#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
618pub struct ChatMessageTextContentPart {
619    /// The type of the content part.
620    pub r#type: String,
621    /// The text content.
622    pub text: String,
623}
624
625#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
626pub struct ChatMessageImageContentPart {
627    /// The type of the content part.
628    pub r#type: String,
629    /// The text content.
630    pub image_url: ImageUrlType,
631}
632
633#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
634pub struct ChatMessageAudioContentPart {
635    /// The type of the content part. Always input_audio.
636    pub r#type: String,
637    /// The input audio data.
638    pub audio_url: AudioUrlType,
639}
640
641#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
642pub struct ChatMessageVideoContentPart {
643    /// The type of the content part.
644    pub r#type: String,
645    /// The text content.
646    pub video_url: VideoUrlType,
647}
648
649#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
650pub struct ChatMessageImageUrl {
651    /// Either a URL of the image or the base64 encoded image data.
652    pub url: String,
653    /// Specifies the detail level of the image.
654    pub detail: String,
655}
656
657#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
658pub struct InputAudioData {
659    /// Base64 encoded audio data.
660    pub data: String,
661    /// The format of the encoded audio data. Currently supports "wav" and "mp3".
662    pub format: String,
663}
664
665#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
666pub struct WebSearchOptions {
667    /// High level guidance for the amount of context window space to use for the search.
668    #[serde(skip_serializing_if = "Option::is_none")]
669    pub search_context_size: Option<WebSearchContextSize>,
670    /// Approximate location parameters for the search.
671    #[serde(skip_serializing_if = "Option::is_none")]
672    pub user_location: Option<ApproximateUserLocation>,
673}
674
675#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
676pub struct ApproximateUserLocation {
677    pub r#type: UserLocationType,
678    /// Approximate location parameters for the search.
679    pub approximate: WebSearchUserLocation,
680}
681
682impl Display for ChatMessageContent {
683    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
684        match self {
685            ChatMessageContent::Text(text) => write!(f, "{text}"),
686            ChatMessageContent::ContentPart(tcp) => {
687                for part in tcp {
688                    write!(f, "{part:?}")?;
689                }
690                Ok(())
691            }
692            ChatMessageContent::None => write!(f, ""),
693        }
694    }
695}
696
697#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
698#[serde(rename_all = "snake_case")]
699pub enum ChatCompletionToolType {
700    Function,
701}
702
703#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
704#[serde(rename_all = "snake_case")]
705pub enum ChatCompletionToolChoice {
706    None,
707    Auto,
708    Required,
709    #[serde(untagged)]
710    ChatCompletionToolChoiceFunction(ChatCompletionToolChoiceFunction),
711}
712
713#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
714pub struct WebSearchUserLocation {
715    pub city: Option<String>,
716    pub country: Option<String>,
717    pub region: Option<String>,
718    pub timezone: Option<String>,
719}
720
721#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
722#[serde(rename_all = "snake_case")]
723pub enum UserLocationType {
724    Approximate,
725}
726
727#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
728#[serde(rename_all = "snake_case")]
729pub enum Voice {
730    Alloy,
731    Ash,
732    Ballad,
733    Coral,
734    Echo,
735    Sage,
736    Shimmer,
737    Verse,
738}
739
740#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
741#[serde(rename_all = "snake_case")]
742pub enum AudioFormat {
743    Wav,
744    Mp3,
745    Flac,
746    Opus,
747    Pcm16,
748}
749
750impl Default for ChatMessageContent {
751    fn default() -> Self {
752        ChatMessageContent::Text("".to_string())
753    }
754}
755
756impl DeltaFunction {
757    pub fn merge(&mut self, other: &Self) {
758        if self.name.is_none() && other.name.is_some() {
759            self.name.clone_from(&other.name);
760        }
761
762        if let Some(arguments) = &other.arguments {
763            if let Some(self_arguments) = &mut self.arguments {
764                self_arguments.push_str(arguments);
765            } else {
766                self.arguments = Some(arguments.clone());
767            }
768        }
769    }
770
771    pub fn is_empty(&self) -> bool {
772        self.name.is_none() && self.arguments.is_none()
773    }
774}