use serde::{Deserialize, Serialize};
use super::{ToolCall, ToolCallDelta};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Role {
System,
User,
Assistant,
Tool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Content {
Text(String),
Multimodal(Vec<ContentPart>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum ContentPart {
#[serde(rename = "text")]
Text {
text: String,
},
#[serde(rename = "image_url")]
Image {
image_url: ImageUrl,
},
#[serde(rename = "audio")]
Audio {
audio: AudioData,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageUrl {
pub url: String,
pub detail: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AudioData {
pub data: String,
pub format: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
pub role: Role,
pub content: Option<Content>,
pub name: Option<String>,
pub tool_calls: Option<Vec<ToolCall>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tool_call_id: Option<String>,
}
impl Message {
pub fn tool_result(tool_call_id: impl Into<String>, content: impl Into<String>) -> Self {
Self {
role: Role::Tool,
content: Some(Content::Text(content.into())),
name: None,
tool_calls: None,
tool_call_id: Some(tool_call_id.into()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageDelta {
pub role: Option<Role>,
pub content: Option<String>,
pub tool_calls: Option<Vec<ToolCallDelta>>,
}