use serde::{Deserialize, Serialize};
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct ThreadResource {
pub id: String,
#[serde(default = "default_thread_object")]
pub object: String,
pub created_at: u64,
pub title: Option<String>,
#[serde(flatten)]
pub status: ThreadStatus,
pub user: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub items: Option<ThreadItemListResource>,
}
fn default_thread_object() -> String {
"chatkit.thread".to_string()
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ThreadStatus {
Active,
Locked { reason: Option<String> },
Closed { reason: Option<String> },
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
pub struct ThreadListResource {
#[serde(default = "default_list_object")]
pub object: String,
pub data: Vec<ThreadResource>,
pub first_id: Option<String>,
pub last_id: Option<String>,
pub has_more: bool,
}
fn default_list_object() -> String {
"list".to_string()
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
pub struct DeletedThreadResource {
pub id: String,
#[serde(default = "default_deleted_object")]
pub object: String,
pub deleted: bool,
}
fn default_deleted_object() -> String {
"chatkit.thread.deleted".to_string()
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
pub struct ThreadItemListResource {
#[serde(default = "default_list_object")]
pub object: String,
pub data: Vec<ThreadItem>,
pub first_id: Option<String>,
pub last_id: Option<String>,
pub has_more: bool,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ThreadItem {
#[serde(rename = "chatkit.user_message")]
UserMessage(UserMessageItem),
#[serde(rename = "chatkit.assistant_message")]
AssistantMessage(AssistantMessageItem),
#[serde(rename = "chatkit.widget")]
Widget(WidgetMessageItem),
#[serde(rename = "chatkit.client_tool_call")]
ClientToolCall(ClientToolCallItem),
#[serde(rename = "chatkit.task")]
Task(TaskItem),
#[serde(rename = "chatkit.task_group")]
TaskGroup(TaskGroupItem),
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
pub struct UserMessageItem {
pub id: String,
#[serde(default = "default_thread_item_object")]
pub object: String,
pub created_at: u64,
pub thread_id: String,
pub content: Vec<UserMessageContent>,
#[serde(default)]
pub attachments: Vec<Attachment>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inference_options: Option<InferenceOptions>,
}
fn default_thread_item_object() -> String {
"chatkit.thread_item".to_string()
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum UserMessageContent {
#[serde(rename = "input_text")]
InputText { text: String },
#[serde(rename = "quoted_text")]
QuotedText { text: String },
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct Attachment {
#[serde(rename = "type")]
pub attachment_type: AttachmentType,
pub id: String,
pub name: String,
pub mime_type: String,
pub preview_url: Option<String>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum AttachmentType {
Image,
File,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
pub struct InferenceOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_choice: Option<ToolChoice>,
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
pub struct ToolChoice {
pub id: String,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq, Default)]
pub struct AssistantMessageItem {
pub id: String,
#[serde(default = "default_thread_item_object")]
pub object: String,
pub created_at: u64,
pub thread_id: String,
pub content: Vec<ResponseOutputText>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct ResponseOutputText {
#[serde(default = "default_output_text_type")]
pub r#type: String,
pub text: String,
#[serde(default)]
pub annotations: Vec<Annotation>,
}
fn default_output_text_type() -> String {
"output_text".to_string()
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum Annotation {
#[serde(rename = "file")]
File(FileAnnotation),
#[serde(rename = "url")]
Url(UrlAnnotation),
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct FileAnnotation {
#[serde(default = "default_file_annotation_type")]
pub r#type: String,
pub source: FileAnnotationSource,
}
fn default_file_annotation_type() -> String {
"file".to_string()
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct FileAnnotationSource {
#[serde(default = "default_file_source_type")]
pub r#type: String,
pub filename: String,
}
fn default_file_source_type() -> String {
"file".to_string()
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct UrlAnnotation {
#[serde(default = "default_url_annotation_type")]
pub r#type: String,
pub source: UrlAnnotationSource,
}
fn default_url_annotation_type() -> String {
"url".to_string()
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct UrlAnnotationSource {
#[serde(default = "default_url_source_type")]
pub r#type: String,
pub url: String,
}
fn default_url_source_type() -> String {
"url".to_string()
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct WidgetMessageItem {
pub id: String,
#[serde(default = "default_thread_item_object")]
pub object: String,
pub created_at: u64,
pub thread_id: String,
pub widget: String,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct ClientToolCallItem {
pub id: String,
#[serde(default = "default_thread_item_object")]
pub object: String,
pub created_at: u64,
pub thread_id: String,
pub status: ClientToolCallStatus,
pub call_id: String,
pub name: String,
pub arguments: String,
pub output: Option<String>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ClientToolCallStatus {
InProgress,
Completed,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct TaskItem {
pub id: String,
#[serde(default = "default_thread_item_object")]
pub object: String,
pub created_at: u64,
pub thread_id: String,
pub task_type: TaskType,
pub heading: Option<String>,
pub summary: Option<String>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum TaskType {
Custom,
Thought,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct TaskGroupItem {
pub id: String,
#[serde(default = "default_thread_item_object")]
pub object: String,
pub created_at: u64,
pub thread_id: String,
pub tasks: Vec<TaskGroupTask>,
}
#[derive(Clone, Serialize, Debug, Deserialize, PartialEq)]
pub struct TaskGroupTask {
pub task_type: TaskType,
pub heading: Option<String>,
pub summary: Option<String>,
}