async_openai/
chat.rs

1use crate::{
2    config::Config,
3    error::OpenAIError,
4    types::chat::{
5        ChatCompletionDeleted, ChatCompletionList, ChatCompletionMessageList,
6        ChatCompletionResponseStream, CreateChatCompletionRequest, CreateChatCompletionResponse,
7        UpdateChatCompletionRequest,
8    },
9    Client, RequestOptions,
10};
11
12/// Given a list of messages comprising a conversation, the model will return a response.
13///
14/// Related guide: [Chat Completions](https://platform.openai.com/docs/guides/text-generation)
15pub struct Chat<'c, C: Config> {
16    client: &'c Client<C>,
17    pub(crate) request_options: RequestOptions,
18}
19
20impl<'c, C: Config> Chat<'c, C> {
21    pub fn new(client: &'c Client<C>) -> Self {
22        Self {
23            client,
24            request_options: RequestOptions::new(),
25        }
26    }
27
28    /// Creates a model response for the given chat conversation.
29    ///
30    /// Returns a [chat completion](https://platform.openai.com/docs/api-reference/chat/object) object, or a streamed sequence of [chat completion chunk](https://platform.openai.com/docs/api-reference/chat/streaming) objects if the request is streamed.
31    ///
32    /// Learn more in the [text generation](https://platform.openai.com/docs/guides/text-generation), [vision](https://platform.openai.com/docs/guides/vision), and [audio](https://platform.openai.com/docs/guides/audio) guides.
33    ///
34    /// Parameter support can differ depending on the model used to generate the response, particularly for newer reasoning models. Parameters that are only supported for reasoning models are noted below. For the current state of unsupported parameters in reasoning models, [refer to the reasoning guide](https://platform.openai.com/docs/guides/reasoning).
35    ///
36    /// byot: You must ensure "stream: false" in serialized `request`
37    #[crate::byot(
38        T0 = serde::Serialize,
39        R = serde::de::DeserializeOwned
40    )]
41    pub async fn create(
42        &self,
43        request: CreateChatCompletionRequest,
44    ) -> Result<CreateChatCompletionResponse, OpenAIError> {
45        #[cfg(not(feature = "byot"))]
46        {
47            if request.stream.is_some() && request.stream.unwrap() {
48                return Err(OpenAIError::InvalidArgument(
49                    "When stream is true, use Chat::create_stream".into(),
50                ));
51            }
52        }
53        self.client
54            .post("/chat/completions", request, &self.request_options)
55            .await
56    }
57
58    /// Creates a completion for the chat message.
59    ///
60    /// If set to true, the model response data will be streamed to the client as it is generated using [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format).
61    ///
62    /// See the [Streaming section](https://platform.openai.com/docs/api-reference/chat/streaming) for more information, along with the [streaming responses](https://platform.openai.com/docs/guides/streaming-responses) guide for more information on how to handle the streaming events.
63    ///
64    /// [ChatCompletionResponseStream] is a parsed SSE stream until a \[DONE\] is received from server.
65    ///
66    /// byot: You must ensure "stream: true" in serialized `request`
67    #[crate::byot(
68        T0 = serde::Serialize,
69        R = serde::de::DeserializeOwned,
70        stream = "true",
71        where_clause = "R: std::marker::Send + 'static"
72    )]
73    #[allow(unused_mut)]
74    pub async fn create_stream(
75        &self,
76        mut request: CreateChatCompletionRequest,
77    ) -> Result<ChatCompletionResponseStream, OpenAIError> {
78        #[cfg(not(feature = "byot"))]
79        {
80            if request.stream.is_some() && !request.stream.unwrap() {
81                return Err(OpenAIError::InvalidArgument(
82                    "When stream is false, use Chat::create".into(),
83                ));
84            }
85
86            request.stream = Some(true);
87        }
88        Ok(self
89            .client
90            .post_stream("/chat/completions", request, &self.request_options)
91            .await)
92    }
93
94    /// List stored Chat Completions. Only Chat Completions that have been stored
95    /// with the `store` parameter set to `true` will be returned.
96    #[crate::byot(R = serde::de::DeserializeOwned)]
97    pub async fn list(&self) -> Result<ChatCompletionList, OpenAIError> {
98        self.client
99            .get("/chat/completions", &self.request_options)
100            .await
101    }
102
103    /// Get a stored chat completion. Only Chat Completions that have been created
104    /// with the `store` parameter set to `true` will be returned.
105    #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
106    pub async fn retrieve(
107        &self,
108        completion_id: &str,
109    ) -> Result<CreateChatCompletionResponse, OpenAIError> {
110        self.client
111            .get(
112                &format!("/chat/completions/{completion_id}"),
113                &self.request_options,
114            )
115            .await
116    }
117
118    /// Modify a stored chat completion. Only Chat Completions that have been
119    /// created with the `store` parameter set to `true` can be modified. Currently,
120    /// the only supported modification is to update the `metadata` field.
121    #[crate::byot(
122        T0 = std::fmt::Display,
123        T1 = serde::Serialize,
124        R = serde::de::DeserializeOwned
125    )]
126    pub async fn update(
127        &self,
128        completion_id: &str,
129        request: UpdateChatCompletionRequest,
130    ) -> Result<CreateChatCompletionResponse, OpenAIError> {
131        self.client
132            .post(
133                &format!("/chat/completions/{completion_id}"),
134                request,
135                &self.request_options,
136            )
137            .await
138    }
139
140    /// Delete a stored chat completion. Only Chat Completions that have been
141    /// created with the `store` parameter set to `true` can be deleted.
142    #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
143    pub async fn delete(&self, completion_id: &str) -> Result<ChatCompletionDeleted, OpenAIError> {
144        self.client
145            .delete(
146                &format!("/chat/completions/{completion_id}"),
147                &self.request_options,
148            )
149            .await
150    }
151
152    /// Get a list of messages for the specified chat completion.
153    #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
154    pub async fn messages(
155        &self,
156        completion_id: &str,
157    ) -> Result<ChatCompletionMessageList, OpenAIError> {
158        self.client
159            .get(
160                &format!("/chat/completions/{completion_id}/messages"),
161                &self.request_options,
162            )
163            .await
164    }
165}