> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Hooks Module

> Event hooks for intercepting and modifying agent behavior

# Hooks Module

The hooks module provides a powerful hook system for intercepting and modifying agent behavior at various lifecycle points. Unlike callbacks (which are for UI events), hooks can intercept, modify, or block tool execution.

## Installation

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
pip install praisonaiagents
```

## Features

* **Event-based hook system** - BeforeTool, AfterTool, BeforeAgent, etc.
* **Shell command hooks** - External integrations via shell commands
* **Python function hooks** - In-process customization
* **Matcher patterns** - Selective hook execution
* **Decision outcomes** - allow, deny, block, ask

## Quick Start (Simplified API)

The simplest way to use hooks:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import add_hook, has_hook, remove_hook

# Register a hook - no HookResult needed!
@add_hook('before_tool')
def log_tools(event_data):
    print(f"Tool: {event_data.tool_name}")
    # No return = allow

@add_hook('before_tool')
def block_dangerous(event_data):
    if 'delete' in event_data.tool_name:
        return "Delete not allowed"  # String = deny with reason
    # No return = allow

# Check and manage hooks
has_hook('before_tool')  # True
remove_hook(hook_id)     # Remove by ID
```

### Return Values

| Return             | Meaning                 |
| ------------------ | ----------------------- |
| `None` / no return | Allow                   |
| `True`             | Allow                   |
| `False`            | Deny                    |
| `"reason"`         | Deny with message       |
| `HookResult(...)`  | Full control (advanced) |

## Classes

### HookEvent

Enumeration of available hook events.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import HookEvent

# Available events
HookEvent.BEFORE_TOOL      # Before tool execution
HookEvent.AFTER_TOOL       # After tool execution
HookEvent.BEFORE_AGENT     # Before agent runs
HookEvent.AFTER_AGENT      # After agent completes
HookEvent.SESSION_START    # When session starts
HookEvent.SESSION_END      # When session ends
```

### HookDecision

Possible decisions a hook can return.

| Decision | Description                      |
| -------- | -------------------------------- |
| `allow`  | Allow the operation to proceed   |
| `deny`   | Deny the operation with a reason |
| `block`  | Block the operation silently     |
| `ask`    | Prompt for user confirmation     |

### HookResult

Result returned by a hook function.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import HookResult

# Allow the operation
result = HookResult(decision="allow")

# Deny with reason
result = HookResult(decision="deny", reason="Tool blocked by policy")

# Modify the input
result = HookResult(decision="allow", modified_input={"query": "sanitized"})
```

#### Attributes

| Attribute        | Type   | Description                             |
| ---------------- | ------ | --------------------------------------- |
| `decision`       | `str`  | The decision (allow/deny/block/ask)     |
| `reason`         | `str`  | Reason for the decision                 |
| `modified_input` | `dict` | Modified input to pass to the operation |
| `metadata`       | `dict` | Additional metadata                     |

### HookRegistry

Registry for managing hooks.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import HookRegistry, HookEvent

registry = HookRegistry()

# Register a function hook using decorator
@registry.on(HookEvent.BEFORE_TOOL)
def my_hook(event_data):
    return HookResult(decision="allow")

# Register a command hook
registry.register_command_hook(
    event=HookEvent.BEFORE_TOOL,
    command="python /path/to/validator.py",
    matcher="write_*"  # Only match tools starting with write_
)
```

#### Methods

| Method                                           | Description                           |
| ------------------------------------------------ | ------------------------------------- |
| `on(event)`                                      | Decorator to register a function hook |
| `register_command_hook(event, command, matcher)` | Register a shell command hook         |
| `register_function_hook(event, func, matcher)`   | Register a function hook              |
| `get_hooks(event)`                               | Get all hooks for an event            |
| `clear()`                                        | Clear all registered hooks            |

### HookRunner

Executes hooks for events.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import HookRunner, HookRegistry

registry = HookRegistry()
runner = HookRunner(registry)

# Run hooks for an event
result = runner.run(HookEvent.BEFORE_TOOL, event_data)
```

## Event Input Types

### BeforeToolInput

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import BeforeToolInput

input_data = BeforeToolInput(
    tool_name="write_file",
    tool_input={"path": "/tmp/file.txt", "content": "data"},
    agent_name="Writer"
)
```

### AfterToolInput

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import AfterToolInput

input_data = AfterToolInput(
    tool_name="write_file",
    tool_input={"path": "/tmp/file.txt"},
    tool_output="File written successfully",
    agent_name="Writer"
)
```

### BeforeAgentInput / AfterAgentInput

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import BeforeAgentInput, AfterAgentInput

before = BeforeAgentInput(
    agent_name="Researcher",
    task_description="Research AI trends"
)

after = AfterAgentInput(
    agent_name="Researcher",
    task_description="Research AI trends",
    result="Research completed"
)
```

## Usage Examples

### Basic Hook Registration

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonaiagents.hooks import HookRegistry, HookEvent, HookResult

# Create registry
registry = HookRegistry()

# Register a hook to block dangerous tools
@registry.on(HookEvent.BEFORE_TOOL)
def security_hook(event_data):
    dangerous_tools = ["delete_file", "execute_command"]
    if event_data.tool_name in dangerous_tools:
        return HookResult(
            decision="deny",
            reason=f"Tool '{event_data.tool_name}' is blocked by security policy"
        )
    return HookResult(decision="allow")

# Use with agent
agent = Agent(
    name="Assistant",
    hooks=registry
)
```

### Logging Hook

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import HookRegistry, HookEvent, HookResult
import logging

registry = HookRegistry()

@registry.on(HookEvent.BEFORE_TOOL)
def log_tool_calls(event_data):
    logging.info(f"Tool called: {event_data.tool_name}")
    logging.info(f"Input: {event_data.tool_input}")
    return HookResult(decision="allow")

@registry.on(HookEvent.AFTER_TOOL)
def log_tool_results(event_data):
    logging.info(f"Tool result: {event_data.tool_output}")
    return HookResult(decision="allow")
```

### Input Sanitization Hook

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import HookRegistry, HookEvent, HookResult

registry = HookRegistry()

@registry.on(HookEvent.BEFORE_TOOL)
def sanitize_input(event_data):
    if event_data.tool_name == "search_web":
        # Sanitize the query
        sanitized_query = event_data.tool_input.get("query", "").strip()
        return HookResult(
            decision="allow",
            modified_input={"query": sanitized_query}
        )
    return HookResult(decision="allow")
```

### Shell Command Hook

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import HookRegistry, HookEvent

registry = HookRegistry()

# Run external validator before file writes
registry.register_command_hook(
    event=HookEvent.BEFORE_TOOL,
    command="python /path/to/file_validator.py",
    matcher="write_*"  # Only for tools starting with write_
)
```

### Matcher Patterns

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.hooks import HookRegistry, HookEvent, HookResult

registry = HookRegistry()

# Match specific tools
registry.register_function_hook(
    event=HookEvent.BEFORE_TOOL,
    func=my_hook,
    matcher="write_file"  # Exact match
)

# Match with wildcard
registry.register_function_hook(
    event=HookEvent.BEFORE_TOOL,
    func=my_hook,
    matcher="file_*"  # Matches file_read, file_write, etc.
)

# Match multiple patterns
registry.register_function_hook(
    event=HookEvent.BEFORE_TOOL,
    func=my_hook,
    matcher=["read_*", "write_*"]  # Multiple patterns
)
```

## Best Practices

1. **Keep hooks lightweight** - Hooks run synchronously, avoid heavy operations
2. **Use matchers** - Only run hooks for relevant tools
3. **Return early** - Return `allow` quickly for non-matching cases
4. **Log decisions** - Log why hooks deny operations for debugging
5. **Handle errors** - Wrap hook logic in try/except to avoid breaking agents

## Related

* [Agent](/docs/sdk/praisonaiagents/agent/agent) - Using hooks with agents
* [Tools](/docs/sdk/praisonaiagents/tools/tools) - Tool system
* [Guardrails](/docs/sdk/praisonaiagents/guardrails/guardrails) - Output validation
