use serde_json::Value;
#[derive(Debug, Clone)]
pub enum StreamEvent {
TextDelta(String),
ReasoningDelta(String),
ReasoningBlockStart,
FunctionCallStart {
index: usize,
call_id: String,
name: String,
},
FunctionCallDelta { index: usize, delta: String },
FunctionCallDone { index: usize, arguments: String },
UsageUpdate {
usage: Option<Value>,
stop_reason: Option<String>,
},
Done(Value),
Error(String),
}
pub trait StreamCallback: Send + Sync {
fn on_event(&self, event: &StreamEvent);
}
pub struct FnStreamCallback<F: Fn(&StreamEvent) + Send + Sync>(pub F);
impl<F: Fn(&StreamEvent) + Send + Sync> StreamCallback for FnStreamCallback<F> {
fn on_event(&self, event: &StreamEvent) {
(self.0)(event);
}
}
pub fn parse_sse_data(line: &str) -> Option<Value> {
let data = line.strip_prefix("data: ")?;
if data == "[DONE]" {
return None;
}
serde_json::from_str(data).ok()
}
pub fn parse_sse_block(event_line: Option<&str>, data_line: &str) -> Option<(String, Value)> {
let event_type = event_line
.and_then(|l| l.strip_prefix("event: "))
.map(|s| s.to_string())
.unwrap_or_default();
let data = parse_sse_data(data_line)?;
Some((event_type, data))
}