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: u64,
13 pub title: Option<String>,
16 #[serde(flatten)]
18 pub status: ThreadStatus,
19 pub user: String,
21 #[serde(skip_serializing_if = "Option::is_none")]
23 pub items: Option<ThreadItemListResource>,
24}
25
26fn default_thread_object() -> String {
27 "chatkit.thread".to_string()
28}
29
30#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
32#[serde(tag = "type", rename_all = "snake_case")]
33pub enum ThreadStatus {
34 Active,
36 Locked { reason: Option<String> },
38 Closed { reason: Option<String> },
40}
41
42#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
44pub struct ThreadListResource {
45 #[serde(default = "default_list_object")]
47 pub object: String,
48 pub data: Vec<ThreadResource>,
50 pub first_id: Option<String>,
52 pub last_id: Option<String>,
54 pub has_more: bool,
56}
57
58fn default_list_object() -> String {
59 "list".to_string()
60}
61
62#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
64pub struct DeletedThreadResource {
65 pub id: String,
67 #[serde(default = "default_deleted_object")]
69 pub object: String,
70 pub deleted: bool,
72}
73
74fn default_deleted_object() -> String {
75 "chatkit.thread.deleted".to_string()
76}
77
78#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
80pub struct ThreadItemListResource {
81 #[serde(default = "default_list_object")]
83 pub object: String,
84 pub data: Vec<ThreadItem>,
86 pub first_id: Option<String>,
88 pub last_id: Option<String>,
90 pub has_more: bool,
92}
93
94#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
96#[serde(tag = "type", rename_all = "snake_case")]
97pub enum ThreadItem {
98 #[serde(rename = "chatkit.user_message")]
100 UserMessage(UserMessageItem),
101 #[serde(rename = "chatkit.assistant_message")]
103 AssistantMessage(AssistantMessageItem),
104 #[serde(rename = "chatkit.widget")]
106 Widget(WidgetMessageItem),
107 #[serde(rename = "chatkit.client_tool_call")]
109 ClientToolCall(ClientToolCallItem),
110 #[serde(rename = "chatkit.task")]
112 Task(TaskItem),
113 #[serde(rename = "chatkit.task_group")]
115 TaskGroup(TaskGroupItem),
116}
117
118#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
120pub struct UserMessageItem {
121 pub id: String,
123 #[serde(default = "default_thread_item_object")]
125 pub object: String,
126 pub created_at: u64,
128 pub thread_id: String,
130 pub content: Vec<UserMessageContent>,
132 #[serde(default)]
134 pub attachments: Vec<Attachment>,
135 #[serde(skip_serializing_if = "Option::is_none")]
137 pub inference_options: Option<InferenceOptions>,
138}
139
140fn default_thread_item_object() -> String {
141 "chatkit.thread_item".to_string()
142}
143
144#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
146#[serde(tag = "type", rename_all = "snake_case")]
147pub enum UserMessageContent {
148 #[serde(rename = "input_text")]
150 InputText { text: String },
151 #[serde(rename = "quoted_text")]
153 QuotedText { text: String },
154}
155
156#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
158pub struct Attachment {
159 #[serde(rename = "type")]
161 pub attachment_type: AttachmentType,
162 pub id: String,
164 pub name: String,
166 pub mime_type: String,
168 pub preview_url: Option<String>,
170}
171
172#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
174#[serde(rename_all = "snake_case")]
175pub enum AttachmentType {
176 Image,
177 File,
178}
179
180#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
182pub struct InferenceOptions {
183 #[serde(skip_serializing_if = "Option::is_none")]
185 pub tool_choice: Option<ToolChoice>,
186 #[serde(skip_serializing_if = "Option::is_none")]
188 pub model: Option<String>,
189}
190
191#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
193pub struct ToolChoice {
194 pub id: String,
196}
197
198#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
200pub struct AssistantMessageItem {
201 pub id: String,
203 #[serde(default = "default_thread_item_object")]
205 pub object: String,
206 pub created_at: u64,
208 pub thread_id: String,
210 pub content: Vec<ResponseOutputText>,
212}
213
214#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
216pub struct ResponseOutputText {
217 #[serde(default = "default_output_text_type")]
219 pub kind: String,
220 pub text: String,
222 #[serde(default)]
224 pub annotations: Vec<Annotation>,
225}
226
227fn default_output_text_type() -> String {
228 "output_text".to_string()
229}
230
231#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
233#[serde(tag = "type", rename_all = "snake_case")]
234pub enum Annotation {
235 #[serde(rename = "file")]
237 File(FileAnnotation),
238 #[serde(rename = "url")]
240 Url(UrlAnnotation),
241}
242
243#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
245pub struct FileAnnotation {
246 #[serde(default = "default_file_annotation_type")]
248 pub kind: String,
249 pub source: FileAnnotationSource,
251}
252
253fn default_file_annotation_type() -> String {
254 "file".to_string()
255}
256
257#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
259pub struct FileAnnotationSource {
260 #[serde(default = "default_file_source_type")]
262 pub kind: String,
263 pub filename: String,
265}
266
267fn default_file_source_type() -> String {
268 "file".to_string()
269}
270
271#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
273pub struct UrlAnnotation {
274 #[serde(default = "default_url_annotation_type")]
276 pub kind: String,
277 pub source: UrlAnnotationSource,
279}
280
281fn default_url_annotation_type() -> String {
282 "url".to_string()
283}
284
285#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
287pub struct UrlAnnotationSource {
288 #[serde(default = "default_url_source_type")]
290 pub kind: String,
291 pub url: String,
293}
294
295fn default_url_source_type() -> String {
296 "url".to_string()
297}
298
299#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
301pub struct WidgetMessageItem {
302 pub id: String,
304 #[serde(default = "default_thread_item_object")]
306 pub object: String,
307 pub created_at: u64,
309 pub thread_id: String,
311 pub widget: String,
313}
314
315#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
317pub struct ClientToolCallItem {
318 pub id: String,
320 #[serde(default = "default_thread_item_object")]
322 pub object: String,
323 pub created_at: u64,
325 pub thread_id: String,
327 pub status: ClientToolCallStatus,
329 pub call_id: String,
331 pub name: String,
333 pub arguments: String,
335 pub output: Option<String>,
338}
339
340#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
342#[serde(rename_all = "snake_case")]
343pub enum ClientToolCallStatus {
344 InProgress,
345 Completed,
346}
347
348#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
350pub struct TaskItem {
351 pub id: String,
353 #[serde(default = "default_thread_item_object")]
355 pub object: String,
356 pub created_at: u64,
358 pub thread_id: String,
360 pub task_type: TaskType,
362 pub heading: Option<String>,
364 pub summary: Option<String>,
366}
367
368#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
370#[serde(rename_all = "snake_case")]
371pub enum TaskType {
372 Custom,
373 Thought,
374}
375
376#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
378pub struct TaskGroupItem {
379 pub id: String,
381 #[serde(default = "default_thread_item_object")]
383 pub object: String,
384 pub created_at: u64,
386 pub thread_id: String,
388 pub tasks: Vec<TaskGroupTask>,
390}
391
392#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
394pub struct TaskGroupTask {
395 pub task_type: TaskType,
397 pub heading: Option<String>,
399 pub summary: Option<String>,
401}