use serde::Deserialize;
use super::FinishReason;
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
#[non_exhaustive]
pub enum AnthropicEvent {
MessageStart {},
ContentBlockStart {
index: u32,
content_block: AnthropicBlockStart,
},
ContentBlockDelta {
index: u32,
delta: AnthropicDelta,
},
ContentBlockStop {
index: u32,
},
MessageDelta {
delta: AnthropicMessageDelta,
},
MessageStop {},
Ping {},
Error {
error: AnthropicErrorBody,
},
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
#[non_exhaustive]
pub enum AnthropicBlockStart {
Text {
#[serde(default)]
text: String,
},
Thinking {
#[serde(default)]
thinking: String,
},
RedactedThinking {},
ToolUse {
id: String,
name: String,
},
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
#[non_exhaustive]
pub enum AnthropicDelta {
TextDelta {
text: String,
},
ThinkingDelta {
thinking: String,
},
SignatureDelta {},
InputJsonDelta {
partial_json: String,
},
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, Deserialize)]
pub struct AnthropicMessageDelta {
#[serde(default)]
pub stop_reason: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct AnthropicErrorBody {
#[serde(rename = "type", default)]
pub error_type: Option<String>,
#[serde(default)]
pub message: String,
}
pub fn anthropic_finish_reason(raw: &str) -> FinishReason {
match raw.to_ascii_lowercase().as_str() {
"end_turn" | "stop_sequence" => FinishReason::Stop,
"max_tokens" | "model_context_window_exceeded" => FinishReason::Length,
"tool_use" => FinishReason::ToolCalls,
"refusal" => FinishReason::ContentFilter,
_ => FinishReason::Other(raw.to_string()),
}
}
#[cfg(test)]
mod tests;