Documentation Index
Fetch the complete documentation index at: https://allhandsai-burak-2864-agent-based-hook-evaluation.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
A ready-to-run example is available here!
Overview
Hooks let you observe and customize key lifecycle moments in the SDK without forking core code. Typical uses include:- Logging and analytics
- Emitting custom metrics
- Auditing or compliance
- Tracing and debugging
Hook Types
| Hook | When it runs | Can block? |
|---|---|---|
| PreToolUse | Before tool execution | Yes (exit 2) |
| PostToolUse | After tool execution | No |
| UserPromptSubmit | Before processing user message | Yes (exit 2) |
| Stop | When agent tries to finish | Yes (exit 2) |
| SessionStart | When conversation starts | No |
| SessionEnd | When conversation ends | No |
Exit Codes
Hook scripts signal their result through their exit code. The SDK matches the Claude Code hook contract:0— success. The operation proceeds.stdoutis parsed as JSON for structured output (decision,reason,additionalContext,continue).2— block. The operation is denied. ForPreToolUseandUserPromptSubmitthis rejects the action; forStopit prevents the agent from finishing and the conversation continues.stderr/reasonis surfaced as feedback.- Any other non-zero exit code — non-blocking error.
successis set toFalseand the error is logged viaHookExecutionEvent, but the operation still proceeds.
Key Concepts
- Registration points: subscribe to events or attach pre/post hooks around LLM calls and tool execution
- Isolation: hooks run outside the agent loop logic, avoiding core modifications
- Composition: enable or disable hooks per environment (local vs. prod)
Ready-to-run Example
This example is available on GitHub: examples/01_standalone_sdk/33_hooks
examples/01_standalone_sdk/33_hooks/main.py
The model name should follow the LiteLLM convention:
provider/model_name (e.g., anthropic/claude-sonnet-4-5-20250929, openai/gpt-4o).
The LLM_API_KEY should be the API key for your chosen provider.Hook Scripts
The example uses external hook scripts in thehook_scripts/ directory:
block_dangerous.sh - PreToolUse hook
block_dangerous.sh - PreToolUse hook
log_tools.sh - PostToolUse hook
log_tools.sh - PostToolUse hook
inject_git_context.sh - UserPromptSubmit hook
inject_git_context.sh - UserPromptSubmit hook
require_summary.sh - Stop hook
require_summary.sh - Stop hook
Agent-based Hooks
Besides shell scripts, a hook can delegate its decision to an LLM-driven sub-agent by settingtype="agent". The sub-agent receives the lifecycle event
as JSON, reasons about it semantically, and replies with a decision payload:
PreToolUse reviewer that recognises awk '{print}' /etc/passwd as reading a
sensitive file even though no obvious keyword (cat, /etc/shadow) appears.
Key fields on an agent HookDefinition:
system_prompt— the policy the reviewer agent follows.tools— optional tools the reviewer may use (e.g.["file_editor"]to inspect the workspace before deciding).timeout/max_iterations— bound how long the reviewer runs.
agent-hook:<name> usage
bucket that is merged back into the parent conversation’s metrics. If no LLM is
available or the reviewer fails to produce a valid decision, the hook falls
open (allows) so it never blocks the agent on an internal error.
This example is available on GitHub: examples/01_standalone_sdk/51_agent_hooks
examples/01_standalone_sdk/51_agent_hooks/main.py
The model name should follow the LiteLLM convention:
provider/model_name (e.g., anthropic/claude-sonnet-4-5-20250929, openai/gpt-4o).
The LLM_API_KEY should be the API key for your chosen provider.Next Steps
- See also: Metrics and Observability
- Architecture: Events

