Skip to main content

NormalizingStream

Struct NormalizingStream 

Source
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: usize

Lowest 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: bool

true 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: bool

true 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

Source

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.

Source

fn enqueue_parser_output(&mut self, out: ParserOutput)

Translate one parser output batch into the queued event sequence.

Source

fn handle_upstream(&mut self, event: LlmStreamEvent)

Process one upstream event and queue the resulting downstream events.

Trait Implementations§

Source§

impl Stream for NormalizingStream

Source§

type Item = Result<LlmStreamEvent, Error>

Values yielded by the stream.
Source§

fn poll_next( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the current task for wakeup if the value is not yet available, and returning None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where S: Stream<Item = Result<T, E>> + ?Sized,

§

type Ok = T

The type of successful values yielded by this future
§

type Error = E

The type of failures yielded by this future
§

fn try_poll_next( self: Pin<&mut S>, cx: &mut Context<'_>, ) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more