An agent loop repeatedly sends the current state to a model, interprets the model’s response, executes allowed tool calls, records their results, and asks the model what to do next. The loop ends on a final answer, policy denial, approval pause, budget limit, cancellation, unrecoverable error, or explicit completion condition.
You will trace a run as state transitions, distinguish one model turn from one application run, and design stop conditions that do not depend on the model deciding to behave.
The model is a planner inside an event loop, not the loop itself.
An SDK performs much of this plumbing, but your application still owns the boundary around it.
Represent a run as an append-only event stream:
The conversation is useful model context. The event stream is operational truth. Do not confuse them.
This pseudocode exposes the responsibilities that an SDK later implements:
Notice what the model does not own: identity, permission, timeout, budget, checkpointing, or final verification.
Test transitions, not prose:
Failure injection: Configure a tool to time out. The loop should record a classified failure, apply only its configured retry policy, and either choose a safe alternative or stop. It must not retry forever.
Use multiple, independent stops:
“The prompt says stop when finished” is guidance, not enforcement.
Draw the state machine for running, waiting_for_approval, retry_scheduled, succeeded, failed, and cancelled. Define which transitions are legal and which events make each transition auditable.