Expand description
NormalizingStream — the single wrap point that canonicalises an
LLM event stream.
Adapters that implement crate::ports::LlmCompletionPort wrap the
inner SSE-derived stream once with NormalizingStream::new(inner, get_parser(&model.tags)). Every downstream consumer (Axum SSE, CLI,
Tauri, the proxy, the agent loop) then sees a strict OpenAI-shaped
sequence of LlmStreamEvent values, regardless of which dialect the
underlying model speaks.
§Translation rules
TextDelta→ routed throughToolCallParser::push_text; the parser may strip dialect markup and synthesiseLlmStreamEvent::ToolCallDeltaevents for any extracted tool calls.ReasoningDelta→ routed throughToolCallParser::push_reasoningsymmetrically.ToolCallDelta→ forwarded unchanged (already conformant). The wrapper records the highest seenindexso synthesised deltas use non-colliding indices.PromptProgress→ forwarded unchanged.Done→ToolCallParser::finishis called first, any flushed bytes / tool calls / errors are emitted, thenDoneis forwarded last. The contract that every stream ends with exactly oneDoneitem is preserved.
§Errors
Upstream Err items terminate the stream early (we propagate them
verbatim). Non-fatal normalization issues from the parser are surfaced
as LlmStreamEvent::NormalizationError events; they do not
terminate the stream.
Structs§
- Normalizing
Stream - Stream adapter that runs every event through a
ToolCallParserbefore re-emitting the normalized result. See module docs.