1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize)]
9pub struct AssistantCreateRequest {
10 pub model: String,
11 #[serde(skip_serializing_if = "Option::is_none")]
12 pub name: Option<String>,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub description: Option<String>,
15 #[serde(skip_serializing_if = "Option::is_none")]
16 pub instructions: Option<String>,
17 #[serde(skip_serializing_if = "Option::is_none")]
18 pub tools: Option<Vec<serde_json::Value>>,
19 #[serde(skip_serializing_if = "Option::is_none")]
20 pub metadata: Option<std::collections::HashMap<String, String>>,
21 #[serde(skip_serializing_if = "Option::is_none")]
22 pub temperature: Option<f64>,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub top_p: Option<f64>,
25}
26
27impl AssistantCreateRequest {
28 pub fn new(model: impl Into<String>) -> Self {
29 Self {
30 model: model.into(),
31 name: None,
32 description: None,
33 instructions: None,
34 tools: None,
35 metadata: None,
36 temperature: None,
37 top_p: None,
38 }
39 }
40}
41
42#[derive(Debug, Clone, Deserialize)]
44pub struct Assistant {
45 pub id: String,
46 pub object: String,
47 pub created_at: i64,
48 pub model: String,
49 #[serde(default)]
50 pub name: Option<String>,
51 #[serde(default)]
52 pub description: Option<String>,
53 #[serde(default)]
54 pub instructions: Option<String>,
55 #[serde(default)]
56 pub tools: Vec<serde_json::Value>,
57 #[serde(default)]
58 pub metadata: Option<std::collections::HashMap<String, String>>,
59 #[serde(default)]
60 pub temperature: Option<f64>,
61 #[serde(default)]
62 pub top_p: Option<f64>,
63}
64
65#[derive(Debug, Clone, Deserialize)]
67pub struct AssistantList {
68 pub object: String,
69 pub data: Vec<Assistant>,
70}
71
72#[derive(Debug, Clone, Deserialize)]
74pub struct AssistantDeleted {
75 pub id: String,
76 pub deleted: bool,
77 pub object: String,
78}
79
80#[derive(Debug, Clone, Default, Serialize)]
84pub struct ThreadCreateRequest {
85 #[serde(skip_serializing_if = "Option::is_none")]
86 pub messages: Option<Vec<ThreadMessage>>,
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub metadata: Option<std::collections::HashMap<String, String>>,
89}
90
91#[derive(Debug, Clone, Serialize)]
93pub struct ThreadMessage {
94 pub role: String,
95 pub content: String,
96}
97
98#[derive(Debug, Clone, Deserialize)]
100pub struct Thread {
101 pub id: String,
102 pub object: String,
103 pub created_at: i64,
104 #[serde(default)]
105 pub metadata: Option<std::collections::HashMap<String, String>>,
106}
107
108#[derive(Debug, Clone, Deserialize)]
110pub struct ThreadDeleted {
111 pub id: String,
112 pub deleted: bool,
113 pub object: String,
114}
115
116#[derive(Debug, Clone, Deserialize)]
118pub struct Message {
119 pub id: String,
120 pub object: String,
121 pub created_at: i64,
122 pub thread_id: String,
123 pub role: String,
124 pub content: Vec<MessageContent>,
125 #[serde(default)]
126 pub assistant_id: Option<String>,
127 #[serde(default)]
128 pub run_id: Option<String>,
129 #[serde(default)]
130 pub metadata: Option<std::collections::HashMap<String, String>>,
131}
132
133#[derive(Debug, Clone, Deserialize)]
135pub struct MessageContent {
136 #[serde(rename = "type")]
137 pub type_: String,
138 #[serde(default)]
139 pub text: Option<MessageText>,
140}
141
142#[derive(Debug, Clone, Deserialize)]
144pub struct MessageText {
145 pub value: String,
146 #[serde(default)]
147 pub annotations: Vec<serde_json::Value>,
148}
149
150#[derive(Debug, Clone, Serialize)]
152pub struct MessageCreateRequest {
153 pub role: String,
154 pub content: String,
155}
156
157#[derive(Debug, Clone, Deserialize)]
159pub struct MessageList {
160 pub object: String,
161 pub data: Vec<Message>,
162}
163
164#[derive(Debug, Clone, Serialize)]
168pub struct RunCreateRequest {
169 pub assistant_id: String,
170 #[serde(skip_serializing_if = "Option::is_none")]
171 pub instructions: Option<String>,
172 #[serde(skip_serializing_if = "Option::is_none")]
173 pub tools: Option<Vec<serde_json::Value>>,
174 #[serde(skip_serializing_if = "Option::is_none")]
175 pub metadata: Option<std::collections::HashMap<String, String>>,
176 #[serde(skip_serializing_if = "Option::is_none")]
177 pub model: Option<String>,
178}
179
180impl RunCreateRequest {
181 pub fn new(assistant_id: impl Into<String>) -> Self {
182 Self {
183 assistant_id: assistant_id.into(),
184 instructions: None,
185 tools: None,
186 metadata: None,
187 model: None,
188 }
189 }
190}
191
192#[derive(Debug, Clone, Deserialize)]
194pub struct Run {
195 pub id: String,
196 pub object: String,
197 pub created_at: i64,
198 pub thread_id: String,
199 pub assistant_id: String,
200 pub status: String,
201 #[serde(default)]
202 pub model: Option<String>,
203 #[serde(default)]
204 pub instructions: Option<String>,
205 #[serde(default)]
206 pub tools: Vec<serde_json::Value>,
207 #[serde(default)]
208 pub started_at: Option<i64>,
209 #[serde(default)]
210 pub completed_at: Option<i64>,
211 #[serde(default)]
212 pub cancelled_at: Option<i64>,
213 #[serde(default)]
214 pub failed_at: Option<i64>,
215 #[serde(default)]
216 pub metadata: Option<std::collections::HashMap<String, String>>,
217}
218
219#[derive(Debug, Clone, Serialize)]
221pub struct SubmitToolOutputsRequest {
222 pub tool_outputs: Vec<ToolOutput>,
223}
224
225#[derive(Debug, Clone, Serialize)]
227pub struct ToolOutput {
228 pub tool_call_id: String,
229 pub output: String,
230}
231
232#[derive(Debug, Clone, Default, Serialize)]
236pub struct VectorStoreCreateRequest {
237 #[serde(skip_serializing_if = "Option::is_none")]
238 pub name: Option<String>,
239 #[serde(skip_serializing_if = "Option::is_none")]
240 pub file_ids: Option<Vec<String>>,
241 #[serde(skip_serializing_if = "Option::is_none")]
242 pub metadata: Option<std::collections::HashMap<String, String>>,
243}
244
245#[derive(Debug, Clone, Deserialize)]
247pub struct VectorStore {
248 pub id: String,
249 pub object: String,
250 pub created_at: i64,
251 #[serde(default)]
252 pub name: Option<String>,
253 pub status: String,
254 #[serde(default)]
255 pub file_counts: Option<VectorStoreFileCounts>,
256 #[serde(default)]
257 pub metadata: Option<std::collections::HashMap<String, String>>,
258}
259
260#[derive(Debug, Clone, Deserialize)]
262pub struct VectorStoreFileCounts {
263 pub in_progress: i64,
264 pub completed: i64,
265 pub failed: i64,
266 pub cancelled: i64,
267 pub total: i64,
268}
269
270#[derive(Debug, Clone, Deserialize)]
272pub struct VectorStoreList {
273 pub object: String,
274 pub data: Vec<VectorStore>,
275}
276
277#[derive(Debug, Clone, Deserialize)]
279pub struct VectorStoreDeleted {
280 pub id: String,
281 pub deleted: bool,
282 pub object: String,
283}
284
285#[cfg(test)]
286mod tests {
287 use super::*;
288
289 #[test]
290 fn test_serialize_assistant_create() {
291 let req = AssistantCreateRequest::new("gpt-4o");
292 let json = serde_json::to_value(&req).unwrap();
293 assert_eq!(json["model"], "gpt-4o");
294 }
295
296 #[test]
297 fn test_deserialize_assistant() {
298 let json = r#"{
299 "id": "asst_abc123",
300 "object": "assistant",
301 "created_at": 1699009709,
302 "model": "gpt-4o",
303 "tools": [{"type": "code_interpreter"}]
304 }"#;
305 let asst: Assistant = serde_json::from_str(json).unwrap();
306 assert_eq!(asst.id, "asst_abc123");
307 assert_eq!(asst.tools.len(), 1);
308 }
309
310 #[test]
311 fn test_deserialize_thread() {
312 let json = r#"{
313 "id": "thread_abc123",
314 "object": "thread",
315 "created_at": 1699012949
316 }"#;
317 let thread: Thread = serde_json::from_str(json).unwrap();
318 assert_eq!(thread.id, "thread_abc123");
319 }
320
321 #[test]
322 fn test_deserialize_run() {
323 let json = r#"{
324 "id": "run_abc123",
325 "object": "thread.run",
326 "created_at": 1699012949,
327 "thread_id": "thread_abc123",
328 "assistant_id": "asst_abc123",
329 "status": "completed",
330 "tools": []
331 }"#;
332 let run: Run = serde_json::from_str(json).unwrap();
333 assert_eq!(run.status, "completed");
334 }
335
336 #[test]
337 fn test_deserialize_vector_store() {
338 let json = r#"{
339 "id": "vs_abc123",
340 "object": "vector_store",
341 "created_at": 1699012949,
342 "name": "My Store",
343 "status": "completed",
344 "file_counts": {
345 "in_progress": 0,
346 "completed": 5,
347 "failed": 0,
348 "cancelled": 0,
349 "total": 5
350 }
351 }"#;
352 let vs: VectorStore = serde_json::from_str(json).unwrap();
353 assert_eq!(vs.id, "vs_abc123");
354 assert_eq!(vs.file_counts.unwrap().completed, 5);
355 }
356}