Overview

The IVRNavigator is a pipeline component that provides intelligent navigation of IVR phone systems. It combines LLM-based decision making with DTMF tone generation to automatically traverse phone menus toward specified goals. The navigator includes automatic classification between IVR systems and human conversations, enabling flexible call handling scenarios.

Constructor

from pipecat.extensions.ivr.ivr_navigator import IVRNavigator, IVRStatus

IVRNavigator(
    llm,
    ivr_prompt,
    ivr_vad_params=None
)

Parameters

llm
LLMService
required
The LLM service instance used for text generation and navigation decision making.
ivr_prompt
str
required
The navigation goal that will be integrated with the base IVR navigation instructions. This should clearly describe what you want to accomplish (e.g., “Navigate to billing support to discuss account charges”).
ivr_vad_params
Optional[VADParams]
default:"VADParams(stop_secs=2.0)"
Voice Activity Detection parameters optimized for IVR navigation. The default 2.0 second stop time allows the system to hear complete menu options before responding, improving navigation success rates.
The IVRNavigator processes several XML-tagged commands from LLM responses:

DTMF Commands

<dtmf>1</dtmf>        <!-- Single keypress -->
<dtmf>1</dtmf><dtmf>2</dtmf><dtmf>3</dtmf>  <!-- Sequence entry -->
Valid DTMF values: 0-9, *, #

IVR Status Commands

<ivr>detected</ivr>   <!-- IVR system detected, switch to navigation mode -->
<ivr>completed</ivr>  <!-- Navigation goal achieved -->
<ivr>stuck</ivr>      <!-- Unable to proceed -->
<ivr>wait</ivr>       <!-- Waiting for more complete information -->

Mode Classification

<mode>ivr</mode>          <!-- Classified as IVR system -->
<mode>conversation</mode> <!-- Classified as human conversation -->

Event Handlers

The navigator supports two primary event handlers for different interaction scenarios.

on_conversation_detected

Triggered when the system classifies incoming audio as a human conversation rather than an IVR system.
@ivr_navigator.event_handler("on_conversation_detected")
async def on_conversation_detected(processor, conversation_history: List[dict]):
    # Handle human conversation scenario
    # conversation_history contains previous interaction context
    pass
Parameters:
  • processor: The IVRProcessor instance
  • conversation_history: List of message dictionaries from previous context (excluding system messages)

on_ivr_status_changed

Triggered when IVR navigation status changes during the navigation process.
@ivr_navigator.event_handler("on_ivr_status_changed")
async def on_ivr_status_changed(processor, status: IVRStatus):
    # Handle navigation status changes
    if status == IVRStatus.COMPLETED:
        # Navigation successful
        pass
    elif status == IVRStatus.STUCK:
        # Navigation failed
        pass
Parameters:
  • processor: The IVRProcessor instance
  • status: IVRStatus enum value (DETECTED, COMPLETED, STUCK)

IVRStatus Enumeration

from pipecat.extensions.ivr.ivr_navigator import IVRStatus

class IVRStatus(Enum):
    DETECTED = "detected"    # IVR system detected and navigation started
    COMPLETED = "completed"  # Navigation goal successfully achieved
    STUCK = "stuck"         # Navigation unable to proceed
    WAIT = "wait"           # Waiting for more complete information

Built-in Prompts

The IVRNavigator includes sophisticated built-in prompts that handle classification and navigation logic automatically.

Classification Prompt

The navigator starts with an automatic classification system that distinguishes between: IVR System Indicators:
  • Menu options (“Press 1 for billing”, “Press 2 for support”)
  • Automated instructions (“Please enter your account number”)
  • System prompts (“Thank you for calling [company]”)
  • Hold messages (“Please continue to hold”)
Human Conversation Indicators:
  • Personal greetings (“Hello, this is Sarah”)
  • Interactive responses (“Who am I speaking with?”)
  • Natural speech patterns and conversational flow
  • Direct engagement (“I can help with that”)
Once IVR is detected, the system uses your provided goal with comprehensive navigation instructions that include:
  • Decision making logic for menu option selection
  • DTMF sequence handling for data entry (dates, account numbers, phone numbers)
  • Verbal response generation for conversational prompts
  • Completion detection for successful navigation
  • Stuck state recognition for error scenarios
  • Wait state management for incomplete transcriptions

Advanced Usage

Context Preservation

The navigator automatically preserves conversation context when switching between modes:
# Context is automatically saved and restored during mode transitions
# No manual intervention required for basic scenarios

# For advanced context manipulation:
@ivr_navigator.event_handler("on_conversation_detected")
async def handle_conversation(processor, conversation_history):
    # conversation_history contains preserved context
    # Add additional context as needed
    enhanced_context = [
        {"role": "system", "content": "You are a customer service representative."},
        *conversation_history,
        {"role": "assistant", "content": "How can I help you today?"}
    ]

    await task.queue_frame(LLMMessagesUpdateFrame(messages=enhanced_context, run_llm=True))

VAD Parameter Management

# Switch to conversation-optimized timing
@ivr_navigator.event_handler("on_conversation_detected")
async def optimize_for_conversation(processor, conversation_history):
    # Reduce response delay for natural conversation flow
    conversation_vad = VADParams(stop_secs=0.8)
    await task.queue_frame(VADParamsUpdateFrame(params=conversation_vad))

Integration Examples

Basic Pipeline Integration

from pipecat.pipeline.pipeline import Pipeline
from pipecat.processors.ivr.ivr_navigator import IVRNavigator

pipeline = Pipeline([
    transport.input(),
    stt,
    context_aggregator.user(),
    ivr_navigator,    # Add in place of LLM
    tts,
    transport.output(),
    context_aggregator.assistant()
])