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.
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
The name of the handoff tool
agent
Union[str, Agent]
required
Target agent name or Agent instance
template
str
default:"DEFAULT_TEMPLATE"
Template for handoff instructions
description
str
default:"DEFAULT_DESCRIPTION"
Description of the handoff tool
input_model
Optional[Type[BaseModel]]
Pydantic model for structured input
Callback function called during handoff
Methods
run()
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:
handoff_tool = Handoff(name="escalate", agent="Supervisor")
result = handoff_tool.run("Customer needs manager approval")
Pydantic model for structured handoff input when using input_model
.
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.
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
agent
Optional[Union[str, Agent]]
Description of the handoff functionality
Template for handoff instructions
input_model
Optional[Type[BaseModel]]
Model for structured input
Callback function for handoff events
Message for direct handoff execution
Returns
Handoff
: When creating a tool (no message provided)
str
: When executing directly (message provided)
Usage Examples
Creating a handoff tool:
# 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:
# 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.
def prompt_with_handoff_instructions(
agent: str,
template: str,
message: str = ""
) -> str
Parameters
Additional context or message
Returns
str
: Formatted handoff prompt
Built-in Filters
handoff_filters()
Returns available handoff filter options.
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
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:
DEFAULT_TEMPLATE = '''Transferred to: {agent}
{message}
Continue the conversation and help the user with their request.'''
DEFAULT_DESCRIPTION
Default description for handoff tools:
DEFAULT_DESCRIPTION = "Hand off the conversation to another agent"
Integration with Agents
Using Handoffs in Agent Configuration
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
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
- Use descriptive names for custom handoff tools
- Implement callbacks for logging and monitoring
- Set appropriate filters to prevent handoff loops
- Provide context in handoff messages
- Test handoff chains to ensure smooth transitions
Complete Example
from praisonaiagents import Agent, Task, PraisonAIAgents, 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 = PraisonAIAgents(
agents=[frontdesk, manager, tech_support],
memory=True
)
# The agents can now hand off tasks based on conversation context