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

> API reference for the agent handoff system

## Overview

The handoff module provides functionality for agents to delegate tasks to other agents dynamically. It includes the `Handoff` class for creating custom handoff tools and the `handoff` function for standard handoff operations.

## Classes

### `Handoff`

A subclass of `Tool` that provides handoff-specific functionality.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
class Handoff(Tool):
    def __init__(
        self,
        name: str,
        agent: Union[str, Agent],
        template: str = DEFAULT_TEMPLATE,
        description: str = DEFAULT_DESCRIPTION,
        input_model: Optional[Type[BaseModel]] = None,
        callback: Optional[Callable] = None
    )
```

#### Parameters

<ParamField path="name" type="str" required>
  The name of the handoff tool
</ParamField>

<ParamField path="agent" type="Union[str, Agent]" required>
  Target agent name or Agent instance
</ParamField>

<ParamField path="template" type="str" default="DEFAULT_TEMPLATE">
  Template for handoff instructions
</ParamField>

<ParamField path="description" type="str" default="DEFAULT_DESCRIPTION">
  Description of the handoff tool
</ParamField>

<ParamField path="input_model" type="Optional[Type[BaseModel]]">
  Pydantic model for structured input
</ParamField>

<ParamField path="callback" type="Optional[Callable]">
  Callback function called during handoff
</ParamField>

#### Methods

##### `run()`

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def run(self, message: str = "") -> str
```

Executes the handoff operation.

**Parameters:**

* `message` (str): Message to pass to the target agent

**Returns:**

* `str`: Handoff prompt with instructions

**Example:**

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
handoff_tool = Handoff(name="escalate", agent="Supervisor")
result = handoff_tool.run("Customer needs manager approval")
```

### `HandoffInputData`

Pydantic model for structured handoff input when using `input_model`.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
class HandoffInputData(BaseModel):
    agent: str = Field(..., description="The name of the agent to hand off to")
    message: str = Field("", description="Additional message or context")
```

## Functions

### `handoff()`

Creates a handoff tool or executes a handoff operation.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def handoff(
    agent: Optional[Union[str, Agent]] = None,
    name: str = "handoff",
    description: str = DEFAULT_DESCRIPTION,
    template: str = DEFAULT_TEMPLATE,
    input_model: Optional[Type[BaseModel]] = HandoffInputData,
    callback: Optional[Callable] = None,
    # Direct execution parameters
    message: str = ""
) -> Union[Handoff, str]
```

#### Parameters

<ParamField path="agent" type="Optional[Union[str, Agent]]">
  Target agent for handoff
</ParamField>

<ParamField path="name" type="str" default="handoff">
  Name of the handoff tool
</ParamField>

<ParamField path="description" type="str">
  Description of the handoff functionality
</ParamField>

<ParamField path="template" type="str">
  Template for handoff instructions
</ParamField>

<ParamField path="input_model" type="Optional[Type[BaseModel]]">
  Model for structured input
</ParamField>

<ParamField path="callback" type="Optional[Callable]">
  Callback function for handoff events
</ParamField>

<ParamField path="message" type="str">
  Message for direct handoff execution
</ParamField>

#### Returns

* `Handoff`: When creating a tool (no message provided)
* `str`: When executing directly (message provided)

#### Usage Examples

**Creating a handoff tool:**

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Basic handoff tool
transfer = handoff(agent="Specialist")

# Custom named handoff
escalate = handoff(
    agent="Supervisor",
    name="escalate_to_supervisor",
    description="Escalate complex issues to supervisor"
)

# With callback
def log_handoff(from_agent, to_agent, context):
    print(f"Handoff: {from_agent} -> {to_agent}")
    
transfer_with_log = handoff(
    agent="Support",
    callback=log_handoff
)
```

**Direct handoff execution:**

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Execute handoff immediately
prompt = handoff(
    agent="TechSupport",
    message="User experiencing login issues"
)
```

### `prompt_with_handoff_instructions()`

Generates a handoff prompt with specific instructions and context.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def prompt_with_handoff_instructions(
    agent: str,
    template: str,
    message: str = ""
) -> str
```

#### Parameters

<ParamField path="agent" type="str" required>
  Name of the target agent
</ParamField>

<ParamField path="template" type="str" required>
  Instruction template
</ParamField>

<ParamField path="message" type="str">
  Additional context or message
</ParamField>

#### Returns

* `str`: Formatted handoff prompt

## Built-in Filters

### `handoff_filters()`

Returns available handoff filter options.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def handoff_filters() -> List[str]
```

#### Returns

List of available filters:

* `"all"` - Accept handoffs from any agent
* `"none"` - Reject all handoffs
* `"self"` - Only accept from same agent
* `"other"` - Accept from any agent except self
* `"team:<name>"` - Only accept from agents in specified team

#### Example

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
filters = handoff_filters()
print(filters)  # ["all", "none", "self", "other", "team:"]

# Use in agent configuration
agent = Agent(
    name="Specialist",
    handoff_filter="team:support"
)
```

## Constants

### `DEFAULT_TEMPLATE`

Default template for handoff instructions:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
DEFAULT_TEMPLATE = '''Transferred to: {agent}
{message}

Continue the conversation and help the user with their request.'''
```

### `DEFAULT_DESCRIPTION`

Default description for handoff tools:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
DEFAULT_DESCRIPTION = "Hand off the conversation to another agent"
```

## Integration with Agents

### Using Handoffs in Agent Configuration

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

# Method 1: Specify handoff targets
agent = Agent(
    name="Support",
    handoffs=["Billing", "Technical", "Sales"]
)

# Method 2: Provide handoff as a tool
transfer_tool = handoff(name="transfer")
agent = Agent(
    name="Support",
    tools=[transfer_tool]
)

# Method 3: Multiple custom handoffs
escalate = handoff(agent="Supervisor", name="escalate")
transfer = handoff(agent="Specialist", name="transfer")

agent = Agent(
    name="Support",
    tools=[escalate, transfer]
)
```

### Callback Function Signature

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def handoff_callback(
    from_agent: str,
    to_agent: str, 
    context: Dict[str, Any]
) -> bool:
    """
    Process handoff event.
    
    Args:
        from_agent: Name of agent initiating handoff
        to_agent: Name of target agent
        context: Handoff context including message and history
        
    Returns:
        bool: True to allow handoff, False to block
    """
    # Custom logic here
    return True
```

## Error Handling

The handoff system handles various error conditions:

* **Invalid agent name**: Returns error message if target agent not found
* **Circular handoffs**: Can be prevented using handoff filters
* **Callback errors**: Logged and handoff continues if callback fails

## Best Practices

1. **Use descriptive names** for custom handoff tools
2. **Implement callbacks** for logging and monitoring
3. **Set appropriate filters** to prevent handoff loops
4. **Provide context** in handoff messages
5. **Test handoff chains** to ensure smooth transitions

## Complete Example

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent, Task, AgentTeam, handoff
from typing import Dict, Any

# Callback for logging
def log_handoffs(from_agent: str, to_agent: str, context: Dict[str, Any]) -> bool:
    timestamp = context.get('timestamp', 'unknown')
    message = context.get('message', '')
    print(f"[{timestamp}] Handoff: {from_agent} -> {to_agent}")
    print(f"Context: {message[:50]}...")
    return True

# Create specialized handoff tools
escalate_to_manager = handoff(
    agent="Manager",
    name="escalate",
    description="Escalate to manager for approval",
    callback=log_handoffs
)

transfer_to_tech = handoff(
    agent="TechSupport",
    name="transfer_to_tech",
    description="Transfer technical issues to tech support",
    callback=log_handoffs
)

# Create agents with handoff capabilities
frontdesk = Agent(
    name="FrontDesk",
    role="Customer Service Representative",
    goal="Help customers and route complex issues",
    tools=[escalate_to_manager, transfer_to_tech],
    handoff_filter="other"  # Can receive from others but not self
)

manager = Agent(
    name="Manager",
    role="Customer Service Manager",
    goal="Handle escalated issues and approvals",
    handoff_filter="all"  # Can receive from anyone
)

tech_support = Agent(
    name="TechSupport",
    role="Technical Support Specialist",
    goal="Resolve technical issues",
    handoff_filter="team:support"  # Only from support team
)

# Create workflow
workflow = AgentTeam(
    agents=[frontdesk, manager, tech_support],
    memory=True
)

# The agents can now hand off tasks based on conversation context
```
