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

> Filter and transform context when handing off between agents

Handoff filters control what context passes when one agent hands off to another — reducing tokens, focusing relevance, and stripping sensitive data.

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

coordinator = Agent(
    name="Coordinator",
    instructions="Route tasks to specialists with trimmed context",
    handoffs=[
        Handoff(
            agent=Agent(name="Analyst", instructions="Analyse the handoff payload"),
            input_filter=handoff_filters.compress_history,
        )
    ],
)

coordinator.start("Prepare a focused brief for the analyst")
```

The user asks the coordinator; filtered context is passed on handoff.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Handoff Filters"
        H[📋 Full History] --> F[🔍 Filters]
        F --> C[✅ Clean Context]
    end

    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef tool fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff
    class H input
    class F tool
    class C output
```

<Info>
  **New in v2.x**: Chain multiple filters with `input_filter=[filter1, filter2]` and use `compress_history` to reduce token usage.
</Info>

## Overview

Handoff filters let you control what context is passed when one agent hands off to another. This helps:

* **Reduce token usage** by removing unnecessary messages
* **Focus context** on relevant information
* **Protect privacy** by filtering sensitive data

## Quick Start

<Steps>
  <Step title="Single filter">
    <CodeGroup>
      ```python Single Filter theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
      from praisonaiagents import Agent, Handoff, handoff_filters

      analyst = Agent(name="Analyst", instructions="Analyze data")

      coordinator = Agent(
          name="Coordinator",
          handoffs=[
              Handoff(
                  agent=analyst,
                  input_filter=handoff_filters.compress_history
              )
          ]
      )
      ```
    </CodeGroup>
  </Step>

  <Step title="Chain filters">
    <CodeGroup>
      ```python Filter Chaining theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
      from praisonaiagents import Agent, Handoff, handoff_filters

      analyst = Agent(name="Analyst", instructions="Analyze data")

      coordinator = Agent(
          name="Coordinator",
          handoffs=[
              Handoff(
                  agent=analyst,
                  input_filter=[
                      handoff_filters.remove_all_tools,
                      handoff_filters.remove_system_messages,
                      handoff_filters.compress_history,
                  ]
              )
          ]
      )
      ```
    </CodeGroup>
  </Step>
</Steps>

## Available Filters

### compress\_history

Compresses all messages into a single summary message. Great for reducing token usage.

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

# Before: Multiple messages
# [
#   {"role": "user", "content": "Hello"},
#   {"role": "assistant", "content": "Hi there!"},
#   {"role": "user", "content": "How are you?"}
# ]

# After: Single compressed message
# [{"role": "user", "content": "Previous conversation summary:\n[user]: Hello\n[assistant]: Hi there!\n[user]: How are you?"}]
```

### remove\_all\_tools

Removes all tool-related messages (tool calls and tool results).

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Removes:
# - Messages with role="tool"
# - Messages with tool_calls field
```

### keep\_last\_n\_messages

Keeps only the last N messages.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Keep last 5 messages
filter_fn = handoff_filters.keep_last_n_messages(5)
```

### remove\_system\_messages

Removes all system messages from the history.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Removes all messages where role="system"
```

## Filter Chaining

<Tip>
  Filters are applied **in order**. Put removal filters first, then compression last.
</Tip>

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

# Recommended order:
# 1. Remove unwanted content
# 2. Limit message count
# 3. Compress remaining

handoff = Handoff(
    agent=target_agent,
    input_filter=[
        handoff_filters.remove_all_tools,      # First: remove tool noise
        handoff_filters.remove_system_messages, # Second: remove system prompts
        handoff_filters.keep_last_n_messages(10), # Third: limit to recent
        handoff_filters.compress_history,       # Last: compress into one
    ]
)
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
flowchart TB
    subgraph Input["Original History (20 messages)"]
        M1[User + Assistant + Tools + System]
    end
    
    subgraph Step1["Step 1: remove_all_tools"]
        M2[User + Assistant + System]
    end
    
    subgraph Step2["Step 2: remove_system_messages"]
        M3[User + Assistant only]
    end
    
    subgraph Step3["Step 3: keep_last_n(10)"]
        M4[Last 10 messages]
    end
    
    subgraph Step4["Step 4: compress_history"]
        M5[1 summary message]
    end
    
    M1 --> M2 --> M3 --> M4 --> M5
    
    style M1 fill:#8B0000,color:#fff
    style M5 fill:#189AB4,color:#fff
```

## How It Works

The user asks the coordinator; on handoff the input filters run in order to trim the history before the target agent receives it.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Coordinator
    participant Filters
    participant Target

    User->>Coordinator: start("Prepare a brief")
    Coordinator->>Filters: Full history on handoff
    Filters->>Filters: remove_tools → compress_history
    Filters->>Target: Clean context
    Target-->>User: Focused response
```

***

## Custom Filters

Create your own filter function:

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

def my_custom_filter(data: HandoffInputData) -> HandoffInputData:
    """Remove messages containing sensitive keywords."""
    sensitive_words = ["password", "secret", "api_key"]
    
    filtered = []
    for msg in data.messages:
        if isinstance(msg, dict):
            content = msg.get("content", "").lower()
            if not any(word in content for word in sensitive_words):
                filtered.append(msg)
    
    data.messages = filtered
    return data

# Use with handoff
handoff = Handoff(
    agent=target_agent,
    input_filter=[
        my_custom_filter,
        handoff_filters.compress_history,
    ]
)
```

## API Reference

### HandoffInputData

The data structure passed to filter functions:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
@dataclass
class HandoffInputData:
    messages: List[Dict[str, Any]]  # Conversation messages
    context: Dict[str, Any]         # Additional context
    source_agent: str               # Name of source agent
    handoff_depth: int = 0          # Current handoff depth
    handoff_chain: List[str] = []   # Chain of agent names
```

### Filter Function Signature

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
def filter_function(data: HandoffInputData) -> HandoffInputData:
    # Modify data.messages as needed
    return data
```

## Examples

<AccordionGroup>
  <Accordion title="Token-Efficient Handoff">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent, Handoff, handoff_filters

    # Minimize tokens passed to specialist
    specialist = Agent(name="Specialist", instructions="Handle complex tasks")

    coordinator = Agent(
        name="Coordinator",
        handoffs=[
            Handoff(
                agent=specialist,
                input_filter=[
                    handoff_filters.remove_all_tools,
                    handoff_filters.keep_last_n_messages(3),
                    handoff_filters.compress_history,
                ]
            )
        ]
    )
    ```
  </Accordion>

  <Accordion title="Privacy-Aware Handoff">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent, Handoff, handoff_filters
    from praisonaiagents import HandoffInputData

    def remove_pii(data: HandoffInputData) -> HandoffInputData:
        """Remove personally identifiable information."""
        import re
        
        for msg in data.messages:
            if isinstance(msg, dict) and "content" in msg:
                # Remove email addresses
                msg["content"] = re.sub(
                    r'\b[\w.-]+@[\w.-]+\.\w+\b',
                    '[EMAIL REDACTED]',
                    msg["content"]
                )
                # Remove phone numbers
                msg["content"] = re.sub(
                    r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b',
                    '[PHONE REDACTED]',
                    msg["content"]
                )
        
        return data

    external_agent = Agent(name="External", instructions="Process request")

    internal_agent = Agent(
        name="Internal",
        handoffs=[
            Handoff(
                agent=external_agent,
                input_filter=[remove_pii, handoff_filters.compress_history]
            )
        ]
    )
    ```
  </Accordion>

  <Accordion title="Focus on Recent Context">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent, Handoff, handoff_filters

    # Only pass last 5 messages, no tools
    analyst = Agent(name="Analyst", instructions="Analyze recent conversation")

    coordinator = Agent(
        name="Coordinator",
        handoffs=[
            Handoff(
                agent=analyst,
                input_filter=[
                    handoff_filters.remove_all_tools,
                    handoff_filters.keep_last_n_messages(5),
                ]
            )
        ]
    )
    ```
  </Accordion>
</AccordionGroup>

## Best Practices

<AccordionGroup>
  <Accordion title="Compress history before large handoffs">
    Passing a full conversation to a specialist wastes tokens on context it doesn't need. Use `handoff_filters.compress_history` (or a custom trim) so the receiving agent gets a focused brief, not the entire transcript.
  </Accordion>

  <Accordion title="Strip tool calls the next agent can't use">
    Tool-call messages from the source agent are noise to a specialist with different tools. Filter them out (`remove_tools`) so the receiving model reasons over content, not stale tool invocations it will never repeat.
  </Accordion>

  <Accordion title="Redact sensitive data at the boundary">
    Handoffs are the natural place to drop secrets, PII, or credentials before another agent sees them. Add a redaction filter to the chain so sensitive fields never cross into an agent that doesn't need them.
  </Accordion>

  <Accordion title="Chain filters in order of intent">
    Filters compose left to right, each receiving the previous filter's output. Order them so structural cuts (remove tools) run before compression, and redaction runs last, so nothing sensitive slips through a later transform.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Handoffs" icon="hand-holding-hand" href="/docs/features/handoffs">
    Agent-to-agent delegation
  </Card>

  <Card title="Agent as Tool" icon="wrench" href="/docs/features/agent-as-tool">
    Use agents as callable tools
  </Card>

  <Card title="Context Policies" icon="shield" href="/docs/features/context-files">
    Control context sharing across agents
  </Card>

  <Card title="Handoff Tool Policy" icon="filter-circle-dollar" href="/docs/features/handoff-tool-policy">
    Secure tool boundaries during handoff
  </Card>
</CardGroup>
