IVR Extension
Use case
When placing outbound calls to businesses or government services, your agent will often encounter an Interactive Voice Response (IVR) system before reaching a human — “Press 1 for billing, press 2 for support.” The IVR extension automates this navigation: it listens to the IVR audio, uses an LLM to decide what to do, sends DTMF keypad tones, and hands off cleanly to normal conversation mode once a human is reached.How it works
The extension operates in two LLM modes managed by a singleIVRProcessor:
-
Classifier mode — active at call start. The LLM listens to audio and outputs one of two mode tags:
<mode>conversation</mode>(human detected, hand off) or<mode>ivr</mode>(IVR system detected, enter navigation mode). -
IVR navigation mode — activated when the classifier fires
ivr. The processor injects the IVR system prompt into the LLM context and adjusts VAD silence thresholds (shorter stop time so the agent doesn’t wait long between IVR prompts). The LLM then outputs DTMF tags (<dtmf>1</dtmf>) and status tags (<status>completed</status>) as it navigates the menu.
LLMMessagesUpdateFrame to swap the system prompt, and VADParamsUpdateFrame to tighten the silence window during IVR navigation.
Key types
IVRProcessor — the core frame processor:
IVRStatus — reported via OnIVRStatusChanged:
LLM command tags
The IVR system prompt must instruct the LLM to wrap commands in XML tags. The processor pattern-matches these tags in the streaming LLM output:Text outside the XML tags is forwarded downstream as normal
AggregatedTextFrame content. The LLM can still speak to the IVR system between DTMF presses — useful for spoken menu options that require voice input rather than keypad input.Pipeline position
IVRNavigator wraps a [LLM, IVRProcessor] chain into a single pipeline node. The internal LLM context is automatically wired to IVRProcessor.SetSavedMessages so that when conversation mode is triggered, the full conversation history is available in the callback.
Setup
1
Import the extension package
2
Create the navigator
IVRVADStopSecs.3
Register callbacks
4
Add to pipeline
Frames emitted
Voicemail Detection Extension
Use case
When placing outbound calls, you need to know whether a human or an answering machine picked up before your agent starts speaking. Delivering a full sales pitch to voicemail wastes the recording slot and sounds wrong. The voicemail detection extension holds the TTS output in a gate, classifies the audio using a fast LLM, and then either releases the buffered speech (human) or triggers a tailored voicemail response.How it works
The detector inserts a parallel pipeline branch after STT. Both branches receive the transcribed audio simultaneously:- Conversation gate branch — passes frames through normally, but closes if voicemail is detected, preventing the main LLM from wasting compute on a recording.
- Classifier branch — runs a dedicated fast LLM with a classification prompt. Its output is monitored by
ClassificationProcessor, which fires one of two notifiers when it seesCONVERSATIONorVOICEMAILin the LLM response.
CONVERSATION→ the gate opens and releases all buffered TTS frames. The caller hears the agent’s greeting with minimal delay.VOICEMAIL→ the gate discards buffered frames. TheOnVoicemailDetectedcallback fires so your code can push a custom TTS message (e.g. “Please call us back at 555-0100”).
Components
Pipeline position
det.Detector() is the parallel pipeline node inserted after STT. det.Gate() is the TTS buffer inserted after TTS and before the transport sink.
Setup
1
Import the extension package
2
Create the detector
3
Register callbacks
4
Add to pipeline
Classifier prompt requirements
The classifier LLM must respond with exactlyCONVERSATION or VOICEMAIL as a complete response. Any other output is ignored and classification stalls until a valid token appears.
Append voicemail.ClassifierResponseInstruction to any custom prompt — it contains the exact constraint text Voxray expects.
Integration with IVR
For outbound campaigns that encounter both voicemail screening and IVR systems, chain the two extensions: voicemail detection runs first, and onOnConversationDetected you start the IVR navigator: