The Loop
The loop is the core of AG2B's runtime — the cycle that turns a single LLM call into an agent.
Before the loop
- Fire
onChatStart. Carries the user message and abort signal. - Commit the user message to history. Fires
onMessage.
One iteration explained
A pass through the loop runs in four phases.
Request
- Build the request — history snapshot, enabled tools, scope contexts, base system prompt.
- Fire
preRequest. Hooks can modify the request or short-circuit with a synthetic response. - Call the provider. Skipped if
preRequestsupplied a response.
Response
- Fire
onResponse. Hooks can replace the response before the agent uses it. - Commit the assistant message to history. Fires
onMessage.
Tool handling
- No tool calls? The loop ends — fire
onChatDoneand return the response. - Tool calls? Run sequentially. For each:
- Fire
preToolCall. Hooks can modify args or short-circuit with a result/error. - Execute the handler. Throws in handlers don't terminate the chat — they become tool messages the LLM sees on the next turn.
- Fire
onToolCallResulton success,onToolCallErroron failure. - Commit the tool message. Fires
onMessage.
- Fire
Continue or stop
- Increment the iteration counter and start the next pass — unless the counter hits
maxIterations, in which case the loop throwsAg2bMaxIterationsError.
Stop Conditions
A chat ends in one of five ways. The terminal hook depends on what stopped it:
| Trigger | Hook |
|---|---|
| LLM returns a turn without tool calls | onChatDone |
AbortSignal aborts the run | onChatAbort |
Counter reaches maxIterations | onChatError |
| Provider throws (HTTP, malformed payload, network) | onChatError |
| Any non-terminal hook throws | onChatError |