The request lifecycle#
Knowing the order of hooks is how you pick the right one. Each stage finishes for
every extension before the next stage starts, and extensions run in ascending
priority (lower numbers first).
new request
│
on_tool() register the tools this request can call
│
on_state() restore history and inject system instructions
│
on_message() transform the pending user input
│
append input
│
before_run()
│
turn 1..n before_turn() → model step → tools → after_turn()
│
after_run() → on_success() → RUN_COMPLETED
Because on_tool always completes before on_state, a guidance extension
can describe every tool no matter which extension registered it. Priority only
changes the order within a stage.
One turn#
before_turn()
│
before_model(context, request) adjust context before this model call
│
model streams deltas → final response
│
after_model()
│
├─ no tool calls ─▶ after_turn() ─▶ final answer
│
└─ tool calls ────▶ before_tool() ─▶ run tool ─▶ after_tool()
│
after_turn() ◀───────┘
│
next turn
Emit UI progress from any hook with await context.emit(AgentEvent(...)). The
event becomes visible to whoever is consuming Agent.stream().
Which hook should I use?#
Hook |
Use it for |
|---|---|
|
Registering request-scoped tools. |
|
Restoring history and adding system instructions. |
|
Rewriting the user’s input before it is sent. |
|
Anything that must change immediately before a model call, including compaction. |
|
Reading the response, usage, or recording a checkpoint. |
|
Approving, rewriting, or observing one tool call. |
|
Persisting results and releasing per-request state. |
|
Cleaning up after a failure or cancellation. |
Success, failure, cancellation#
Cleanup needs all three paths:
A model or hook error calls
on_errorand propagates the original exception.Cancelling the request publishes
RunCancelledEvent;on_errorandon_successdo not run.A tool failure is different: it becomes an unsuccessful tool result so the model can react, rather than failing the whole request.
See Lifecycle hook reference for every hook and State, concurrency, and cleanup for a cleanup pattern that handles all three.