use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Attachment {
pub kind: AttachmentKind,
pub uri: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub media_type: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum AttachmentKind {
File,
Image,
Audio,
Video,
Other,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum Role {
System,
User,
Assistant,
Tool,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ToolCall {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub name: String,
pub arguments: serde_json::Value,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ToolResult {
pub name: String,
pub output: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_call_id: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Message {
pub role: Role,
pub content: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_call: Option<ToolCall>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_result: Option<ToolResult>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub attachments: Vec<Attachment>,
}
impl Message {
pub fn system(content: impl Into<String>) -> Self {
Self {
role: Role::System,
content: content.into(),
tool_call: None,
tool_result: None,
attachments: Vec::new(),
}
}
pub fn user(content: impl Into<String>) -> Self {
Self {
role: Role::User,
content: content.into(),
tool_call: None,
tool_result: None,
attachments: Vec::new(),
}
}
pub fn assistant(content: impl Into<String>) -> Self {
Self {
role: Role::Assistant,
content: content.into(),
tool_call: None,
tool_result: None,
attachments: Vec::new(),
}
}
pub fn tool(name: impl Into<String>, output: serde_json::Value) -> Self {
let name = name.into();
Self {
role: Role::Tool,
content: format!("Result from `{}`", name),
tool_call: None,
tool_result: Some(ToolResult {
name: name.clone(),
output,
tool_call_id: None,
}),
attachments: Vec::new(),
}
}
pub fn tool_with_call(
name: impl Into<String>,
output: serde_json::Value,
tool_call_id: Option<String>,
) -> Self {
let name = name.into();
Self {
role: Role::Tool,
content: format!("Result from `{}`", name),
tool_call: None,
tool_result: Some(ToolResult {
name: name.clone(),
output,
tool_call_id,
}),
attachments: Vec::new(),
}
}
}