use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ConversationItem {
Message(MessageItem),
FunctionCall(FunctionCallItem),
FunctionCallOutput(FunctionCallOutputItem),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageItem {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub role: MessageRole,
pub content: Vec<ContentPart>,
}
impl MessageItem {
pub fn user_text(text: impl Into<String>) -> Self {
Self { id: None, role: MessageRole::User, content: vec![ContentPart::InputText { text: text.into() }] }
}
pub fn assistant_text(text: impl Into<String>) -> Self {
Self { id: None, role: MessageRole::Assistant, content: vec![ContentPart::Text { text: text.into() }] }
}
pub fn system(text: impl Into<String>) -> Self {
Self { id: None, role: MessageRole::System, content: vec![ContentPart::InputText { text: text.into() }] }
}
pub fn user_audio(audio_base64: impl Into<String>) -> Self {
Self { id: None, role: MessageRole::User, content: vec![ContentPart::InputAudio { audio: audio_base64.into(), transcript: None }] }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum MessageRole {
System,
User,
Assistant,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ContentPart {
InputText { text: String },
InputAudio {
audio: String,
#[serde(skip_serializing_if = "Option::is_none")]
transcript: Option<String>,
},
Text { text: String },
Audio {
#[serde(skip_serializing_if = "Option::is_none")]
audio: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
transcript: Option<String>,
},
ItemReference { id: String },
}
impl ContentPart {
pub fn input_text(text: impl Into<String>) -> Self {
Self::InputText { text: text.into() }
}
pub fn input_audio(audio_base64: impl Into<String>) -> Self {
Self::InputAudio { audio: audio_base64.into(), transcript: None }
}
pub fn text(text: impl Into<String>) -> Self {
Self::Text { text: text.into() }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionCallItem {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub call_id: String,
pub name: String,
pub arguments: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionCallOutputItem {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub call_id: String,
pub output: String,
}
impl FunctionCallOutputItem {
pub fn new(call_id: impl Into<String>, output: impl Into<String>) -> Self {
Self { id: None, call_id: call_id.into(), output: output.into() }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ItemStatus {
InProgress,
Completed,
Incomplete,
}