1use serde::{Deserialize, Serialize};
2
3#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
5pub struct ThreadResource {
6 pub id: String,
8 #[serde(default = "default_thread_object")]
10 pub object: String,
11 pub created_at: i64,
13 pub title: Option<String>,
15 #[serde(flatten)]
17 pub status: ThreadStatus,
18 pub user: String,
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub items: Option<ThreadItemListResource>,
23}
24
25fn default_thread_object() -> String {
26 "chatkit.thread".to_string()
27}
28
29#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
31#[serde(tag = "type", rename_all = "snake_case")]
32pub enum ThreadStatus {
33 Active,
35 Locked { reason: Option<String> },
37 Closed { reason: Option<String> },
39}
40
41#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
43pub struct ThreadListResource {
44 #[serde(default = "default_list_object")]
46 pub object: String,
47 pub data: Vec<ThreadResource>,
49 pub first_id: Option<String>,
51 pub last_id: Option<String>,
53 pub has_more: bool,
55}
56
57fn default_list_object() -> String {
58 "list".to_string()
59}
60
61#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
63pub struct DeletedThreadResource {
64 pub id: String,
66 #[serde(default = "default_deleted_object")]
68 pub object: String,
69 pub deleted: bool,
71}
72
73fn default_deleted_object() -> String {
74 "chatkit.thread.deleted".to_string()
75}
76
77#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
79pub struct ThreadItemListResource {
80 #[serde(default = "default_list_object")]
82 pub object: String,
83 pub data: Vec<ThreadItem>,
85 pub first_id: Option<String>,
87 pub last_id: Option<String>,
89 pub has_more: bool,
91}
92
93#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
95#[serde(tag = "type", rename_all = "snake_case")]
96pub enum ThreadItem {
97 #[serde(rename = "chatkit.user_message")]
99 UserMessage(UserMessageItem),
100 #[serde(rename = "chatkit.assistant_message")]
102 AssistantMessage(AssistantMessageItem),
103 #[serde(rename = "chatkit.widget")]
105 Widget(WidgetMessageItem),
106 #[serde(rename = "chatkit.client_tool_call")]
108 ClientToolCall(ClientToolCallItem),
109 #[serde(rename = "chatkit.task")]
111 Task(TaskItem),
112 #[serde(rename = "chatkit.task_group")]
114 TaskGroup(TaskGroupItem),
115}
116
117#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
119pub struct UserMessageItem {
120 pub id: String,
122 #[serde(default = "default_thread_item_object")]
124 pub object: String,
125 pub created_at: i64,
127 pub thread_id: String,
129 pub content: Vec<UserMessageContent>,
131 #[serde(default)]
133 pub attachments: Vec<Attachment>,
134 #[serde(skip_serializing_if = "Option::is_none")]
136 pub inference_options: Option<InferenceOptions>,
137}
138
139fn default_thread_item_object() -> String {
140 "chatkit.thread_item".to_string()
141}
142
143#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
145#[serde(tag = "type", rename_all = "snake_case")]
146pub enum UserMessageContent {
147 #[serde(rename = "input_text")]
149 InputText { text: String },
150 #[serde(rename = "quoted_text")]
152 QuotedText { text: String },
153}
154
155#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
157pub struct Attachment {
158 #[serde(rename = "type")]
160 pub attachment_type: AttachmentType,
161 pub id: String,
163 pub name: String,
165 pub mime_type: String,
167 pub preview_url: Option<String>,
169}
170
171#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
173#[serde(rename_all = "snake_case")]
174pub enum AttachmentType {
175 Image,
176 File,
177}
178
179#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
181pub struct InferenceOptions {
182 #[serde(skip_serializing_if = "Option::is_none")]
184 pub tool_choice: Option<ToolChoice>,
185 #[serde(skip_serializing_if = "Option::is_none")]
187 pub model: Option<String>,
188}
189
190#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
192pub struct ToolChoice {
193 pub id: String,
195}
196
197#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
199pub struct AssistantMessageItem {
200 pub id: String,
202 #[serde(default = "default_thread_item_object")]
204 pub object: String,
205 pub created_at: i64,
207 pub thread_id: String,
209 pub content: Vec<ResponseOutputText>,
211}
212
213#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
215pub struct ResponseOutputText {
216 #[serde(default = "default_output_text_type")]
218 pub r#type: String,
219 pub text: String,
221 #[serde(default)]
223 pub annotations: Vec<Annotation>,
224}
225
226fn default_output_text_type() -> String {
227 "output_text".to_string()
228}
229
230#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
232#[serde(tag = "type", rename_all = "snake_case")]
233pub enum Annotation {
234 #[serde(rename = "file")]
236 File(FileAnnotation),
237 #[serde(rename = "url")]
239 Url(UrlAnnotation),
240}
241
242#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
244pub struct FileAnnotation {
245 #[serde(default = "default_file_annotation_type")]
247 pub r#type: String,
248 pub source: FileAnnotationSource,
250}
251
252fn default_file_annotation_type() -> String {
253 "file".to_string()
254}
255
256#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
258pub struct FileAnnotationSource {
259 #[serde(default = "default_file_source_type")]
261 pub r#type: String,
262 pub filename: String,
264}
265
266fn default_file_source_type() -> String {
267 "file".to_string()
268}
269
270#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
272pub struct UrlAnnotation {
273 #[serde(default = "default_url_annotation_type")]
275 pub r#type: String,
276 pub source: UrlAnnotationSource,
278}
279
280fn default_url_annotation_type() -> String {
281 "url".to_string()
282}
283
284#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
286pub struct UrlAnnotationSource {
287 #[serde(default = "default_url_source_type")]
289 pub r#type: String,
290 pub url: String,
292}
293
294fn default_url_source_type() -> String {
295 "url".to_string()
296}
297
298#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
300pub struct WidgetMessageItem {
301 pub id: String,
303 #[serde(default = "default_thread_item_object")]
305 pub object: String,
306 pub created_at: i64,
308 pub thread_id: String,
310 pub widget: String,
312}
313
314#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
316pub struct ClientToolCallItem {
317 pub id: String,
319 #[serde(default = "default_thread_item_object")]
321 pub object: String,
322 pub created_at: i64,
324 pub thread_id: String,
326 pub status: ClientToolCallStatus,
328 pub call_id: String,
330 pub name: String,
332 pub arguments: String,
334 pub output: Option<String>,
336}
337
338#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
340#[serde(rename_all = "snake_case")]
341pub enum ClientToolCallStatus {
342 InProgress,
343 Completed,
344}
345
346#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
348pub struct TaskItem {
349 pub id: String,
351 #[serde(default = "default_thread_item_object")]
353 pub object: String,
354 pub created_at: i64,
356 pub thread_id: String,
358 pub task_type: TaskType,
360 pub heading: Option<String>,
362 pub summary: Option<String>,
364}
365
366#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
368#[serde(rename_all = "snake_case")]
369pub enum TaskType {
370 Custom,
371 Thought,
372}
373
374#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
376pub struct TaskGroupItem {
377 pub id: String,
379 #[serde(default = "default_thread_item_object")]
381 pub object: String,
382 pub created_at: i64,
384 pub thread_id: String,
386 pub tasks: Vec<TaskGroupTask>,
388}
389
390#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
392pub struct TaskGroupTask {
393 pub task_type: TaskType,
395 pub heading: Option<String>,
397 pub summary: Option<String>,
399}