use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::canonical::error::CanonicalError;
use crate::canonical::request::Role;
pub const EVENT_SCHEMA_VERSION: u8 = 1;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
#[non_exhaustive]
pub enum Event {
MessageStart {
v: u8,
#[serde(default)]
id: Option<String>,
#[serde(default)]
model: Option<String>,
role: Role,
},
ContentStart {
index: u32,
kind: ContentKind,
},
ContentDelta {
index: u32,
delta: Delta,
},
ContentStop {
index: u32,
},
Usage(Usage),
Finish {
#[serde(flatten)]
reason: FinishReason,
},
Error(CanonicalError),
#[serde(skip)]
Raw(Vec<u8>),
End,
#[serde(other)]
Other,
}
impl Event {
pub fn message_start(id: Option<String>, model: Option<String>, role: Role) -> Event {
Event::MessageStart {
v: EVENT_SCHEMA_VERSION,
id,
model,
role,
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum ContentKind {
Text {},
ToolUse {
id: String,
name: String,
},
Thinking {
id: Option<String>,
},
RedactedThinking {
data: String,
},
ServerToolUse {
id: String,
name: String,
},
ServerToolResult {
kind: String,
tool_use_id: String,
content: Value,
},
Other(Value),
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
#[allow(clippy::enum_variant_names)]
pub enum Delta {
TextDelta(String),
JsonDelta(String),
ThinkingDelta(String),
SignatureDelta(String),
EncryptedReasoningDelta(String),
Other(Value),
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Usage {
pub input_tokens: Option<u32>,
pub output_tokens: Option<u32>,
pub cache_read_tokens: Option<u32>,
pub cache_write_tokens: Option<u32>,
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum FinishReason {
Stop,
Length,
ToolUse,
StopSequence,
Refusal {
category: String,
explanation: Option<String>,
},
Pause,
Other(String),
}