Documentation Index
Fetch the complete documentation index at: https://docs.xpander.ai/llms.txt
Use this file to discover all available pages before exploring further.
@on_tool_before, @on_tool_after, and @on_tool_error register hooks that fire around tool invocations: useful for logging, validation, caching, alerting, or analytics. The hooks run during every Tool.ainvoke (which means around every framework-driven tool call too).
Required signatures
| Decorator | Parameters | Notes |
|---|---|---|
@on_tool_before | tool, payload, payload_extension, tool_call_id, agent_version | Fires before the tool runs. |
@on_tool_after | tool, payload, payload_extension, tool_call_id, agent_version, result | Fires after a successful invocation. result is the tool’s response. |
@on_tool_error | tool, payload, payload_extension, tool_call_id, agent_version, error | Fires when the invocation raises. error is the exception. |
| Parameter | Type | Description |
|---|---|---|
tool | Tool | The tool being invoked. |
payload | Any | The input payload after schema validation. |
payload_extension | dict | None | Extra fields that will be deep-merged into the payload. |
tool_call_id | str | None | Correlation id matching the LLM tool-call. |
agent_version | str | None | Agent version pinned for the call. |
result (after only) | Any | The tool’s response. |
error (error only) | Exception | The raised exception. |
Decorator forms
@on_tool_after and @on_tool_error. The optional configuration parameter is reserved for future use; hooks don’t currently read it.
Examples
Log every tool call
Block invocations matching a payload pattern
Hooks can’t cancel invocations directly (the runtime catches their exceptions and continues), but you can mutate state or short-circuit by raising a guard before the call:@register_tool function bodies.
Cache successful results
Alert on failures
Notes
- Hooks fire once per tool invocation, regardless of whether the tool is local or remote.
- Exceptions in hooks are caught and logged via
loguru: they never crash the invocation pipeline. - Hooks are class-level on
ToolHooksRegistry(process-wide singleton). There’s no scoping to a specific repository. - The auto-emitted
ToolCallRequest/ToolCallResultevents ontask.aevents()are independent of these hooks. The hooks fire even whenreport_activity=FalseinTool.ainvoke.

