use serde::{Deserialize, Serialize};
use crate::cache::CacheControl;
use crate::thinking::ThinkingBlock;
use crate::tool::{ToolResultBlock, ToolUseBlock};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Role {
User,
Assistant,
System,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Message {
pub role: Role,
pub content: Vec<ContentBlock>,
}
impl Message {
pub fn user_text(text: impl Into<String>) -> Self {
Self {
role: Role::User,
content: vec![ContentBlock::Text(TextBlock {
text: text.into(),
cache_control: None,
})],
}
}
pub fn assistant_text(text: impl Into<String>) -> Self {
Self {
role: Role::Assistant,
content: vec![ContentBlock::Text(TextBlock {
text: text.into(),
cache_control: None,
})],
}
}
pub fn system_text(text: impl Into<String>) -> Self {
Self {
role: Role::System,
content: vec![ContentBlock::Text(TextBlock {
text: text.into(),
cache_control: None,
})],
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ContentBlock {
Text(TextBlock),
Image(ImageBlock),
ToolUse(ToolUseBlock),
ToolResult(ToolResultBlock),
Thinking(ThinkingBlock),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TextBlock {
pub text: String,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub cache_control: Option<CacheControl>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ImageBlock {
pub source: ImageSource,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub cache_control: Option<CacheControl>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub sha256: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub dims: Option<(u32, u32)>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ImageSource {
Base64 {
media_type: String,
data: String,
},
Url {
url: String,
},
BlobRef {
sha256: String,
media_type: String,
},
}