Hooks allow you to intercept and customize agent behavior at key lifecycle points. They can add context, block operations, modify inputs, or trigger side effects.
Hooks allow intercepting and customizing agent behavior at key points
in the execution lifecycle. They can add context, block operations,
modify inputs, or trigger side effects.
Currently supported events:
- pre_run / post_run: Before/after agent.run() processes a prompt
- pre_tool_use / post_tool_use: Before/after a tool is called
-pre_run:[]post_run:[]# Hooks executed after agent.run() completes.pre_tool_use:[]# Hooks executed before a tool is called. Can block or modify the call.post_tool_use:[]# Hooks executed after a tool completes.
The command receives hook input as JSON via stdin and should return
JSON output via stdout. Exit code 0 = success, exit code 2 = block.
By default, command hooks run in the agent's execution environment
(e.g. Docker, E2B sandbox) so they operate on the same filesystem
as the agent's tools. Use the environment field to override with
a specific environment, or set it to a local path to force local execution.
-type:commandcommand:/path/to/script.sh# Shell command to execute. Supports $PROJECT_DIR variable.env:null# Additional environment variables for the command.environment:null# Per-hook execution environment override.matcher:null# Regex pattern to match tool names. None or '' matches all.timeout:60.0# Maximum execution time in seconds.enabled:true# Whether this hook is active.
-type:callableimport_path:myproject.hooks.validate_tool# Dotted import path to the callable.arguments:{}# Additional keyword arguments passed to the callable.matcher:null# Regex pattern to match tool names. None or '' matches all.timeout:60.0# Maximum execution time in seconds.enabled:true# Whether this hook is active.
The prompt is sent to a fast LLM which returns a structured decision.
Use $TOOL_NAME, $TOOL_INPUT, \(INPUT placeholders in the prompt.</p>
<div class="language-yaml highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Prompt Hook (YAML)</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-2-1">1</a></span>
<span class="normal"><a href="#__codelineno-2-2">2</a></span>
<span class="normal"><a href="#__codelineno-2-3">3</a></span>
<span class="normal"><a href="#__codelineno-2-4">4</a></span>
<span class="normal"><a href="#__codelineno-2-5">5</a></span>
<span class="normal"><a href="#__codelineno-2-6">6</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1"></a><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">prompt</span>
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2"></a><span class="w"> </span><span class="nt">prompt</span><span class="p">:</span><span class="w"> </span><span class="s">'Evaluate</span><span class="nv"> </span><span class="s">if</span><span class="nv"> </span><span class="s">this</span><span class="nv"> </span><span class="s">tool</span><span class="nv"> </span><span class="s">call</span><span class="nv"> </span><span class="s">is</span><span class="nv"> </span><span class="s">safe:</span><span class="nv"> </span><span class="s">\)INPUT'# Prompt template for LLM evaluation. Supports placeholders.model:null# Model to use for evaluation. Defaults to a fast model if not specified.matcher:null# Regex pattern to match tool names. None or '*' matches all.timeout:60.0# Maximum execution time in seconds.enabled:true# Whether this hook is active.
Uses an LLM to evaluate the action with structured output.
agents:my_agent:model:openai:gpt-4ohooks:pre_tool_use:-type:promptprompt:|Should this command be allowed?Tool: $TOOL_NAMEInput: $TOOL_INPUTmodel:openai:gpt-4o-minimatcher:"Bash"
fromagentpoolimportAgentfromagentpool.hooksimportAgentHooks,CallableHookdefmy_pre_tool_hook(tool_name:str,tool_input:dict,**kwargs):iftool_name=="Bash"and"rm"intool_input.get("command",""):return{"decision":"deny","reason":"rm commands not allowed"}return{"decision":"allow"}hooks=AgentHooks(pre_tool_use=[CallableHook(event="pre_tool_use",fn=my_pre_tool_hook,matcher="Bash",)])agent=Agent(model="openai:gpt-4o",hooks=hooks)