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