Skip to main content

outfox_openai/spec/assistants/
message.rs

1use std::collections::HashMap;
2
3use derive_builder::Builder;
4use serde::{Deserialize, Serialize};
5
6use crate::error::OpenAIError;
7use crate::spec::assistants::{ImageDetail, ImageUrl};
8
9#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
10#[serde(rename_all = "lowercase")]
11pub enum MessageRole {
12    #[default]
13    User,
14    Assistant,
15}
16
17#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
18#[serde(rename_all = "snake_case")]
19pub enum MessageStatus {
20    InProgress,
21    Incomplete,
22    Completed,
23}
24
25#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
26#[serde(rename_all = "snake_case")]
27pub enum MessageIncompleteDetailsType {
28    ContentFilter,
29    MaxTokens,
30    RunCancelled,
31    RunExpired,
32    RunFailed,
33}
34
35#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
36pub struct MessageIncompleteDetails {
37    /// The reason the message is incomplete.
38    pub reason: MessageIncompleteDetailsType,
39}
40
41///  Represents a message within a [thread](https://platform.openai.com/docs/api-reference/threads).
42#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
43pub struct MessageObject {
44    /// The identifier, which can be referenced in API endpoints.
45    pub id: String,
46    /// The object type, which is always `thread.message`.
47    pub object: String,
48    /// The Unix timestamp (in seconds) for when the message was created.
49    pub created_at: u64,
50    /// The [thread](https://platform.openai.com/docs/api-reference/threads) ID that this message belongs to.
51    pub thread_id: String,
52
53    /// The status of the message, which can be either `in_progress`, `incomplete`, or `completed`.
54    pub status: Option<MessageStatus>,
55
56    /// On an incomplete message, details about why the message is incomplete.
57    pub incomplete_details: Option<MessageIncompleteDetails>,
58
59    /// The Unix timestamp (in seconds) for when the message was completed.
60    pub completed_at: Option<u64>,
61
62    /// The Unix timestamp (in seconds) for when the message was marked as incomplete.
63    pub incomplete_at: Option<u64>,
64
65    /// The entity that produced the message. One of `user` or `assistant`.
66    pub role: MessageRole,
67
68    /// The content of the message in array of text and/or images.
69    pub content: Vec<MessageContent>,
70
71    /// If applicable, the ID of the [assistant](https://platform.openai.com/docs/api-reference/assistants) that authored this message.
72    pub assistant_id: Option<String>,
73
74    /// The ID of the [run](https://platform.openai.com/docs/api-reference/runs) associated with the creation of this message. Value is `null` when messages are created manually using the create message or create thread endpoints.
75    pub run_id: Option<String>,
76
77    /// A list of files attached to the message, and the tools they were added to.
78    pub attachments: Option<Vec<MessageAttachment>>,
79
80    pub metadata: Option<HashMap<String, serde_json::Value>>,
81}
82
83#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
84pub struct MessageAttachment {
85    /// The ID of the file to attach to the message.
86    pub file_id: String,
87    /// The tools to add this file to.
88    pub tools: Vec<MessageAttachmentTool>,
89}
90
91#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
92#[serde(tag = "type")]
93#[serde(rename_all = "snake_case")]
94pub enum MessageAttachmentTool {
95    CodeInterpreter,
96    FileSearch,
97}
98
99#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
100#[serde(tag = "type")]
101#[serde(rename_all = "snake_case")]
102pub enum MessageContent {
103    Text(MessageContentTextObject),
104    ImageFile(MessageContentImageFileObject),
105    ImageUrl(MessageContentImageUrlObject),
106    Refusal(MessageContentRefusalObject),
107}
108
109#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
110pub struct MessageContentRefusalObject {
111    pub refusal: String,
112}
113
114/// The text content that is part of a message.
115#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
116pub struct MessageContentTextObject {
117    pub text: TextData,
118}
119
120#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
121pub struct TextData {
122    /// The data that makes up the text.
123    pub value: String,
124    pub annotations: Vec<MessageContentTextAnnotations>,
125}
126
127#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
128#[serde(tag = "type")]
129#[serde(rename_all = "snake_case")]
130pub enum MessageContentTextAnnotations {
131    /// A citation within the message that points to a specific quote from a specific File
132    /// associated with the assistant or the message. Generated when the assistant uses the
133    /// "retrieval" tool to search files.
134    FileCitation(MessageContentTextAnnotationsFileCitationObject),
135    /// A URL for the file that's generated when the assistant used the `code_interpreter` tool to
136    /// generate a file.
137    FilePath(MessageContentTextAnnotationsFilePathObject),
138}
139
140/// A citation within the message that points to a specific quote from a specific File associated
141/// with the assistant or the message. Generated when the assistant uses the "file_search" tool to
142/// search files.
143#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
144pub struct MessageContentTextAnnotationsFileCitationObject {
145    /// The text in the message content that needs to be replaced.
146    pub text: String,
147    pub file_citation: FileCitation,
148    pub start_index: u32,
149    pub end_index: u32,
150}
151
152#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
153pub struct FileCitation {
154    /// The ID of the specific File the citation is from.
155    pub file_id: String,
156    /// The specific quote in the file.
157    pub quote: Option<String>,
158}
159
160#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
161pub struct MessageContentTextAnnotationsFilePathObject {
162    /// The text in the message content that needs to be replaced.
163    pub text: String,
164    pub file_path: FilePath,
165    pub start_index: u32,
166    pub end_index: u32,
167}
168
169#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
170pub struct FilePath {
171    /// The ID of the file that was generated.
172    pub file_id: String,
173}
174
175/// References an image [File](https://platform.openai.com/docs/api-reference/files) in the content of a message.
176#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
177pub struct MessageContentImageFileObject {
178    pub image_file: ImageFile,
179}
180
181#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
182pub struct ImageFile {
183    /// The [File](https://platform.openai.com/docs/api-reference/files) ID of the image in the message content. Set `purpose="vision"` when uploading the File if you need to later display the file content.
184    pub file_id: String,
185    /// Specifies the detail level of the image if specified by the user. `low` uses fewer tokens,
186    /// you can opt in to high resolution using `high`.
187    pub detail: Option<ImageDetail>,
188}
189
190/// References an image URL in the content of a message.
191#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
192pub struct MessageContentImageUrlObject {
193    pub image_url: ImageUrl,
194}
195
196#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
197pub struct MessageRequestContentTextObject {
198    /// Text content to be sent to the model
199    pub text: String,
200}
201
202#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
203#[serde(untagged)]
204pub enum CreateMessageRequestContent {
205    /// The text contents of the message.
206    Content(String),
207    /// An array of content parts with a defined type, each can be of type `text` or images can be passed with `image_url` or `image_file`. Image types are only supported on [Vision-compatible models](https://platform.openai.com/docs/models/overview).
208    ContentArray(Vec<MessageContentInput>),
209}
210
211#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
212#[serde(tag = "type")]
213#[serde(rename_all = "snake_case")]
214pub enum MessageContentInput {
215    Text(MessageRequestContentTextObject),
216    ImageFile(MessageContentImageFileObject),
217    ImageUrl(MessageContentImageUrlObject),
218}
219#[derive(Clone, Serialize, Default, Debug, Deserialize, Builder, PartialEq)]
220#[builder(name = "CreateMessageRequestArgs")]
221#[builder(pattern = "mutable")]
222#[builder(setter(into, strip_option), default)]
223#[builder(derive(Debug))]
224#[builder(build_fn(error = "OpenAIError"))]
225pub struct CreateMessageRequest {
226    /// The role of the entity that is creating the message. Allowed values include:
227    /// - `user`: Indicates the message is sent by an actual user and should be used in most cases
228    ///   to represent user-generated messages.
229    /// - `assistant`: Indicates the message is generated by the assistant. Use this value to
230    ///   insert messages from the assistant into the conversation.
231    pub role: MessageRole,
232    /// The content of the message.
233    pub content: CreateMessageRequestContent,
234
235    /// A list of files attached to the message, and the tools they should be added to.
236    pub attachments: Option<Vec<MessageAttachment>>,
237
238    #[serde(skip_serializing_if = "Option::is_none")]
239    pub metadata: Option<HashMap<String, serde_json::Value>>,
240}
241
242#[derive(Clone, Serialize, Default, Debug, Deserialize, PartialEq)]
243pub struct ModifyMessageRequest {
244    #[serde(skip_serializing_if = "Option::is_none")]
245    pub metadata: Option<HashMap<String, serde_json::Value>>,
246}
247
248#[derive(Clone, Serialize, Default, Debug, Deserialize, PartialEq)]
249pub struct DeleteMessageResponse {
250    pub id: String,
251    pub deleted: bool,
252    pub object: String,
253}
254
255#[derive(Clone, Serialize, Default, Debug, Deserialize, PartialEq)]
256pub struct ListMessagesResponse {
257    pub object: String,
258    pub data: Vec<MessageObject>,
259    pub first_id: Option<String>,
260    pub last_id: Option<String>,
261    pub has_more: bool,
262}
263
264/// Represents a message delta i.e. any changed fields on a message during streaming.
265#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
266pub struct MessageDeltaObject {
267    /// The identifier of the message, which can be referenced in API endpoints.
268    pub id: String,
269    /// The object type, which is always `thread.message.delta`.
270    pub object: String,
271    /// The delta containing the fields that have changed on the Message.
272    pub delta: MessageDelta,
273}
274
275#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
276pub struct MessageDelta {
277    /// The entity that produced the message. One of `user` or `assistant`.
278    pub role: Option<MessageRole>,
279    ///  The content of the message in array of text and/or images.
280    pub content: Option<Vec<MessageDeltaContent>>,
281}
282
283#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
284#[serde(tag = "type")]
285#[serde(rename_all = "snake_case")]
286pub enum MessageDeltaContent {
287    ImageFile(MessageDeltaContentImageFileObject),
288    ImageUrl(MessageDeltaContentImageUrlObject),
289    Text(MessageDeltaContentTextObject),
290    Refusal(MessageDeltaContentRefusalObject),
291}
292
293#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
294pub struct MessageDeltaContentRefusalObject {
295    /// The index of the refusal part in the message.
296    pub index: u32,
297    pub refusal: Option<String>,
298}
299
300/// The text content that is part of a message.
301#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
302pub struct MessageDeltaContentTextObject {
303    /// The index of the content part in the message.
304    pub index: u32,
305    pub text: Option<MessageDeltaContentText>,
306}
307
308#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
309pub struct MessageDeltaContentText {
310    /// The data that makes up the text.
311    pub value: Option<String>,
312    pub annotations: Option<Vec<MessageDeltaContentTextAnnotations>>,
313}
314
315#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
316#[serde(tag = "type")]
317#[serde(rename_all = "snake_case")]
318pub enum MessageDeltaContentTextAnnotations {
319    FileCitation(MessageDeltaContentTextAnnotationsFileCitationObject),
320    FilePath(MessageDeltaContentTextAnnotationsFilePathObject),
321}
322
323/// A citation within the message that points to a specific quote from a specific File associated
324/// with the assistant or the message. Generated when the assistant uses the "file_search" tool to
325/// search files.
326#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
327pub struct MessageDeltaContentTextAnnotationsFileCitationObject {
328    /// The index of the annotation in the text content part.
329    pub index: u32,
330    /// The text in the message content that needs to be replaced.
331    pub text: Option<String>,
332    pub file_citation: Option<FileCitation>,
333    pub start_index: Option<u32>,
334    pub end_index: Option<u32>,
335}
336
337/// A URL for the file that's generated when the assistant used the `code_interpreter` tool to
338/// generate a file.
339#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
340pub struct MessageDeltaContentTextAnnotationsFilePathObject {
341    /// The index of the annotation in the text content part.
342    pub index: u32,
343    /// The text in the message content that needs to be replaced.
344    pub text: Option<String>,
345    pub file_path: Option<FilePath>,
346    pub start_index: Option<u32>,
347    pub end_index: Option<u32>,
348}
349
350/// References an image [File](https://platform.openai.com/docs/api-reference/files) in the content of a message.
351#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
352pub struct MessageDeltaContentImageFileObject {
353    /// The index of the content part in the message.
354    pub index: u32,
355
356    pub image_file: Option<ImageFile>,
357}
358
359#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
360pub struct MessageDeltaContentImageUrlObject {
361    /// The index of the content part in the message.
362    pub index: u32,
363
364    pub image_url: Option<ImageUrl>,
365}