pub struct NormalizingStream {
inner: Pin<Box<dyn Stream<Item = Result<LlmStreamEvent>> + Send>>,
parser: Box<dyn ToolCallParser>,
queued: VecDeque<LlmStreamEvent>,
next_index: usize,
terminated: bool,
done_forwarded: bool,
}Expand description
Stream adapter that runs every event through a ToolCallParser before
re-emitting the normalized result. See module docs.
Fields§
§inner: Pin<Box<dyn Stream<Item = Result<LlmStreamEvent>> + Send>>§parser: Box<dyn ToolCallParser>§queued: VecDeque<LlmStreamEvent>Events ready to emit on the next poll. A single upstream event can
expand to many downstream events (e.g. Done flushes parser state
before propagating).
next_index: usizeLowest tool-call index that is safe to use for a synthesised delta.
Bumped past every upstream index we observe so downstream
collectors can use indices as keys without collision.
terminated: booltrue once the upstream inner stream is fully exhausted (ended or
errored). Subsequent polls return None. Note this is not set
merely because a Done event was seen — see done_forwarded.
done_forwarded: booltrue once we’ve forwarded the upstream Done event.
Done is not treated as an absolute end-of-stream signal: per the
OpenAI stream_options.include_usage convention (and llama.cpp’s
wire behaviour), a trailing Usage event legitimately arrives
after the finish_reason/Done chunk, before the underlying byte
stream actually closes. Once this flag is set, only trailer-safe
events (Usage, PromptProgress, NormalizationError,
UpstreamError) are still queued; any further content-bearing event
(TextDelta, ReasoningDelta, ToolCallDelta, a second Done) is
dropped defensively — a well-formed stream never sends these after
Done, and the parser has already been finalised.
Implementations§
Source§impl NormalizingStream
impl NormalizingStream
Sourcepub fn new(
inner: Pin<Box<dyn Stream<Item = Result<LlmStreamEvent>> + Send>>,
parser: Box<dyn ToolCallParser>,
) -> Self
pub fn new( inner: Pin<Box<dyn Stream<Item = Result<LlmStreamEvent>> + Send>>, parser: Box<dyn ToolCallParser>, ) -> Self
Wrap inner so every event is normalized through parser.
Sourcefn enqueue_parser_output(&mut self, out: ParserOutput)
fn enqueue_parser_output(&mut self, out: ParserOutput)
Translate one parser output batch into the queued event sequence.
Sourcefn handle_upstream(&mut self, event: LlmStreamEvent)
fn handle_upstream(&mut self, event: LlmStreamEvent)
Process one upstream event and queue the resulting downstream events.