#[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
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
ToolCallDelta
A JSON fragment of the tool call’s arguments.
Fields
ToolCallComplete
The fully assembled tool call, ready to execute.
Fields
Usage(Usage)
Token usage information for this LLM call.
IterationStart
A new iteration of the tool loop is starting.
Fields
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
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
result: ToolResultThe result from the tool.
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
action: LoopActionThe 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.