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 self.client
92 .post_stream("/chat/completions", request, &self.request_options)
93 .await
94 }
95
96 /// List stored Chat Completions. Only Chat Completions that have been stored
97 /// with the `store` parameter set to `true` will be returned.
98 #[crate::byot(R = serde::de::DeserializeOwned)]
99 pub async fn list(&self) -> Result<ChatCompletionList, OpenAIError> {
100 self.client
101 .get("/chat/completions", &self.request_options)
102 .await
103 }
104
105 /// Get a stored chat completion. Only Chat Completions that have been created
106 /// with the `store` parameter set to `true` will be returned.
107 #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
108 pub async fn retrieve(
109 &self,
110 completion_id: &str,
111 ) -> Result<CreateChatCompletionResponse, OpenAIError> {
112 self.client
113 .get(
114 &format!("/chat/completions/{completion_id}"),
115 &self.request_options,
116 )
117 .await
118 }
119
120 /// Modify a stored chat completion. Only Chat Completions that have been
121 /// created with the `store` parameter set to `true` can be modified. Currently,
122 /// the only supported modification is to update the `metadata` field.
123 #[crate::byot(
124 T0 = std::fmt::Display,
125 T1 = serde::Serialize,
126 R = serde::de::DeserializeOwned
127 )]
128 pub async fn update(
129 &self,
130 completion_id: &str,
131 request: UpdateChatCompletionRequest,
132 ) -> Result<CreateChatCompletionResponse, OpenAIError> {
133 self.client
134 .post(
135 &format!("/chat/completions/{completion_id}"),
136 request,
137 &self.request_options,
138 )
139 .await
140 }
141
142 /// Delete a stored chat completion. Only Chat Completions that have been
143 /// created with the `store` parameter set to `true` can be deleted.
144 #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
145 pub async fn delete(&self, completion_id: &str) -> Result<ChatCompletionDeleted, OpenAIError> {
146 self.client
147 .delete(
148 &format!("/chat/completions/{completion_id}"),
149 &self.request_options,
150 )
151 .await
152 }
153
154 /// Get a list of messages for the specified chat completion.
155 #[crate::byot(T0 = std::fmt::Display, R = serde::de::DeserializeOwned)]
156 pub async fn messages(
157 &self,
158 completion_id: &str,
159 ) -> Result<ChatCompletionMessageList, OpenAIError> {
160 self.client
161 .get(
162 &format!("/chat/completions/{completion_id}/messages"),
163 &self.request_options,
164 )
165 .await
166 }
167}