Skip to main content
Hooks are the runtime control layer in ai-query. Use hooks when you need to influence execution at stable boundaries. Use turn events when you only need to observe what is happening.

Hooks vs Events vs Lifecycle Overrides

Hooks are intentionally narrow and typed. They are not a full plugin system.

Available Hooks

AgentHooks currently supports:
  1. before_step
  2. after_step
  3. before_tool_call
  4. after_tool_call
  5. on_reasoning_event

Configuring Hooks

The best DX for subclass-based agents is to override hook methods on the class:
For composition-style usage, you can also set hooks on the agent instance:
Override them for one turn:
Per-turn hooks merge over agent defaults.

before_step

Runs before each provider request in a tool loop. Return StepControl to inject messages or stop before the next step begins.

after_step

Runs after a step completes. Use it for logging, status updates, and post-step policy.

before_tool_call

Runs before a tool executes. Return BeforeToolCallResult(block=True, reason=...) to block execution.

after_tool_call

Runs after a tool finishes. Return AfterToolCallResult to override the tool result or terminate the current step batch.
Merge semantics are explicit:
  • omitted fields preserve the original tool result
  • returned fields replace the original value for that field

on_reasoning_event

Runs when provider reasoning/thinking output arrives.
This hook runs in addition to the agent’s legacy on_reasoning_event callback if you configured both.

Chump-Style Example

Best Practices

  • keep hooks small
  • use hooks for control and policy, not presentation
  • use events for UI output
  • prefer agent-level defaults and only override per turn when necessary
  • avoid expensive work inside before_step and before_tool_call