use serde::{Deserialize, Serialize};
#[derive(Debug, Clone)]
pub enum StreamEvent {
Text(String),
ToolCall {
id: String,
name: String,
arguments: String,
},
Thinking(String),
Usage {
input_tokens: u32,
output_tokens: u32,
},
Stop,
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum StopReason {
#[serde(rename = "stop")]
Stop,
#[serde(rename = "length")]
Length,
#[serde(rename = "tool_use")]
ToolUse,
#[serde(rename = "error")]
Error,
#[serde(rename = "aborted")]
Aborted,
}
impl StopReason {
pub fn as_str(self) -> &'static str {
match self {
Self::Stop => "stop",
Self::Length => "length",
Self::ToolUse => "tool_use",
Self::Error => "error",
Self::Aborted => "aborted",
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct Usage {
pub input_tokens: u32,
pub output_tokens: u32,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(tag = "type")]
pub enum AssistantStreamEvent {
#[serde(rename = "start")]
Start {
partial: crate::message::AssistantMessage,
},
#[serde(rename = "text_start")]
TextStart {
content_index: usize,
partial: crate::message::AssistantMessage,
},
#[serde(rename = "text_delta")]
TextDelta {
content_index: usize,
delta: String,
partial: crate::message::AssistantMessage,
},
#[serde(rename = "text_end")]
TextEnd {
content_index: usize,
content: String,
partial: crate::message::AssistantMessage,
},
#[serde(rename = "thinking_start")]
ThinkingStart {
content_index: usize,
partial: crate::message::AssistantMessage,
},
#[serde(rename = "thinking_delta")]
ThinkingDelta {
content_index: usize,
delta: String,
partial: crate::message::AssistantMessage,
},
#[serde(rename = "thinking_end")]
ThinkingEnd {
content_index: usize,
content: String,
partial: crate::message::AssistantMessage,
},
#[serde(rename = "tool_call_start")]
ToolCallStart {
content_index: usize,
partial: crate::message::AssistantMessage,
},
#[serde(rename = "tool_call_delta")]
ToolCallDelta {
content_index: usize,
delta: String,
partial: crate::message::AssistantMessage,
},
#[serde(rename = "tool_call_end")]
ToolCallEnd {
content_index: usize,
tool_call: crate::message::ToolCall,
partial: crate::message::AssistantMessage,
},
#[serde(rename = "done")]
Done {
reason: StopReason,
message: crate::message::AssistantMessage,
},
#[serde(rename = "error")]
Error {
reason: StopReason,
message: crate::message::AssistantMessage,
},
}
impl AssistantStreamEvent {
pub fn is_terminal(&self) -> bool {
matches!(self, Self::Done { .. } | Self::Error { .. })
}
}