Skip to main content

outfox_openai/spec/
chat.rs

1mod api;
2mod impls;
3
4use std::collections::HashMap;
5use std::pin::Pin;
6
7pub use api::*;
8use derive_builder::Builder;
9use futures::Stream;
10use serde::{Deserialize, Serialize};
11
12use crate::error::OpenAIError;
13// Re-export shared types that are used in chat
14pub use crate::spec::shared::CompletionTokensDetails;
15pub use crate::spec::shared::{
16    CustomGrammarFormatParam, FunctionCall, FunctionObjectArgs, GrammarSyntax, ImageUrlArgs,
17    PromptTokensDetails,
18};
19// Re-export text types used in chat
20pub use crate::spec::text::{PartibleTextContent, TextObject};
21
22#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
23#[serde(untagged)]
24pub enum Prompt {
25    String(String),
26    StringArray(Vec<String>),
27    // Minimum value is 0, maximum value is 4_294_967_295 (inclusive).
28    IntegerArray(Vec<u32>),
29    ArrayOfIntegerArray(Vec<Vec<u32>>),
30}
31
32#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
33#[serde(untagged)]
34pub enum StopConfiguration {
35    String(String),           // nullable: true
36    StringArray(Vec<String>), // minItems: 1; maxItems: 4
37}
38
39#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
40pub struct Logprobs {
41    pub tokens: Vec<String>,
42    pub token_logprobs: Vec<Option<f32>>, // Option is to account for null value in the list
43    pub top_logprobs: Vec<serde_json::Value>,
44    pub text_offset: Vec<u32>,
45}
46
47#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
48#[serde(rename_all = "snake_case")]
49pub enum CompletionFinishReason {
50    Stop,
51    Length,
52    ContentFilter,
53}
54
55#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
56pub struct Choice {
57    pub text: String,
58    pub index: u32,
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub logprobs: Option<Logprobs>,
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub finish_reason: Option<CompletionFinishReason>,
63}
64
65#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
66pub enum ChatCompletionFunctionCall {
67    /// The model does not call a function, and responds to the end-user.
68    #[serde(rename = "none")]
69    None,
70    /// The model can pick between an end-user or calling a function.
71    #[serde(rename = "auto")]
72    Auto,
73
74    // In spec this is ChatCompletionFunctionCallOption
75    // based on feedback from @m1guelpf in https://github.com/64bit/async-openai/pull/118
76    // it is diverged from the spec
77    /// Forces the model to call the specified function.
78    #[serde(untagged)]
79    Function { name: String },
80}
81
82#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, PartialEq)]
83#[serde(rename_all = "lowercase")]
84pub enum Role {
85    System,
86    #[default]
87    User,
88    Assistant,
89    Tool,
90    Function,
91}
92
93/// Usage statistics for the completion request.
94#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
95pub struct CompletionUsage {
96    /// Number of tokens in the prompt.
97    pub prompt_tokens: u32,
98    /// Number of tokens in the generated completion.
99    pub completion_tokens: u32,
100    /// Total number of tokens used in the request (prompt + completion).
101    pub total_tokens: u32,
102    /// Breakdown of tokens used in the prompt.
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub prompt_tokens_details: Option<PromptTokensDetails>,
105    /// Breakdown of tokens used in a completion.
106    #[serde(skip_serializing_if = "Option::is_none")]
107    pub completion_tokens_details: Option<CompletionTokensDetails>,
108}
109
110#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
111#[builder(name = "ChatCompletionRequestDeveloperMessageArgs")]
112#[builder(pattern = "mutable")]
113#[builder(setter(into, strip_option), default)]
114#[builder(derive(Debug))]
115#[builder(build_fn(error = "OpenAIError"))]
116pub struct ChatCompletionRequestDeveloperMessage {
117    /// The contents of the developer message.
118    pub content: ChatCompletionRequestDeveloperMessageContent,
119
120    /// An optional name for the participant. Provides the model information to differentiate
121    /// between participants of the same role.
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub name: Option<String>,
124}
125
126impl ChatCompletionRequestDeveloperMessage {
127    pub fn to_texts(&self) -> Vec<String> {
128        self.content.to_texts()
129    }
130}
131
132#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
133#[serde(untagged)]
134pub enum ChatCompletionRequestDeveloperMessageContent {
135    Text(String),
136    Array(Vec<ChatCompletionRequestDeveloperMessageContentPart>),
137}
138
139impl ChatCompletionRequestDeveloperMessageContent {
140    pub fn to_texts(&self) -> Vec<String> {
141        match self {
142            Self::Text(text) => vec![text.clone()],
143            Self::Array(parts) => parts
144                .iter()
145                .map(|part| {
146                    let ChatCompletionRequestDeveloperMessageContentPart::Text(text_part) = part;
147                    text_part.text.clone()
148                })
149                .collect(),
150        }
151    }
152}
153
154#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
155#[serde(tag = "type")]
156#[serde(rename_all = "snake_case")]
157pub enum ChatCompletionRequestDeveloperMessageContentPart {
158    Text(ChatCompletionRequestMessageContentPartText),
159}
160
161#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
162#[serde(untagged)]
163pub enum ChatCompletionRequestSystemMessageContent {
164    Text(String),
165    Array(Vec<ChatCompletionRequestSystemMessageContentPart>),
166}
167
168impl ChatCompletionRequestSystemMessageContent {
169    pub fn to_texts(&self) -> Vec<String> {
170        match self {
171            Self::Text(text) => vec![text.clone()],
172            Self::Array(parts) => parts
173                .iter()
174                .map(|part| {
175                    let ChatCompletionRequestSystemMessageContentPart::Text(text_part) = part;
176                    text_part.text.clone()
177                })
178                .collect(),
179        }
180    }
181}
182
183#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
184#[serde(tag = "type")]
185#[serde(rename_all = "snake_case")]
186pub enum ChatCompletionRequestSystemMessageContentPart {
187    Text(ChatCompletionRequestMessageContentPartText),
188}
189
190#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
191#[serde(untagged)]
192pub enum ChatCompletionRequestToolMessageContent {
193    Text(String),
194    Array(Vec<ChatCompletionRequestToolMessageContentPart>),
195}
196
197#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
198#[builder(name = "ChatCompletionRequestSystemMessageArgs")]
199#[builder(pattern = "mutable")]
200#[builder(setter(into, strip_option), default)]
201#[builder(derive(Debug))]
202#[builder(build_fn(error = "OpenAIError"))]
203pub struct ChatCompletionRequestSystemMessage {
204    /// The contents of the system message.
205    pub content: ChatCompletionRequestSystemMessageContent,
206    /// An optional name for the participant. Provides the model information to differentiate
207    /// between participants of the same role.
208    #[serde(skip_serializing_if = "Option::is_none")]
209    pub name: Option<String>,
210}
211
212impl ChatCompletionRequestSystemMessage {
213    pub fn to_texts(&self) -> Vec<String> {
214        self.content.to_texts()
215    }
216}
217
218#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
219#[builder(name = "ChatCompletionRequestMessageContentPartTextArgs")]
220#[builder(pattern = "mutable")]
221#[builder(setter(into, strip_option), default)]
222#[builder(derive(Debug))]
223#[builder(build_fn(error = "OpenAIError"))]
224pub struct ChatCompletionRequestMessageContentPartText {
225    pub text: String,
226}
227
228#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
229pub struct ChatCompletionRequestMessageContentPartRefusal {
230    /// The refusal message generated by the model.
231    pub refusal: String,
232}
233
234#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
235#[serde(rename_all = "lowercase")]
236pub enum ImageDetail {
237    #[default]
238    Auto,
239    Low,
240    High,
241}
242
243#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
244#[builder(name = "ImageUrlBuilder")]
245#[builder(pattern = "mutable")]
246#[builder(setter(into, strip_option), default)]
247#[builder(derive(Debug))]
248#[builder(build_fn(error = "OpenAIError"))]
249pub struct ImageUrl {
250    /// Either a URL of the image or the base64 encoded image data.
251    pub url: String,
252    /// Specifies the detail level of the image. Learn more in the [Vision guide](https://platform.openai.com/docs/guides/vision/low-or-high-fidelity-image-understanding).
253    pub detail: Option<ImageDetail>,
254}
255
256#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
257#[builder(name = "ChatCompletionRequestMessageContentPartImageBuilder")]
258#[builder(pattern = "mutable")]
259#[builder(setter(into, strip_option), default)]
260#[builder(derive(Debug))]
261#[builder(build_fn(error = "OpenAIError"))]
262pub struct ChatCompletionRequestMessageContentPartImage {
263    pub image_url: ImageUrl,
264}
265
266#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
267#[serde(rename_all = "lowercase")]
268pub enum InputAudioFormat {
269    Wav,
270    #[default]
271    Mp3,
272}
273
274#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
275pub struct InputAudio {
276    /// Base64 encoded audio data.
277    pub data: String,
278    /// The format of the encoded audio data. Currently supports "wav" and "mp3".
279    pub format: InputAudioFormat,
280}
281
282/// Learn about [audio inputs](https://platform.openai.com/docs/guides/audio).
283#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
284#[builder(name = "ChatCompletionRequestMessageContentPartAudioBuilder")]
285#[builder(pattern = "mutable")]
286#[builder(setter(into, strip_option), default)]
287#[builder(derive(Debug))]
288#[builder(build_fn(error = "OpenAIError"))]
289pub struct ChatCompletionRequestMessageContentPartAudio {
290    pub input_audio: InputAudio,
291}
292
293#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
294#[serde(tag = "type")]
295#[serde(rename_all = "snake_case")]
296pub enum ChatCompletionRequestUserMessageContentPart {
297    Text(TextObject),
298    ImageUrl(ChatCompletionRequestMessageContentPartImage),
299    InputAudio(ChatCompletionRequestMessageContentPartAudio),
300}
301
302#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
303#[serde(tag = "type")]
304#[serde(rename_all = "snake_case")]
305pub enum ChatCompletionRequestAssistantMessageContentPart {
306    Text(TextObject),
307    Refusal(ChatCompletionRequestMessageContentPartRefusal),
308}
309
310#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
311#[serde(tag = "type")]
312#[serde(rename_all = "snake_case")]
313pub enum ChatCompletionRequestToolMessageContentPart {
314    Text(TextObject),
315}
316
317#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
318#[serde(untagged)]
319pub enum ChatCompletionRequestUserMessageContent {
320    /// The text contents of the message.
321    Text(String),
322    /// An array of content parts with a defined type. Supported options differ based on the [model](https://platform.openai.com/docs/models) being used to generate the response. Can contain text, image, or audio inputs.
323    Array(Vec<ChatCompletionRequestUserMessageContentPart>),
324}
325impl ChatCompletionRequestUserMessageContent {
326    pub fn to_texts(&self) -> Vec<String> {
327        match self {
328            ChatCompletionRequestUserMessageContent::Text(text) => vec![text.clone()],
329            ChatCompletionRequestUserMessageContent::Array(parts) => parts
330                .iter()
331                .filter_map(|part| match part {
332                    ChatCompletionRequestUserMessageContentPart::Text(text) => {
333                        Some(text.text.clone())
334                    }
335                    _ => None,
336                })
337                .collect(),
338        }
339    }
340}
341
342#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
343#[serde(untagged)]
344pub enum ChatCompletionRequestAssistantMessageContent {
345    /// The text contents of the message.
346    Text(String),
347    /// An array of content parts with a defined type. Can be one or more of type `text`, or exactly
348    /// one of type `refusal`.
349    Array(Vec<ChatCompletionRequestAssistantMessageContentPart>),
350}
351impl ChatCompletionRequestAssistantMessageContent {
352    pub fn to_texts(&self) -> Vec<String> {
353        match self {
354            ChatCompletionRequestAssistantMessageContent::Text(text) => vec![text.clone()],
355            ChatCompletionRequestAssistantMessageContent::Array(parts) => parts
356                .iter()
357                .filter_map(|part| match part {
358                    ChatCompletionRequestAssistantMessageContentPart::Text(text) => {
359                        Some(text.text.clone())
360                    }
361                    _ => None,
362                })
363                .collect(),
364        }
365    }
366}
367
368#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
369#[builder(name = "ChatCompletionRequestUserMessageBuilder")]
370#[builder(pattern = "mutable")]
371#[builder(setter(into, strip_option), default)]
372#[builder(derive(Debug))]
373#[builder(build_fn(error = "OpenAIError"))]
374pub struct ChatCompletionRequestUserMessage {
375    /// The contents of the user message.
376    pub content: ChatCompletionRequestUserMessageContent,
377    /// An optional name for the participant. Provides the model information to differentiate
378    /// between participants of the same role.
379    #[serde(skip_serializing_if = "Option::is_none")]
380    pub name: Option<String>,
381}
382impl ChatCompletionRequestUserMessage {
383    pub fn new(content: impl Into<ChatCompletionRequestUserMessageContent>) -> Self {
384        Self {
385            content: content.into(),
386            name: None,
387        }
388    }
389    pub fn to_texts(&self) -> Vec<String> {
390        self.content.to_texts()
391    }
392}
393
394#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
395pub struct ChatCompletionRequestAssistantMessageAudio {
396    /// Unique identifier for a previous audio response from the model.
397    pub id: String,
398}
399
400#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
401#[builder(name = "ChatCompletionRequestAssistantMessageBuilder")]
402#[builder(pattern = "mutable")]
403#[builder(setter(into, strip_option), default)]
404#[builder(derive(Debug))]
405#[builder(build_fn(error = "OpenAIError"))]
406pub struct ChatCompletionRequestAssistantMessage {
407    /// The contents of the assistant message. Required unless `tool_calls` or `function_call` is
408    /// specified.
409    #[serde(skip_serializing_if = "Option::is_none")]
410    pub content: Option<ChatCompletionRequestAssistantMessageContent>,
411    /// The refusal message by the assistant.
412    #[serde(skip_serializing_if = "Option::is_none")]
413    pub refusal: Option<String>,
414    /// An optional name for the participant. Provides the model information to differentiate
415    /// between participants of the same role.
416    #[serde(skip_serializing_if = "Option::is_none")]
417    pub name: Option<String>,
418    /// Data about a previous audio response from the model.
419    /// [Learn more](https://platform.openai.com/docs/guides/audio).
420    #[serde(skip_serializing_if = "Option::is_none")]
421    pub audio: Option<ChatCompletionRequestAssistantMessageAudio>,
422    #[serde(skip_serializing_if = "Option::is_none")]
423    pub tool_calls: Option<Vec<ChatCompletionMessageToolCall>>,
424}
425impl ChatCompletionRequestAssistantMessage {
426    pub fn to_texts(&self) -> Vec<String> {
427        self.content
428            .as_ref()
429            .map_or_else(Vec::new, |content| content.to_texts())
430    }
431}
432
433/// Tool message
434#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
435#[builder(name = "ChatCompletionRequestToolMessageBuilder")]
436#[builder(pattern = "mutable")]
437#[builder(setter(into, strip_option), default)]
438#[builder(derive(Debug))]
439#[builder(build_fn(error = "OpenAIError"))]
440pub struct ChatCompletionRequestToolMessage {
441    /// The contents of the tool message.
442    pub content: PartibleTextContent,
443    pub tool_call_id: String,
444}
445impl ChatCompletionRequestToolMessage {
446    pub fn to_texts(&self) -> Vec<String> {
447        self.content.to_texts()
448    }
449}
450
451#[derive(Debug, Serialize, Deserialize, Default, Clone, Builder, PartialEq)]
452#[builder(name = "ChatCompletionRequestFunctionMessageBuilder")]
453#[builder(pattern = "mutable")]
454#[builder(setter(into, strip_option), default)]
455#[builder(derive(Debug))]
456#[builder(build_fn(error = "OpenAIError"))]
457pub struct ChatCompletionRequestFunctionMessage {
458    /// The return value from the function call, to return to the model.
459    pub content: Option<String>,
460    /// The name of the function to call.
461    pub name: String,
462}
463impl ChatCompletionRequestFunctionMessage {
464    pub fn to_texts(&self) -> Vec<String> {
465        self.content
466            .as_ref()
467            .map_or_else(Vec::new, |content| vec![content.clone()])
468    }
469}
470
471#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
472#[serde(tag = "role")]
473#[serde(rename_all = "lowercase")]
474pub enum ChatCompletionRequestMessage {
475    Developer(ChatCompletionRequestDeveloperMessage),
476    System(ChatCompletionRequestSystemMessage),
477    User(ChatCompletionRequestUserMessage),
478    Assistant(ChatCompletionRequestAssistantMessage),
479    Tool(ChatCompletionRequestToolMessage),
480    Function(ChatCompletionRequestFunctionMessage),
481}
482impl ChatCompletionRequestMessage {
483    pub fn to_texts(&self) -> Vec<String> {
484        match self {
485            ChatCompletionRequestMessage::Developer(msg) => msg.to_texts(),
486            ChatCompletionRequestMessage::System(msg) => msg.to_texts(),
487            ChatCompletionRequestMessage::User(msg) => msg.to_texts(),
488            ChatCompletionRequestMessage::Assistant(msg) => msg.to_texts(),
489            ChatCompletionRequestMessage::Tool(msg) => msg.to_texts(),
490            ChatCompletionRequestMessage::Function(msg) => msg.to_texts(),
491        }
492    }
493}
494
495#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
496pub struct ChatCompletionMessageToolCall {
497    /// The ID of the tool call.
498    pub id: String,
499    /// The type of the tool. Currently, only `function` is supported.
500    #[serde(rename = "type")]
501    pub kind: ChatCompletionToolType,
502    /// The function that the model called.
503    pub function: FunctionCall,
504}
505
506#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
507pub struct ChatCompletionResponseMessageAudio {
508    /// Unique identifier for this audio response.
509    pub id: String,
510    /// The Unix timestamp (in seconds) for when this audio response will no longer be accessible
511    /// on the server for use in multi-turn conversations.
512    pub expires_at: u32,
513    /// Base64 encoded audio bytes generated by the model, in the format specified in the request.
514    pub data: String,
515    /// Transcript of the audio generated by the model.
516    pub transcript: String,
517}
518
519/// A chat completion message generated by the model.
520#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
521pub struct ChatCompletionResponseMessage {
522    /// The contents of the message.
523    pub content: Option<String>,
524    /// The refusal message generated by the model.
525    pub refusal: Option<String>,
526    /// The tool calls generated by the model, such as function calls.
527    pub tool_calls: Option<Vec<ChatCompletionMessageToolCall>>,
528
529    /// The role of the author of this message.
530    pub role: Role,
531
532    /// If the audio output modality is requested, this object contains data about the audio response from the model. [Learn more](https://platform.openai.com/docs/guides/audio).
533    pub audio: Option<ChatCompletionResponseMessageAudio>,
534}
535
536#[derive(Clone, Serialize, Default, Debug, Deserialize, Builder, PartialEq)]
537#[builder(name = "FunctionObjectBuilder")]
538#[builder(pattern = "mutable")]
539#[builder(setter(into, strip_option), default)]
540#[builder(derive(Debug))]
541#[builder(build_fn(error = "OpenAIError"))]
542pub struct FunctionObject {
543    /// The name of the function to be called. Must be a-z, A-Z, 0-9, or contain underscores and
544    /// dashes, with a maximum length of 64.
545    pub name: String,
546    /// A description of what the function does, used by the model to choose when and how to call
547    /// the function.
548    #[serde(skip_serializing_if = "Option::is_none")]
549    pub description: Option<String>,
550    /// The parameters the functions accepts, described as a JSON Schema object. See the [guide](https://platform.openai.com/docs/guides/text-generation/function-calling) for examples, and the [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for documentation about the format.
551    ///
552    /// Omitting `parameters` defines a function with an empty parameter list.
553    #[serde(skip_serializing_if = "Option::is_none")]
554    pub parameters: Option<serde_json::Value>,
555
556    /// Whether to enable strict schema adherence when generating the function call. If set to true, the model will follow the exact schema defined in the `parameters` field. Only a subset of JSON Schema is supported when `strict` is `true`. Learn more about Structured Outputs in the [function calling guide](https://platform.openai.com/docs/guides/function-calling).
557    #[serde(skip_serializing_if = "Option::is_none")]
558    pub strict: Option<bool>,
559}
560
561#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
562#[serde(tag = "type", rename_all = "snake_case")]
563pub enum ResponseFormat {
564    /// The type of response format being defined: `text`
565    Text,
566    /// The type of response format being defined: `json_object`
567    JsonObject,
568    /// The type of response format being defined: `json_schema`
569    JsonSchema {
570        json_schema: ResponseFormatJsonSchema,
571    },
572}
573
574#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
575pub struct ResponseFormatJsonSchema {
576    /// A description of what the response format is for, used by the model to determine how to
577    /// respond in the format.
578    #[serde(skip_serializing_if = "Option::is_none")]
579    pub description: Option<String>,
580    /// The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and dashes,
581    /// with a maximum length of 64.
582    pub name: String,
583    /// The schema for the response format, described as a JSON Schema object.
584    #[serde(skip_serializing_if = "Option::is_none")]
585    pub schema: Option<serde_json::Value>,
586    /// Whether to enable strict schema adherence when generating the output. If set to true, the model will always follow the exact schema defined in the `schema` field. Only a subset of JSON Schema is supported when `strict` is `true`. To learn more, read the [Structured Outputs guide](https://platform.openai.com/docs/guides/structured-outputs).
587    #[serde(skip_serializing_if = "Option::is_none")]
588    pub strict: Option<bool>,
589}
590
591#[derive(Clone, Serialize, Default, Debug, Deserialize, PartialEq)]
592#[serde(rename_all = "lowercase")]
593pub enum ChatCompletionToolType {
594    #[default]
595    Function,
596}
597
598#[derive(Clone, Serialize, Default, Debug, Builder, Deserialize, PartialEq)]
599#[builder(name = "ChatCompletionToolBuilder")]
600#[builder(pattern = "mutable")]
601#[builder(setter(into, strip_option), default)]
602#[builder(derive(Debug))]
603#[builder(build_fn(error = "OpenAIError"))]
604pub struct ChatCompletionTool {
605    #[builder(default = "ChatCompletionToolType::Function")]
606    #[serde(rename = "type")]
607    pub kind: ChatCompletionToolType,
608    pub function: FunctionObject,
609}
610
611#[derive(Clone, Serialize, Default, Debug, Deserialize, PartialEq)]
612pub struct FunctionName {
613    /// The name of the function to call.
614    pub name: String,
615}
616
617/// Specifies a tool the model should use. Use to force the model to call a specific function.
618#[derive(Clone, Serialize, Default, Debug, Deserialize, PartialEq)]
619pub struct ChatCompletionNamedToolChoice {
620    pub function: FunctionName,
621}
622
623/// Controls which (if any) tool is called by the model.
624/// `none` means the model will not call any tool and instead generates a message.
625/// `auto` means the model can pick between generating a message or calling one or more tools.
626/// `required` means the model must call one or more tools.
627/// Specifying a particular tool via `{"type": "function", "function": {"name": "my_function"}}`
628/// forces the model to call that tool.
629///
630/// `none` is the default when no tools are present. `auto` is the default if tools are
631/// present.present.
632#[derive(Clone, Serialize, Default, Debug, Deserialize, PartialEq)]
633#[serde(rename_all = "lowercase")]
634pub enum ChatCompletionToolChoiceOption {
635    #[default]
636    None,
637    Auto,
638    Required,
639    #[serde(untagged)]
640    Named(ChatCompletionNamedToolChoice),
641}
642
643#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
644#[serde(rename_all = "lowercase")]
645/// The amount of context window space to use for the search.
646pub enum WebSearchContextSize {
647    Low,
648    #[default]
649    Medium,
650    High,
651}
652
653#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
654#[serde(rename_all = "lowercase")]
655pub enum WebSearchUserLocationType {
656    Approximate,
657}
658
659/// Approximate location parameters for the search.
660#[derive(Clone, Serialize, Debug, Default, Deserialize, PartialEq)]
661pub struct WebSearchLocation {
662    ///  The two-letter [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1) of the user, e.g. `US`.
663    pub country: Option<String>,
664    /// Free text input for the region of the user, e.g. `California`.
665    pub region: Option<String>,
666    /// Free text input for the city of the user, e.g. `San Francisco`.
667    pub city: Option<String>,
668    /// The [IANA timezone](https://timeapi.io/documentation/iana-timezones) of the user, e.g. `America/Los_Angeles`.
669    pub timezone: Option<String>,
670}
671
672#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
673pub struct WebSearchUserLocation {
674    //  The type of location approximation. Always `approximate`.
675    #[serde(rename = "type")]
676    pub kind: WebSearchUserLocationType,
677
678    pub approximate: WebSearchLocation,
679}
680
681/// Options for the web search tool.
682#[derive(Clone, Serialize, Debug, Default, Deserialize, PartialEq)]
683pub struct WebSearchOptions {
684    /// High level guidance for the amount of context window space to use for the search. One of
685    /// `low`, `medium`, or `high`. `medium` is the default.
686    pub search_context_size: Option<WebSearchContextSize>,
687
688    /// Approximate location parameters for the search.
689    pub user_location: Option<WebSearchUserLocation>,
690}
691
692#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
693#[serde(rename_all = "lowercase")]
694pub enum ServiceTier {
695    Auto,
696    Default,
697    Flex,
698}
699
700#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
701#[serde(rename_all = "lowercase")]
702pub enum ServiceTierResponse {
703    Scale,
704    Default,
705    Flex,
706}
707
708#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
709#[serde(rename_all = "lowercase")]
710pub enum ReasoningEffort {
711    Low,
712    Medium,
713    High,
714}
715
716/// Output types that you would like the model to generate for this request.
717///
718/// Most models are capable of generating text, which is the default: `["text"]`
719///
720/// The `gpt-4o-audio-preview` model can also be used to [generate
721/// audio](https://platform.openai.com/docs/guides/audio). To request that this model generate both text and audio responses, you can use: `["text", "audio"]`
722#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
723#[serde(rename_all = "lowercase")]
724pub enum ChatCompletionModalities {
725    Text,
726    Audio,
727}
728
729/// Static predicted output content, such as the content of a text file that is being regenerated.
730#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
731#[serde(tag = "type", rename_all = "lowercase", content = "content")]
732pub enum PredictionContent {
733    /// The type of the predicted content you want to provide. This type is
734    /// currently always `content`.
735    Content(PartibleTextContent),
736}
737
738#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
739#[serde(rename_all = "lowercase")]
740pub enum ChatCompletionAudioVoice {
741    Alloy,
742    Ash,
743    Ballad,
744    Coral,
745    Echo,
746    Sage,
747    Shimmer,
748    Verse,
749}
750
751#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
752#[serde(rename_all = "lowercase")]
753pub enum ChatCompletionAudioFormat {
754    Wav,
755    Mp3,
756    Flac,
757    Opus,
758    Pcm16,
759}
760
761#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
762pub struct ChatCompletionAudio {
763    /// The voice the model uses to respond. Supported voices are `ash`, `ballad`, `coral`, `sage`,
764    /// and `verse` (also supported but not recommended are `alloy`, `echo`, and `shimmer`; these
765    /// voices are less expressive).
766    pub voice: ChatCompletionAudioVoice,
767    /// Specifies the output audio format. Must be one of `wav`, `mp3`, `flac`, `opus`, or `pcm16`.
768    pub format: ChatCompletionAudioFormat,
769}
770
771#[derive(Clone, Serialize, Default, Debug, Builder, Deserialize, PartialEq)]
772#[builder(name = "CreateChatCompletionRequestBuilder")]
773#[builder(pattern = "mutable")]
774#[builder(setter(into, strip_option), default)]
775#[builder(derive(Debug))]
776#[builder(build_fn(error = "OpenAIError"))]
777pub struct CreateChatCompletionRequest {
778    /// A list of messages comprising the conversation so far. Depending on the [model](https://platform.openai.com/docs/models) you use, different message types (modalities) are supported, like [text](https://platform.openai.com/docs/guides/text-generation), [images](https://platform.openai.com/docs/guides/vision), and [audio](https://platform.openai.com/docs/guides/audio).
779    pub messages: Vec<ChatCompletionRequestMessage>, // min: 1
780
781    /// ID of the model to use.
782    /// See the [model endpoint compatibility](https://platform.openai.com/docs/models#model-endpoint-compatibility) table for details on which models work with the Chat API.
783    pub model: String,
784
785    /// Whether or not to store the output of this chat completion request
786    ///
787    /// for use in our [model distillation](https://platform.openai.com/docs/guides/distillation) or [evals](https://platform.openai.com/docs/guides/evals) products.
788    #[serde(skip_serializing_if = "Option::is_none")]
789    pub store: Option<bool>, // nullable: true, default: false
790
791    /// **o1 models only**
792    ///
793    /// Constrains effort on reasoning for
794    /// [reasoning models](https://platform.openai.com/docs/guides/reasoning).
795    ///
796    /// Currently supported values are `low`, `medium`, and `high`. Reducing
797    ///
798    /// reasoning effort can result in faster responses and fewer tokens
799    /// used on reasoning in a response.
800    #[serde(skip_serializing_if = "Option::is_none")]
801    pub reasoning_effort: Option<ReasoningEffort>,
802
803    ///  Developer-defined tags and values used for filtering completions in the [dashboard](https://platform.openai.com/chat-completions).
804    #[serde(skip_serializing_if = "Option::is_none")]
805    pub metadata: Option<serde_json::Value>, // nullable: true
806
807    /// Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing
808    /// frequency in the text so far, decreasing the model's likelihood to repeat the same line
809    /// verbatim.
810    #[serde(skip_serializing_if = "Option::is_none")]
811    pub frequency_penalty: Option<f32>, // min: -2.0, max: 2.0, default: 0
812
813    /// Modify the likelihood of specified tokens appearing in the completion.
814    ///
815    /// Accepts a json object that maps tokens (specified by their token ID in the tokenizer) to an
816    /// associated bias value from -100 to 100. Mathematically, the bias is added to the logits
817    /// generated by the model prior to sampling. The exact effect will vary per model, but
818    /// values between -1 and 1 should decrease or increase likelihood of selection;
819    /// values like -100 or 100 should result in a ban or exclusive selection of the relevant
820    /// token.
821    #[serde(skip_serializing_if = "Option::is_none")]
822    pub logit_bias: Option<HashMap<String, serde_json::Value>>, // default: null
823
824    /// Whether to return log probabilities of the output tokens or not. If true, returns the log
825    /// probabilities of each output token returned in the `content` of `message`.
826    #[serde(skip_serializing_if = "Option::is_none")]
827    pub logprobs: Option<bool>,
828
829    /// An integer between 0 and 20 specifying the number of most likely tokens to return at each
830    /// token position, each with an associated log probability. `logprobs` must be set to `true`
831    /// if this parameter is used.
832    #[serde(skip_serializing_if = "Option::is_none")]
833    pub top_logprobs: Option<u8>,
834
835    /// An upper bound for the number of tokens that can be generated for a completion, including visible output tokens and [reasoning tokens](https://platform.openai.com/docs/guides/reasoning).
836    #[serde(skip_serializing_if = "Option::is_none")]
837    pub max_completion_tokens: Option<u32>,
838
839    /// How many chat completion choices to generate for each input message. Note that you will be
840    /// charged based on the number of generated tokens across all of the choices. Keep `n` as `1`
841    /// to minimize costs.
842    #[serde(skip_serializing_if = "Option::is_none")]
843    pub n: Option<u8>, // min:1, max: 128, default: 1
844
845    #[serde(skip_serializing_if = "Option::is_none")]
846    pub modalities: Option<Vec<ChatCompletionModalities>>,
847
848    /// Configuration for a [Predicted Output](https://platform.openai.com/docs/guides/predicted-outputs),which can greatly improve response times when large parts of the model response are known ahead of time. This is most common when you are regenerating a file with only minor changes to most of the content.
849    #[serde(skip_serializing_if = "Option::is_none")]
850    pub prediction: Option<PredictionContent>,
851
852    /// Parameters for audio output. Required when audio output is requested with `modalities: ["audio"]`. [Learn more](https://platform.openai.com/docs/guides/audio).
853    #[serde(skip_serializing_if = "Option::is_none")]
854    pub audio: Option<ChatCompletionAudio>,
855
856    /// Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they
857    /// appear in the text so far, increasing the model's likelihood to talk about new topics.
858    #[serde(skip_serializing_if = "Option::is_none")]
859    pub presence_penalty: Option<f32>, // min: -2.0, max: 2.0, default 0
860
861    /// An object specifying the format that the model must output. Compatible with [GPT-4o](https://platform.openai.com/docs/models/gpt-4o), [GPT-4o mini](https://platform.openai.com/docs/models/gpt-4o-mini), [GPT-4 Turbo](https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo) and all GPT-3.5 Turbo models newer than `gpt-3.5-turbo-1106`.
862    ///
863    /// Setting to `{ "type": "json_schema", "json_schema": {...} }` enables Structured Outputs which guarantees the model will match your supplied JSON schema. Learn more in the [Structured Outputs guide](https://platform.openai.com/docs/guides/structured-outputs).
864    ///
865    /// Setting to `{ "type": "json_object" }` enables JSON mode, which guarantees the message the
866    /// model generates is valid JSON.
867    ///
868    /// **Important:** when using JSON mode, you **must** also instruct the model to produce JSON
869    /// yourself via a system or user message. Without this, the model may generate an unending
870    /// stream of whitespace until the generation reaches the token limit, resulting in a
871    /// long-running and seemingly "stuck" request. Also note that the message content may be
872    /// partially cut off if `finish_reason="length"`, which indicates the generation exceeded
873    /// `max_tokens` or the conversation exceeded the max context length.
874    #[serde(skip_serializing_if = "Option::is_none")]
875    pub response_format: Option<ResponseFormat>,
876
877    ///  This feature is in Beta.
878    /// If specified, our system will make a best effort to sample deterministically, such that
879    /// repeated requests with the same `seed` and parameters should return the same result.
880    /// Determinism is not guaranteed, and you should refer to the `system_fingerprint` response
881    /// parameter to monitor changes in the backend.
882    #[serde(skip_serializing_if = "Option::is_none")]
883    pub seed: Option<i64>,
884
885    /// Specifies the latency tier to use for processing the request. This parameter is relevant
886    /// for customers subscribed to the scale tier service:
887    /// - If set to 'auto', the system will utilize scale tier credits until they are exhausted.
888    /// - If set to 'default', the request will be processed using the default service tier with a
889    ///   lower uptime SLA and no latency guarantee.
890    /// - When not set, the default behavior is 'auto'.
891    ///
892    /// When this parameter is set, the response body will include the `service_tier` utilized.
893    #[serde(skip_serializing_if = "Option::is_none")]
894    pub service_tier: Option<ServiceTier>,
895
896    /// Up to 4 sequences where the API will stop generating further tokens.
897    #[serde(skip_serializing_if = "Option::is_none")]
898    pub stop: Option<Stop>,
899
900    /// If set, partial message deltas will be sent, like in ChatGPT.
901    /// Tokens will be sent as data-only [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format)
902    /// as they become available, with the stream terminated by a `data: [DONE]` message. [Example Python code](https://cookbook.openai.com/examples/how_to_stream_completions).
903    #[serde(skip_serializing_if = "Option::is_none")]
904    pub stream: Option<bool>,
905
906    #[serde(skip_serializing_if = "Option::is_none")]
907    pub stream_options: Option<ChatCompletionStreamOptions>,
908
909    /// What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the
910    /// output more random, while lower values like 0.2 will make it more focused and
911    /// deterministic.
912    ///
913    /// We generally recommend altering this or `top_p` but not both.
914    #[serde(skip_serializing_if = "Option::is_none")]
915    pub temperature: Option<f32>, // min: 0, max: 2, default: 1,
916
917    /// An alternative to sampling with temperature, called nucleus sampling,
918    /// where the model considers the results of the tokens with top_p probability mass.
919    /// So 0.1 means only the tokens comprising the top 10% probability mass are considered.
920    ///
921    ///  We generally recommend altering this or `temperature` but not both.
922    #[serde(skip_serializing_if = "Option::is_none")]
923    pub top_p: Option<f32>, // min: 0, max: 1, default: 1
924
925    /// A list of tools the model may call. Currently, only functions are supported as a tool.
926    /// Use this to provide a list of functions the model may generate JSON inputs for. A max of
927    /// 128 functions are supported.
928    #[serde(skip_serializing_if = "Option::is_none")]
929    pub tools: Option<Vec<ChatCompletionTool>>,
930
931    #[serde(skip_serializing_if = "Option::is_none")]
932    pub tool_choice: Option<ChatCompletionToolChoiceOption>,
933
934    /// Whether to enable [parallel function calling](https://platform.openai.com/docs/guides/function-calling/parallel-function-calling) during tool use.
935    #[serde(skip_serializing_if = "Option::is_none")]
936    pub parallel_tool_calls: Option<bool>,
937
938    /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#end-user-ids).
939    #[serde(skip_serializing_if = "Option::is_none")]
940    pub user: Option<String>,
941
942    /// This tool searches the web for relevant results to use in a response.
943    /// Learn more about the [web search tool](https://platform.openai.com/docs/guides/tools-web-search?api-mode=chat).
944    #[serde(skip_serializing_if = "Option::is_none")]
945    pub web_search_options: Option<WebSearchOptions>,
946}
947
948impl CreateChatCompletionRequest {
949    /// Creates a new chat completion request with the specified model and messages.
950    pub fn new(model: impl Into<String>, messages: Vec<ChatCompletionRequestMessage>) -> Self {
951        Self {
952            model: model.into(),
953            messages,
954            ..Default::default()
955        }
956    }
957}
958
959/// Options for streaming response. Only set this when you set `stream: true`.
960#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
961pub struct ChatCompletionStreamOptions {
962    /// If set, an additional chunk will be streamed before the `data: [DONE]` message. The `usage`
963    /// field on this chunk shows the token usage statistics for the entire request, and the
964    /// `choices` field will always be an empty array. All other chunks will also include a `usage`
965    /// field, but with a null value.
966    pub include_usage: bool,
967}
968
969#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
970#[serde(rename_all = "snake_case")]
971pub enum FinishReason {
972    Stop,
973    Length,
974    ToolCalls,
975    ContentFilter,
976    FunctionCall,
977}
978
979#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
980pub struct TopLogprobs {
981    /// The token.
982    pub token: String,
983    /// The log probability of this token.
984    pub logprob: f32,
985    /// A list of integers representing the UTF-8 bytes representation of the token. Useful in
986    /// instances where characters are represented by multiple tokens and their byte
987    /// representations must be combined to generate the correct text representation. Can be `null`
988    /// if there is no bytes representation for the token.
989    pub bytes: Option<Vec<u8>>,
990}
991
992#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
993pub struct ChatCompletionTokenLogprob {
994    /// The token.
995    pub token: String,
996    /// The log probability of this token, if it is within the top 20 most likely tokens.
997    /// Otherwise, the value `-9999.0` is used to signify that the token is very unlikely.
998    pub logprob: f32,
999    /// A list of integers representing the UTF-8 bytes representation of the token. Useful in
1000    /// instances where characters are represented by multiple tokens and their byte
1001    /// representations must be combined to generate the correct text representation. Can be `null`
1002    /// if there is no bytes representation for the token.
1003    pub bytes: Option<Vec<u8>>,
1004    ///  List of the most likely tokens and their log probability, at this token position. In rare
1005    /// cases, there may be fewer than the number of requested `top_logprobs` returned.
1006    pub top_logprobs: Vec<TopLogprobs>,
1007}
1008
1009#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
1010pub struct ChatChoiceLogprobs {
1011    /// A list of message content tokens with log probability information.
1012    pub content: Option<Vec<ChatCompletionTokenLogprob>>,
1013    pub refusal: Option<Vec<ChatCompletionTokenLogprob>>,
1014}
1015
1016#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
1017pub struct ChatChoice {
1018    /// The index of the choice in the list of choices.
1019    pub index: u32,
1020    pub message: ChatCompletionResponseMessage,
1021    /// The reason the model stopped generating tokens. This will be `stop` if the model hit a
1022    /// natural stop point or a provided stop sequence, `length` if the maximum number of
1023    /// tokens specified in the request was reached, `content_filter` if content was omitted
1024    /// due to a flag from our content filters, `tool_calls` if the model called a tool, or
1025    /// `function_call` (deprecated) if the model called a function.
1026    pub finish_reason: Option<FinishReason>,
1027    /// Log probability information for the choice.
1028    pub logprobs: Option<ChatChoiceLogprobs>,
1029}
1030
1031/// Represents a chat completion response returned by model, based on the provided input.
1032#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
1033pub struct CreateChatCompletionResponse {
1034    /// A unique identifier for the chat completion.
1035    pub id: String,
1036    /// A list of chat completion choices. Can be more than one if `n` is greater than 1.
1037    pub choices: Vec<ChatChoice>,
1038    /// The Unix timestamp (in seconds) of when the chat completion was created.
1039    pub created: u32,
1040    /// The model used for the chat completion.
1041    pub model: String,
1042    /// The service tier used for processing the request. This field is only included if the
1043    /// `service_tier` parameter is specified in the request.
1044    pub service_tier: Option<ServiceTierResponse>,
1045    /// This fingerprint represents the backend configuration that the model runs with.
1046    ///
1047    /// Can be used in conjunction with the `seed` request parameter to understand when backend
1048    /// changes have been made that might impact determinism.
1049    pub system_fingerprint: Option<String>,
1050
1051    /// The object type, which is always `chat.completion`.
1052    pub object: String,
1053    pub usage: Option<CompletionUsage>,
1054}
1055
1056/// Parsed server side events stream until an \[DONE\] is received from server.
1057pub type ChatCompletionResponseStream =
1058    Pin<Box<dyn Stream<Item = Result<CreateChatCompletionStreamResponse, OpenAIError>> + Send>>;
1059
1060#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
1061pub struct FunctionCallStream {
1062    /// The name of the function to call.
1063    pub name: Option<String>,
1064    /// The arguments to call the function with, as generated by the model in JSON format.
1065    /// Note that the model does not always generate valid JSON, and may hallucinate
1066    /// parameters not defined by your function schema. Validate the arguments in your
1067    /// code before calling your function.
1068    pub arguments: Option<String>,
1069}
1070
1071#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
1072pub struct ChatCompletionMessageToolCallChunk {
1073    pub index: u32,
1074    /// The ID of the tool call.
1075    pub id: Option<String>,
1076    /// The type of the tool. Currently, only `function` is supported.
1077    #[serde(rename = "type")]
1078    pub kind: Option<ChatCompletionToolType>,
1079    pub function: Option<FunctionCallStream>,
1080}
1081
1082/// A chat completion delta generated by streamed model responses.
1083#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
1084pub struct ChatCompletionStreamResponseDelta {
1085    /// The contents of the chunk message.
1086    pub content: Option<String>,
1087
1088    pub tool_calls: Option<Vec<ChatCompletionMessageToolCallChunk>>,
1089    /// The role of the author of this message.
1090    pub role: Option<Role>,
1091    /// The refusal message generated by the model.
1092    pub refusal: Option<String>,
1093}
1094
1095#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
1096pub struct ChatChoiceStream {
1097    /// The index of the choice in the list of choices.
1098    pub index: u32,
1099    pub delta: ChatCompletionStreamResponseDelta,
1100    /// The reason the model stopped generating tokens. This will be
1101    /// `stop` if the model hit a natural stop point or a provided
1102    /// stop sequence,
1103    ///
1104    /// `length` if the maximum number of tokens specified in the
1105    /// request was reached,
1106    /// `content_filter` if content was omitted due to a flag from our
1107    /// content filters,
1108    /// `tool_calls` if the model called a tool, or `function_call`
1109    /// (deprecated) if the model called a function.
1110    pub finish_reason: Option<FinishReason>,
1111    /// Log probability information for the choice.
1112    pub logprobs: Option<ChatChoiceLogprobs>,
1113}
1114
1115#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
1116/// Represents a streamed chunk of a chat completion response returned by model, based on the
1117/// provided input.
1118pub struct CreateChatCompletionStreamResponse {
1119    /// A unique identifier for the chat completion. Each chunk has the same ID.
1120    pub id: String,
1121    /// A list of chat completion choices. Can contain more than one elements if `n` is greater
1122    /// than 1. Can also be empty for the last chunk if you set `stream_options: {"include_usage":
1123    /// true}`.
1124    pub choices: Vec<ChatChoiceStream>,
1125
1126    /// The Unix timestamp (in seconds) of when the chat completion was created. Each chunk has the
1127    /// same timestamp.
1128    pub created: u32,
1129    /// The model to generate the completion.
1130    pub model: String,
1131    /// The service tier used for processing the request. This field is only included if the
1132    /// `service_tier` parameter is specified in the request.
1133    pub service_tier: Option<ServiceTierResponse>,
1134    /// This fingerprint represents the backend configuration that the model runs with.
1135    /// Can be used in conjunction with the `seed` request parameter to understand when backend
1136    /// changes have been made that might impact determinism.
1137    pub system_fingerprint: Option<String>,
1138    /// The object type, which is always `chat.completion.chunk`.
1139    pub object: String,
1140
1141    /// An optional field that will only be present when you set `stream_options: {"include_usage":
1142    /// true}` in your request. When present, it contains a null value except for the last
1143    /// chunk which contains the token usage statistics for the entire request.
1144    pub usage: Option<CompletionUsage>,
1145}
1146
1147/// Type alias for backward compatibility
1148pub type Stop = StopConfiguration;
1149
1150/// List of stored chat completions.
1151#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
1152pub struct ChatCompletionList {
1153    pub object: String,
1154    pub data: Vec<CreateChatCompletionResponse>,
1155    #[serde(skip_serializing_if = "Option::is_none")]
1156    pub first_id: Option<String>,
1157    #[serde(skip_serializing_if = "Option::is_none")]
1158    pub last_id: Option<String>,
1159    pub has_more: bool,
1160}
1161
1162/// Request to update a stored chat completion.
1163#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
1164pub struct UpdateChatCompletionRequest {
1165    /// Set of 16 key-value pairs that can be attached to an object.
1166    #[serde(skip_serializing_if = "Option::is_none")]
1167    pub metadata: Option<std::collections::HashMap<String, String>>,
1168}
1169
1170/// Response when a chat completion is deleted.
1171#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
1172pub struct ChatCompletionDeleted {
1173    pub id: String,
1174    pub object: String,
1175    pub deleted: bool,
1176}
1177
1178/// List of messages for a chat completion.
1179#[derive(Debug, Deserialize, Clone, PartialEq, Serialize)]
1180pub struct ChatCompletionMessageList {
1181    pub object: String,
1182    pub data: Vec<ChatCompletionResponseMessage>,
1183    #[serde(skip_serializing_if = "Option::is_none")]
1184    pub first_id: Option<String>,
1185    #[serde(skip_serializing_if = "Option::is_none")]
1186    pub last_id: Option<String>,
1187    pub has_more: bool,
1188}