Skip to main content

Module stream

Module stream 

Source
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 through ToolCallParser::push_text; the parser may strip dialect markup and synthesise LlmStreamEvent::ToolCallDelta events for any extracted tool calls.
  • ReasoningDelta → routed through ToolCallParser::push_reasoning symmetrically.
  • ToolCallDelta → forwarded unchanged (already conformant). The wrapper records the highest seen index so synthesised deltas use non-colliding indices.
  • PromptProgress → forwarded unchanged.
  • DoneToolCallParser::finish is called first, any flushed bytes / tool calls / errors are emitted, then Done is forwarded. The contract that every stream carries exactly one Done item is preserved — but Done is not treated as an absolute end-of-stream signal. Per the OpenAI stream_options.include_usage convention (and llama.cpp’s actual wire behaviour), a trailing LlmStreamEvent::Usage event can legitimately arrive after Done, before the underlying byte stream closes — that event (and PromptProgress / NormalizationError / UpstreamError) still gets forwarded. Any content-bearing event arriving after Done (TextDelta, ReasoningDelta, ToolCallDelta, a second Done) is dropped defensively, since a well-formed stream never sends those.

§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§

NormalizingStream
Stream adapter that runs every event through a ToolCallParser before re-emitting the normalized result. See module docs.

Type Aliases§

InnerStream 🔒