use serde::{Deserialize, Serialize};
use crate::prelude::*;
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct MessageRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
#[serde(default)]
pub messages: Vec<MessageBody>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_tokens: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub system: Option<SystemMessageContent>,
#[serde(skip_serializing_if = "Option::is_none")]
pub temperature: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub top_p: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub top_k: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stream: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stop_sequences: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tools: Option<Vec<MessageTools>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_choice: Option<MessageToolChoice>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<MessageMetadata>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct MessageBody {
pub role: String,
pub content: MessageContent,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum MessageContent {
Text(String),
Parts(Vec<MessageContentPart>),
}
impl Default for MessageContent {
fn default() -> Self {
MessageContent::Text(String::new())
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum MessageContentPart {
Text {
text: String,
#[serde(skip_serializing_if = "Option::is_none")]
cache_control: Option<serde_json::Value>,
},
Image {
source: MessageImageContent,
#[serde(skip_serializing_if = "Option::is_none")]
cache_control: Option<serde_json::Value>,
},
ToolUse {
id: String,
name: String,
input: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
cache_control: Option<serde_json::Value>,
},
ToolResult {
tool_use_id: String,
content: String,
#[serde(skip_serializing_if = "Option::is_none")]
is_error: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
cache_control: Option<serde_json::Value>,
},
RedactedThinking {
data: String,
},
Thinking {
thinking: String,
},
}
impl Default for MessageContentPart {
fn default() -> Self {
MessageContentPart::Text {
text: String::new(),
cache_control: None,
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum MessageImageContent {
Base64 {
data: String,
media_type: String,
},
Url {
url: String,
},
}
impl Default for MessageImageContent {
fn default() -> Self {
MessageImageContent::Url { url: String::new() }
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SystemMessageContent {
Text(String),
Parts(Vec<SystemMessagePart>),
}
impl Default for SystemMessageContent {
fn default() -> Self {
SystemMessageContent::Text(String::new())
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct SystemMessagePart {
#[serde(rename = "type")]
pub part_type: String,
pub text: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_control: Option<serde_json::Value>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct MessageResponse {
pub id: String,
#[serde(rename = "type")]
pub response_type: String,
pub role: String,
pub content: Vec<MessageResponseContent>,
pub model: String,
pub usage: MessageUsage,
#[serde(skip_serializing_if = "Option::is_none")]
pub stop_reason: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stop_sequence: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum MessageResponseContent {
Text {
text: String,
},
Thinking {
thinking: String,
signature: String,
},
RedactedThinking {
data: String,
},
ToolUse {
id: String,
name: String,
input: serde_json::Value,
},
}
impl Default for MessageResponseContent {
fn default() -> Self {
MessageResponseContent::Text {
text: String::new(),
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum MessageToolChoice {
#[default]
Auto,
Any,
Tool {
name: String,
},
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct MessageTools {
pub name: String,
pub description: String,
pub input_schema: MessageToolInputSchema,
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_control: Option<serde_json::Value>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct MessageToolInputSchema {
#[serde(rename = "type")]
pub schema_type: String,
pub properties: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub required: Option<Vec<String>>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct MessageMetadata {
#[serde(skip_serializing_if = "Option::is_none")]
pub user_id: Option<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct MessageUsage {
pub input_tokens: i32,
pub output_tokens: i32,
pub cache_read_input_tokens: i32,
pub cache_creation_input_tokens: i32,
}