use lc_core::tools::ToolCall;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq)]
pub enum AnthropicStreamToken {
Text(String),
Thinking(String),
ToolCall(ToolCall),
Usage(AnthropicUsage),
}
#[derive(Serialize, Clone, Debug)]
#[serde(untagged)]
pub enum AnthropicMessageContent {
Text(String),
Blocks(Vec<AnthropicContentBlock>),
}
#[derive(Serialize, Clone, Debug)]
#[serde(tag = "type")]
pub enum AnthropicContentBlock {
#[serde(rename = "text")]
Text {
text: String,
},
#[serde(rename = "image")]
Image {
source: AnthropicImageSource,
},
#[serde(rename = "tool_use")]
ToolUse {
id: String,
name: String,
input: serde_json::Value,
},
#[serde(rename = "tool_result")]
ToolResult {
tool_use_id: String,
content: String,
},
}
#[derive(Serialize, Clone, Debug)]
pub struct AnthropicImageSource {
#[serde(rename = "type")]
pub source_type: String,
pub media_type: String,
pub data: String,
}
#[derive(Serialize, Clone)]
pub(crate) struct AnthropicMessage {
pub(crate) role: String,
pub(crate) content: AnthropicMessageContent,
}
#[derive(Deserialize)]
#[allow(dead_code)]
pub(crate) struct AnthropicResponse {
pub(crate) id: String,
pub(crate) model: String,
pub(crate) content: Vec<AnthropicContent>,
pub(crate) usage: Option<AnthropicUsage>,
}
#[derive(Deserialize)]
#[allow(dead_code)]
pub(crate) struct AnthropicContent {
#[serde(rename = "type")]
pub(crate) content_type: String,
#[serde(default)]
pub(crate) text: String,
#[serde(default)]
pub(crate) thinking: String,
#[serde(default)]
pub(crate) id: Option<String>,
#[serde(default)]
pub(crate) name: Option<String>,
#[serde(default)]
pub(crate) input: Option<serde_json::Value>,
}
#[derive(Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct AnthropicUsage {
pub(crate) input_tokens: usize,
pub(crate) output_tokens: usize,
#[serde(default)]
pub(crate) cache_creation_input_tokens: usize,
#[serde(default)]
pub(crate) cache_read_input_tokens: usize,
}
impl AnthropicUsage {
pub fn cache_creation_tokens(&self) -> usize {
self.cache_creation_input_tokens
}
pub fn cache_read_tokens(&self) -> usize {
self.cache_read_input_tokens
}
pub fn cache_miss_tokens(&self) -> usize {
self.input_tokens.saturating_sub(self.cache_read_input_tokens)
}
pub fn cache_breakdown(&self) -> (usize, usize) {
(self.cache_creation_input_tokens, self.cache_read_input_tokens)
}
}
#[derive(Deserialize)]
pub(crate) struct AnthropicStreamEvent {
#[serde(rename = "type")]
pub(crate) type_field: String,
#[serde(default)]
pub(crate) index: Option<usize>,
pub(crate) content_block: Option<AnthropicStreamBlock>,
pub(crate) delta: Option<AnthropicDelta>,
#[serde(default)]
pub(crate) usage: Option<AnthropicUsage>,
}
#[derive(Deserialize)]
pub(crate) struct AnthropicStreamBlock {
#[serde(rename = "type")]
pub(crate) type_field: String,
#[serde(default)]
pub(crate) id: String,
#[serde(default)]
pub(crate) name: String,
}
#[derive(Deserialize)]
pub(crate) struct AnthropicDelta {
#[serde(rename = "type")]
pub(crate) type_field: String,
#[serde(default)]
pub(crate) text: String,
#[serde(default)]
pub(crate) thinking: String,
#[serde(default)]
pub(crate) partial_json: String,
}