use serde::{Deserialize, Serialize};
use crate::types::Acceleration;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum StopReason {
EndTurn,
MaxTokens,
StopSequence,
ToolUse,
PauseTurn,
Refusal,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Usage {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub input_tokens: Option<u64>,
pub output_tokens: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cache_creation_input_tokens: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cache_read_input_tokens: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ContentBlock {
Text {
text: String,
},
Thinking {
thinking: String,
#[serde(default)]
signature: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
pub id: String,
#[serde(rename = "type")]
pub r#type: String,
pub role: String,
pub content: Vec<ContentBlock>,
pub model: String,
#[serde(default)]
pub stop_reason: Option<StopReason>,
#[serde(default)]
pub stop_sequence: Option<String>,
pub usage: Usage,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ContentBlockDelta {
TextDelta {
text: String,
},
ThinkingDelta {
thinking: String,
},
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct MessageDelta {
#[serde(default)]
pub stop_reason: Option<StopReason>,
#[serde(default)]
pub stop_sequence: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum RawMessageStreamEvent {
MessageStart {
message: Message,
},
ContentBlockStart {
index: usize,
content_block: ContentBlock,
},
ContentBlockDelta {
index: usize,
delta: ContentBlockDelta,
},
ContentBlockStop {
index: usize,
},
MessageDelta {
delta: MessageDelta,
usage: Usage,
},
MessageStop,
}
impl RawMessageStreamEvent {
pub fn event_type(&self) -> &'static str {
match self {
Self::MessageStart { .. } => "message_start",
Self::ContentBlockStart { .. } => "content_block_start",
Self::ContentBlockDelta { .. } => "content_block_delta",
Self::ContentBlockStop { .. } => "content_block_stop",
Self::MessageDelta { .. } => "message_delta",
Self::MessageStop => "message_stop",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ContentBlockParam {
Text {
text: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum MessageContent {
Text(String),
Blocks(Vec<ContentBlockParam>),
}
impl MessageContent {
pub fn flatten(&self) -> String {
match self {
Self::Text(text) => text.clone(),
Self::Blocks(blocks) => blocks
.iter()
.map(|block| match block {
ContentBlockParam::Text { text } => text.as_str(),
})
.collect(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageParam {
pub role: String,
pub content: MessageContent,
}
#[derive(Debug, Clone, Default)]
pub struct MessageCreateParams {
pub model: String,
pub max_tokens: i32,
pub messages: Vec<MessageParam>,
pub stop_sequences: Option<Vec<String>>,
pub system: Option<MessageContent>,
pub temperature: Option<f32>,
pub top_k: Option<i32>,
pub top_p: Option<f32>,
pub acceleration: Option<Acceleration>,
}