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}