> ## 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.

# Handoff Module

> Documentation for the praisonaiagents.handoff module - Enable agent-to-agent task delegation

# Module praisonaiagents.handoff

The handoff module enables seamless task delegation between AI agents, allowing specialized agents to transfer control to other agents based on expertise or task requirements.

## Classes

### Handoff

The main class that represents a handoff configuration for delegating tasks between agents.

#### Parameters

* `agent: 'Agent'` - The target agent to hand off to
* `tool_name_override: Optional[str] = None` - Custom tool name (defaults to `transfer_to_<agent_name>`)
* `tool_description_override: Optional[str] = None` - Custom tool description for the handoff
* `on_handoff: Optional[Callable] = None` - Callback function executed during handoff
* `input_type: Optional[type] = None` - Type annotation for structured input data
* `input_filter: Optional[Callable[[HandoffInputData], HandoffInputData]] = None` - Function to transform input before passing to target

#### Methods

* `to_tool_function(self, source_agent: 'Agent') → Callable` - Converts the handoff configuration into a callable tool function

### HandoffInputData

A dataclass that standardises the data passed between agents during handoff.

#### Fields

* `messages: List[Message]` - List of conversation history
* `context: Dict[str, Any]` - Dictionary containing additional context (e.g., source agent name)

## Functions

### handoff

Factory function for creating Handoff instances.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def handoff(
    agent: 'Agent',
    tool_name_override: Optional[str] = None,
    tool_description_override: Optional[str] = None,
    on_handoff: Optional[Callable] = None,
    input_type: Optional[type] = None,
    input_filter: Optional[Callable[[HandoffInputData], HandoffInputData]] = None
) -> Handoff
```

## Usage Examples

### Basic Handoff

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

# Create specialised agents
billing_agent = Agent(
    name="Billing Agent",
    role="Handle billing inquiries",
    goal="Resolve billing issues"
)

refund_agent = Agent(
    name="Refund Agent",
    role="Process refunds",
    goal="Handle refund requests"
)

# Create triage agent with handoffs
triage_agent = Agent(
    name="Triage Agent",
    role="Route customer inquiries",
    goal="Direct customers to the right specialist",
    handoffs=[billing_agent, refund_agent]
)
```

### Advanced Handoff with Callbacks

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent, handoff

def log_handoff(source_agent: Agent, input_data: HandoffInputData):
    print(f"Handoff from {source_agent.name} with {len(input_data.messages)} messages")

support_agent = Agent(
    name="Support Agent",
    handoffs=[
        handoff(
            escalation_agent,
            tool_name_override="escalate_to_manager",
            tool_description_override="Escalate complex issues to a manager",
            on_handoff=log_handoff
        )
    ]
)
```

### Handoff with Input Filtering

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import handoff, handoff_filters

# Remove tool calls from conversation history
handoff_with_filter = handoff(
    technical_agent,
    input_filter=handoff_filters.remove_all_tools
)

# Keep only last 5 messages
handoff_with_limit = handoff(
    summary_agent,
    input_filter=handoff_filters.keep_last_n_messages(5)
)
```

### Structured Input Handoff

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from pydantic import BaseModel
from praisonaiagents import Agent, handoff

class EscalationData(BaseModel):
    priority: str
    reason: str
    customer_id: str

escalation_agent = Agent(
    name="Escalation Handler",
    handoffs=[
        handoff(
            manager_agent,
            input_type=EscalationData,
            tool_description_override="Escalate with structured priority data"
        )
    ]
)
```

## Callback Patterns

The `on_handoff` callback supports three patterns:

1. **No parameters** - Simple notification
   ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
   def notify_handoff():
       logging.info("Handoff occurred")
   ```

2. **One parameter** - Receives source agent
   ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
   def log_source(source_agent: Agent):
       print(f"Handoff from: {source_agent.name}")
   ```

3. **Two parameters** - Receives source agent and input data
   ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
   def process_handoff(source_agent: Agent, input_data: HandoffInputData):
       # Access full context and messages
       print(f"Agent: {source_agent.name}")
       print(f"Messages: {len(input_data.messages)}")
   ```

## Built-in Input Filters

The `handoff_filters` module provides common filtering functions:

* `remove_all_tools` - Removes all tool calls from message history
* `keep_last_n_messages(n)` - Keeps only the last n messages
* `remove_system_messages` - Removes system messages from history

## How It Works

1. **Configuration Phase:**

   * Agents are created with a `handoffs` parameter containing target agents
   * The handoff module converts these into callable tool functions
   * Tools are registered with the agent's LLM for function calling

2. **Runtime Delegation:**

   * When an agent determines delegation is needed, it calls the handoff tool
   * The handoff executes any configured callbacks
   * Conversation history is collected and filtered
   * The target agent receives the context and continues the conversation
   * The response is returned to the original caller

3. **Context Preservation:**

   * Full conversation history is maintained
   * Source agent identification is preserved
   * Custom context can be passed via structured inputs

## Best Practices

1. **Design Clear Agent Boundaries** - Each agent should have a specific expertise
2. **Use Descriptive Names** - Tool names should clearly indicate the target agent's role
3. **Implement Callbacks** - Use callbacks for logging, monitoring, or custom logic
4. **Filter Appropriately** - Remove unnecessary context to stay within token limits
5. **Test Handoff Chains** - Ensure agents don't create infinite delegation loops
