pub enum LlmStreamEvent {
TextDelta {
content: String,
},
ReasoningDelta {
content: String,
},
ToolCallDelta {
index: usize,
id: Option<String>,
name: Option<String>,
arguments: Option<String>,
},
PromptProgress {
processed: u32,
total: u32,
cached: u32,
time_ms: u64,
},
Usage {
prompt_tokens: u32,
completion_tokens: u32,
total_tokens: u32,
cached_tokens: Option<u32>,
},
Done {
finish_reason: String,
},
UpstreamError {
message: String,
error_type: String,
code: String,
},
NormalizationError {
kind: NormalizationErrorKind,
raw: String,
},
}Expand description
A single event produced by a streaming LLM response.
These low-level events are the currency of crate::ports::LlmCompletionPort;
they are parsed by adapter crates from raw SSE frames and handed to
gglib-agent’s stream collector, which:
- Forwards
TextDeltaitems directly to the caller’sAgentEventchannel so text appears in real time. - Accumulates
ToolCallDeltafragments until the stream ends, then assembles them intoToolCallvalues. - Waits for
Donebefore triggering tool execution.
Variants§
TextDelta
An incremental text fragment from the model’s response.
ReasoningDelta
An incremental reasoning/thinking fragment (CoT tokens).
Produced by reasoning-capable models (e.g. DeepSeek R1, QwQ) when
llama-server is started with --reasoning-format deepseek. The
runtime adapter maps delta["reasoning_content"] frames to this
variant; the stream collector forwards them as
AgentEvent::ReasoningDelta and accumulates them in a separate
buffer that is never sent back to the LLM as context.
ToolCallDelta
An incremental fragment of a tool-call request.
The adapter crate streams these before the model has finished
generating the full arguments JSON. The stream collector accumulates
all deltas for a given index into a single ToolCall.
Fields
PromptProgress
Prompt-processing progress from llama-server.
Emitted when the request includes return_progress: true. These
frames arrive during the pre-fill phase (before any TextDelta),
giving real-time visibility into how far along token ingestion is.
Fields
Usage
Token usage totals for the completed response.
Emitted when the request includes stream_options.include_usage: true (see gglib_proxy’s inject_streaming_body_overrides).
Per the OpenAI streaming convention this arrives as a single
trailing chunk with an empty/absent choices array, immediately
before the [DONE] sentinel — never mixed with TextDelta or
ToolCallDelta events. Consumers that care about real token counts
(e.g. clients feeding a context-window UI widget) read this event;
everyone else can ignore it.
Fields
cached_tokens: Option<u32>How many of prompt_tokens were served from the KV cache rather
than re-processed, from usage.prompt_tokens_details.cached_tokens
(llama.cpp’s n_prompt_tokens_cache; the same figure it reports as
timings.cache_n).
None when the upstream omits the field — an older llama.cpp, or
any other OpenAI-compatible server that doesn’t report it. Absent
and zero are deliberately distinct: zero means “nothing was
reused”, which is a real measurement, while None means “not
reported” and must not be counted as a cache miss.
Done
Signals the end of the stream.
Every conforming stream must end with exactly one Done item.
Fields
UpstreamError
An upstream error reported inline, mid-stream.
Some OpenAI-compatible servers (including llama.cpp) can emit a bare
{"error": {...}} frame in the middle of an otherwise-successful SSE
response — e.g. a context-length overflow discovered only once
generation is underway — rather than failing the initial HTTP
response. Without special handling this frame carries no choices
array and would otherwise be silently discarded by parsers that treat
“no choices” as an empty keepalive/heartbeat frame.
error_type and code default to "server_error"/"upstream_error"
respectively when the upstream frame omits them, mirroring the
existing convention in gglib_proxy::forward’s pre-flight upstream
error handling.
Fields
NormalizationError
A non-fatal normalization issue surfaced by the
crate::normalize layer.
Emitted when a dialect-specific parser detects malformed markup
(e.g. a Qwen <tool_call> whose body is not valid JSON, or a tag
that the stream ended without closing). The stream is not
aborted; the offending bytes are simply discarded or surfaced via
this event so consumers can log diagnostics.
Fields
kind: NormalizationErrorKindStructured detail about what went wrong.
Trait Implementations§
Source§impl Clone for LlmStreamEvent
impl Clone for LlmStreamEvent
Source§fn clone(&self) -> LlmStreamEvent
fn clone(&self) -> LlmStreamEvent
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for LlmStreamEvent
impl Debug for LlmStreamEvent
Source§impl PartialEq for LlmStreamEvent
impl PartialEq for LlmStreamEvent
Source§fn eq(&self, other: &LlmStreamEvent) -> bool
fn eq(&self, other: &LlmStreamEvent) -> bool
self and other values to be equal, and is used by ==.