pub async fn tool_loop<Ctx: LoopDepth + Send + Sync + 'static>(
provider: &dyn DynProvider,
registry: &ToolRegistry<Ctx>,
params: ChatParams,
config: ToolLoopConfig,
ctx: &Ctx,
) -> Result<ToolLoopResult, LlmError>Expand description
Runs the LLM in a tool-calling loop until completion.
Each iteration:
- Calls
provider.generate_boxed()with the current messages - If the response contains tool calls, executes them via the registry
- Appends tool results as messages and repeats
- Stops when the LLM returns without tool calls, or max iterations is reached
§Depth Tracking
If Ctx implements LoopDepth, nested calls are tracked automatically.
When config.max_depth is set and the context’s depth exceeds the limit,
returns Err(LlmError::MaxDepthExceeded).
§Events
If config.on_event is set, the callback will be invoked with
ToolLoopEvents at key points during execution:
ToolLoopEvent::IterationStartat the beginning of each iterationToolLoopEvent::LlmResponseReceivedafter the LLM respondsToolLoopEvent::ToolExecutionStartbefore each tool executesToolLoopEvent::ToolExecutionEndafter each tool completes
§Errors
Returns LlmError if:
- The provider returns an error
- Max depth is exceeded (returns
LlmError::MaxDepthExceeded) - Max iterations is exceeded (returns in result with
TerminationReason::MaxIterations)