Skip to main content

What are Hooks?

Hooks are optional functions that run automatically at specific points during agent execution. They allow you to modify data, perform side effects, and integrate with external systems without modifying the framework code.

How Hooks Work

Hooks are functions that receive execution context (ThreadState) and data, then either:
  1. Transform data and return modified version (transformation hooks)
  2. Perform side effects without returning anything (event hooks)
All hooks are wrapped in error handling - if a hook throws an error, it’s logged but execution continues with original data.

Defining Hooks

Hooks are defined using defineHook with a unique identifier:
Each hook requires three properties:

Hook ID Requirements

  • IDs must be unique across all hooks in the project
  • IDs must be snake_case (lowercase letters, numbers, underscores, starting with a letter)
  • IDs should be descriptive of what the hook does
Benefits of defineHook:
  • Strict typing: Parameters automatically typed based on hook type
  • IntelliSense support: Full autocomplete in your editor
  • Type checking: Catch errors at compile time

Hook Scoping

Hooks must be explicitly declared on prompts or agents to execute. Undeclared hooks do not run.

Prompt-Level Hooks

Prompt hooks execute when that prompt is the active execution context.

Agent-Level Hooks

Agent hooks are a fallback — they execute when the active prompt has no hooks defined.

Resolution Priority

  1. If the current prompt declares hooks, only those hooks run
  2. If the prompt has no hooks but the agent does, agent hooks run
  3. If neither declares hooks, no hooks execute
This means hooks in agents/hooks/ that aren’t referenced by any prompt or agent will never run. Always add hook IDs to the relevant prompt or agent.

Multiple Hooks of Same Type

You can define multiple hooks of the same hook type with different IDs:
When both are included in a prompt’s hooks array, they execute in the order listed:

Hook Types

Transformation Hooks

These hooks receive data, modify it, and return the modified version:
Available transformation hooks:
  • after_system_message - Modify the rendered system message for the current request
  • filter_messages - Filter message rows before transformation
  • prefilter_llm_history - Modify messages before sending to LLM
  • before_create_message - Modify message before database insert
  • before_update_message - Modify updates before applying
  • before_store_tool_result - Modify tool result before storage
  • after_tool_call_success - Modify or remove successful tool results
  • after_tool_call_failure - Modify or remove failed tool results

Event Hooks

These hooks run after an event occurs and don’t return anything:
Available event hooks:
  • after_create_message - After message inserted
  • after_update_message - After message updated

Common Use Cases

Message Filtering

Filter out unwanted messages before they’re sent to the LLM:

External Logging

Send events to external analytics services:

Tool Call Transformation

Convert tool calls to user messages:

Message Enrichment

Add context to messages before storage:

Sanitize Tool Results

Clean sensitive data from tool results before storage:

Available Hooks Quick Reference

File Organization

Hooks are auto-discovered from the agents/hooks/ directory:
Requirements:
  • File names can be anything (hook is identified by its id)
  • Default export required
  • Use defineHook for type safety
  • Multiple hooks of the same type are supported (each with a unique id)

Error Handling

All hooks are wrapped in error handling that:
  1. Catches exceptions without breaking execution
  2. Logs errors with [Hooks] ✗ prefix
  3. Returns original data as fallback
Always wrap risky operations (API calls, etc.) in try-catch blocks to handle errors gracefully.

Best Practices

Hooks run in the critical execution path. Keep them fast (< 100ms ideal):
Wrap risky operations in try-catch:
Check data structure before processing:
Only add hooks to prompts/agents that need them:

ThreadState Context

All hooks receive a ThreadState object containing execution context:
Use ThreadState to:
  • Check which agent is executing (state.agentId)
  • Read invocation or subagent creation arguments (state.arguments)
  • Access execution state (state.execution?.stepCount)
  • Get/inject messages
  • Emit events to frontend
  • Access the file system

Next Steps

Hooks API Reference

Complete hooks specification

ThreadState

Learn about ThreadState interface

Tools

Create custom tools

Examples

See hooks in action