Controlling the Loop
TheAgentLoop exposes two methods for running an agent: execute() for
simple run-to-completion workflows, and iterate() for step-by-step
observation. Both operate on an immutable AgentState and return the
resulting state after the agent finishes.
execute() vs iterate()
Running to Completion
Theexecute() method runs the full loop and returns the final state in a
single call. This is the right choice for most application code where you
simply need the agent’s answer:
execute() is a thin wrapper around iterate() — it simply
consumes the iterator and returns the last yielded state.
Stepping Through Execution
Theiterate() method returns a generator that yields the state after each
completed step. This gives you the opportunity to observe progress, log
intermediate results, update a UI, or apply custom logic between steps:
$stepState is a complete AgentState snapshot. You can
inspect messages, tool executions, errors, and token usage at every
point in the agent’s run. The final yield includes the post-execution
state after the AfterExecution hooks have fired.
Use execute() for straightforward application logic. Use iterate() when
you need progress updates, streaming indicators, step-level logging, or any
form of real-time observation.
Inspecting State After Execution
Once the loop finishes, the returnedAgentState provides a comprehensive
set of accessors to understand what happened during the run.
Execution Summary
Step History
Every completed step is recorded as aStepExecution in the execution’s
step history. You can iterate over all steps to review the full trace of
the agent’s reasoning:
Tool Execution Details
When the agent used tools during its run, you can drill into the execution details of each tool call:Stop Reason
Every execution ends for a reason. The stop reason tells you whether the agent completed naturally, hit a limit, encountered an error, or was stopped by an external request:Reading the Response
AgentState provides two convenience methods for extracting the agent’s
output, each suited to different situations.
finalResponse()
Returns the output messages from the last step, but only if that step was aFinalResponse (the model answered without requesting tool calls). If
the execution ended mid-tool-use or with an error, this returns an empty
Messages collection:
currentResponse()
Returns the most recent visible output regardless of step type. It first checks for a final response; if none exists, it falls back to the output of the current or last step. This is useful duringiterate() loops where
you want to show the latest output even if the agent has not finished:
Listening to Events
TheAgentLoop dispatches events at every significant point in the
execution lifecycle. You can subscribe to specific event types or listen
to all events with a wiretap.
Subscribing to Specific Events
UseonEvent() to register a listener for a particular event class. The
listener receives the fully-typed event object:
Wiretap (All Events)
Usewiretap() to observe every event the loop dispatches. This is
invaluable for debugging and logging:
Available Events
The loop emits the following events during execution:| Event | When |
|---|---|
AgentExecutionStarted | The loop begins a new execution |
AgentStepStarted | A new step is about to begin |
InferenceRequestStarted | An LLM request is being sent |
InferenceResponseReceived | An LLM response has arrived |
ToolCallStarted | A tool call is about to execute |
ToolCallCompleted | A tool call has finished |
ToolCallBlocked | A hook blocked a tool call |
AgentStepCompleted | A step has finished (includes usage and timing) |
ContinuationEvaluated | The loop evaluated whether to continue |
StopSignalReceived | A stop signal was emitted |
TokenUsageReported | Token usage was recorded for a step |
AgentExecutionStopped | The loop is stopping (includes stop reason) |
AgentExecutionCompleted | The execution has fully finished |
AgentExecutionFailed | The execution ended with an error |
EventDispatcher. If you are using
the AgentBuilder, the builder can wire a parent event handler so that
events propagate up to your application’s event system.
Debugging Execution
For quick diagnostics,AgentState provides a debug() method that returns
an array summarizing the execution: