Skip to main content

LoopEvent

Enum LoopEvent 

Source
#[non_exhaustive]
pub enum LoopEvent { TextDelta(String), ReasoningDelta(String), ToolCallStart { index: u32, id: String, name: String, }, ToolCallDelta { index: u32, json_chunk: String, }, ToolCallComplete { index: u32, call: ToolCall, }, Usage(Usage), IterationStart { iteration: u32, message_count: usize, }, ToolExecutionStart { call_id: String, tool_name: String, arguments: Value, }, ToolExecutionEnd { call_id: String, tool_name: String, result: ToolResult, duration: Duration, }, LoopDetected { tool_name: String, consecutive_count: u32, action: LoopAction, }, Done(ToolLoopResult), }
Expand description

Unified event emitted during tool loop execution.

LoopEvent merges LLM streaming events (text deltas, tool call fragments) with loop-level lifecycle events (iteration boundaries, tool execution progress) into a single stream. This gives consumers a complete, ordered view of everything happening inside the loop.

The stream terminates with Done carrying the final ToolLoopResult.

§Example

use llm_stack::tool::{tool_loop_stream, ToolLoopConfig, LoopEvent};
use futures::StreamExt;
use std::sync::Arc;

let mut stream = tool_loop_stream(provider, registry, params, ToolLoopConfig::default(), Arc::new(()));
while let Some(event) = stream.next().await {
    match event.unwrap() {
        LoopEvent::TextDelta(text) => print!("{text}"),
        LoopEvent::IterationStart { iteration, .. } => {
            println!("\n--- Iteration {iteration} ---");
        }
        LoopEvent::ToolExecutionStart { tool_name, .. } => {
            println!("[calling {tool_name}...]");
        }
        LoopEvent::ToolExecutionEnd { tool_name, duration, .. } => {
            println!("[{tool_name} completed in {duration:?}]");
        }
        LoopEvent::Done(result) => {
            println!("\nDone: {:?}", result.termination_reason);
            break;
        }
        _ => {}
    }
}

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

TextDelta(String)

A fragment of the model’s text output.

§

ReasoningDelta(String)

A fragment of the model’s reasoning (chain-of-thought) output.

§

ToolCallStart

Announces that a new tool call has started.

Fields

§index: u32

Zero-based index identifying this call when multiple tools are invoked in parallel.

§id: String

Provider-assigned identifier linking start → deltas → complete.

§name: String

The name of the tool being called.

§

ToolCallDelta

A JSON fragment of the tool call’s arguments.

Fields

§index: u32

The tool-call index this delta belongs to.

§json_chunk: String

A chunk of the JSON arguments string.

§

ToolCallComplete

The fully assembled tool call, ready to execute.

Fields

§index: u32

The tool-call index this completion corresponds to.

§call: ToolCall

The complete, parsed tool call.

§

Usage(Usage)

Token usage information for this LLM call.

§

IterationStart

A new iteration of the tool loop is starting.

Fields

§iteration: u32

The iteration number (1-indexed).

§message_count: usize

Number of messages in the conversation so far.

§

ToolExecutionStart

About to execute a tool.

When parallel_tool_execution is true, events arrive in completion order (whichever tool finishes first), not the order the LLM listed the calls. Use call_id to correlate start/end pairs.

Fields

§call_id: String

The tool call ID from the LLM.

§tool_name: String

Name of the tool being called.

§arguments: Value

Arguments passed to the tool.

§

ToolExecutionEnd

Tool execution completed.

When parallel_tool_execution is true, events arrive in completion order. Use call_id to correlate with the corresponding ToolExecutionStart.

Fields

§call_id: String

The tool call ID from the LLM.

§tool_name: String

Name of the tool that was called.

§result: ToolResult

The result from the tool.

§duration: Duration

How long the tool took to execute.

§

LoopDetected

A tool call loop was detected.

Emitted when the same tool is called with identical arguments for threshold consecutive times. Only emitted when LoopDetectionConfig is configured.

Fields

§tool_name: String

Name of the tool being called repeatedly.

§consecutive_count: u32

Number of consecutive identical calls detected.

§action: LoopAction

The action being taken in response.

§

Done(ToolLoopResult)

The loop has finished. Carries the final ToolLoopResult with the accumulated response, usage, iteration count, and termination reason.

Trait Implementations§

Source§

impl Clone for LoopEvent

Source§

fn clone(&self) -> LoopEvent

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for LoopEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. 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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

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

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

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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

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

fn with_current_subscriber(self) -> WithDispatch<Self>

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