Quick Start
1
Simple Usage
Register a hook with Hook return values:
add_hook and any agent picks it up automatically:Noneor no return → AllowFalse→ Deny"reason"→ Deny with custom message
2
With HooksConfig
Attach a
HooksConfig to a specific agent for scoped hooks:Which Hook Point Should I Use?
Pick the lifecycle event that matches what you want to observe or block.How It Works
Available Hook Events
The events most agents will ever need are the agent / tool / LLM / error / session ones — start here.This is the core lifecycle subset. The SDK ships ~40 events in total — including plugin/system hooks (
on_init, on_shutdown), tool-result persistence (tool_result_persist), message-level bot hooks (before_message, after_message, message_received, message_sending, message_sent), gateway hooks (gateway_start, gateway_stop), compaction hooks (before_compaction, after_compaction), permission/config/auth hooks (on_permission_ask, on_config, on_auth), schedule hooks (schedule_add, schedule_remove, schedule_trigger), background-job hooks (job_completed), kanban task hooks, and Claude-Code-parity events (user_prompt_submit, notification, subagent_stop, setup).See Hook Events for the complete reference with input dataclasses and examples for each.on_retry is emitted once per retryable error, just before the back-off sleep. It runs whether the LLM call is agent.chat(...) (sync) or await agent.achat(...) (async). Sync-registered callbacks on the async path are run in a thread executor — they cannot block the event loop.
Two lookalike fields. Function-style hooks return
HookResult and set modified_input to rewrite the payload. Shell-command hooks parse into HookOutput and use modified_data for the same purpose. When you write a hook in Python, always use HookResult(decision="allow", modified_input={...}) — the internal Agent code reads .modified_input on hook results.Configuration Options
HooksConfig SDK Reference
Full parameter reference for HooksConfig
Common Patterns
Security Filtering
Audit Logging
Tool Matching with HookRegistry
HookEvent.BEFORE_TOOL and HookEvent.AFTER_TOOL now fire on both the sync (agent.chat(...)) and async (await agent.achat(...)) tool-execution paths. When a BEFORE_TOOL hook blocks a call, the tool returns "Execution of {tool_name} was blocked by security policy." on either path. AFTER_TOOL results aggregate context onto the tool output (string concat, or the _additional_context key on a dict result). The check costs nothing when no hooks are registered.Best Practices
Keep hooks lightweight
Keep hooks lightweight
Hooks run synchronously before/after each operation. Avoid network calls or heavy computation inside hook functions — use async queues for heavy processing.
Return None to allow, string to deny
Return None to allow, string to deny
The simplest hook contract: return nothing (or
None) to allow, return a string with a reason to block. This keeps hooks readable.Use add_hook for global rules, HooksConfig for per-agent rules
Use add_hook for global rules, HooksConfig for per-agent rules
add_hook registers hooks globally — all agents in the process obey them. Use HooksConfig when you need different rules per agent.Set _strict_hooks=True in tests
Set _strict_hooks=True in tests
By default, hook exceptions are logged as warnings and execution continues. Set
agent._strict_hooks = True in tests so hook failures surface immediately as errors.before_agent / after_agent / BEFORE_TOOL_DEFINITIONS cost nothing when unregistered
before_agent / after_agent / BEFORE_TOOL_DEFINITIONS cost nothing when unregistered
before_agent, after_agent, and BEFORE_TOOL_DEFINITIONS cost nothing when no hook is registered — the runtime checks has_hooks() before building the input (including os.getcwd(), the tools list, and any deep-copy of tool definitions) on both sync (chat) and async (achat) paths. Register these hooks in production without a per-turn overhead concern.Related
Hook Events
Complete list of ~40 events with input dataclasses and examples
Guardrails
Validate agent output quality with automatic retry
Callbacks
Observe agent events for UI and logging purposes

