Event Reference

VoiceRun uses an event-driven architecture. Your agent receives input events and yields output events to control the conversation.

Event Lifecycle#

  1. Event handler is invoked once per input event
  2. Event handler can yield zero or more output events
  3. Each output event is processed in the order emitted

Input Events#

Input events are triggered by user actions or system events and passed to your agent's handler function.

StartEvent#

Emitted when a new voice agent session has started.

class StartEvent(Event): pass

Usage:

if isinstance(event, StartEvent): yield TextToSpeechEvent( text="Hello! How can I help you today?", voice="nova" )

TextEvent#

Emitted when the user speaks or types text.

class TextEvent(Event): data: { "source": str # Source of input: "speech" or "text" "text": str # The transcribed or typed text "language": str # Language code (optional, provided by STT) }

Usage:

if isinstance(event, TextEvent): user_message = event.data.get("text", "N/A") source = event.data.get("source") # "speech" or "text"

TimeoutEvent#

Emitted when the user does not speak for 5 seconds of silence. The timeout counter increments with each consecutive timeout and resets when the user speaks.

class TimeoutEvent(Event): data: { "count": int # Number of consecutive timeouts "ms_since_input": int # Milliseconds since last input }

Usage:

if isinstance(event, TimeoutEvent): count = event.data.get("count", 0) ms_since_input = event.data.get("ms_since_input", 0) if count >= 3: yield TextToSpeechEvent(text="Are you still there?", voice="nova") elif count == 1: yield TextToSpeechEvent(text="Take your time.", voice="nova")

DTMFEvent#

Emitted when DTMF tones (phone keypad input) are received.

class DTMFEvent(Event): data: { "digits": str # The DTMF digits pressed (e.g., "123#") }

Usage:

if isinstance(event, DTMFEvent): digits = event.data.get("digits") if digits == "1": yield TextToSpeechEvent(text="You pressed one.", voice="nova")

Output Events#

Output events are yielded by your agent to perform actions like speaking, playing audio, or transferring sessions.

TextToSpeechEvent#

Converts text to speech and plays it to the user.

class TextToSpeechEvent(Event): def __init__( self, text: str, # Text to speak voice: str | TextToSpeechIdentifier = "nova", # Voice name or identifier cache: bool = True, # Cache generated audio interruptible: bool | None = None, # Can user interrupt instructions: str = "", # Voice styling (OpenAI only) speed: float = 1.0, # Playback speed language: str = "en", # Language code stream: bool | None = None, # Enable streaming TTS )

Usage:

# Basic usage yield TextToSpeechEvent( text="Hello, how can I help you?", voice="nova" ) # With voice styling (OpenAI only) yield TextToSpeechEvent( text="Welcome to our service!", voice="alloy", instructions="enthusiastic and professional", speed=1.25 ) # Non-interruptible announcement yield TextToSpeechEvent( text="Please do not interrupt this important message.", voice="nova", interruptible=False ) # Using TextToSpeechIdentifier for specific provider voice yield TextToSpeechEvent( text="G'day mate!", voice={"provider": "azure", "identifier": "en-AU-WilliamNeural"} )

AudioEvent#

Plays audio from a URL.

class AudioEvent(Event): def __init__( self, path: str, # URL of the audio file interruptible: bool = True, # Can user interrupt loop: bool = False, # Loop the audio )

Usage:

# Play audio file yield AudioEvent(path="https://example.com/audio.mp3") # Play non-interruptible audio yield AudioEvent( path="https://example.com/important.mp3", interruptible=False ) # Loop background music yield AudioEvent( path="https://example.com/hold-music.mp3", loop=True )

SilenceEvent#

Plays silence for a specified duration.

class SilenceEvent(Event): def __init__( self, duration: int # Duration in milliseconds )

Usage:

# Pause for 2 seconds yield SilenceEvent(duration=2000)

StopEvent#

Ends the current voice agent session.

class StopEvent(Event): def __init__( self, closing_speech: str | None = None, # Optional goodbye message voice: str | TextToSpeechIdentifier | None = None, # Voice for closing speech speed: float = 1.0, # Playback speed language: str = "en", # Language code )

Usage:

# End session immediately yield StopEvent() # End session with closing message yield StopEvent( closing_speech="Thank you for calling. Goodbye!", voice="nova" )

LogEvent#

Logs a message to the system logs.

class LogEvent(Event): def __init__( self, message: str, # Message to log location: str | None = None # Optional source location )

Usage:

from primfunctions.logger import logger logger.info("User requested account balance")

Tip: Use primfunctions.logger instead of yielding LogEvent directly. The logger can be called from anywhere in your code — not just inside the handler.


TransferSessionEvent#

Transfers the session to another phone number or agent.

class TransferSessionEvent(Event): def __init__( self, *, phone_number: str | None = None, # Phone number to transfer to agent_id: str | None = None, # Agent ID to transfer to environment: str | None = None, # Target environment data: dict | None = None, # Context data to pass closing_speech: str | None = None, # Message before transfer voice: str | TextToSpeechIdentifier | None = None, # Voice for closing speech speed: float = 1.0, # Playback speed language: str = "en", # Language code )

Usage:

# Phone transfer (cold transfer) yield TransferSessionEvent(phone_number="+15555555555") # Phone transfer with context yield TransferSessionEvent( phone_number="+15555551234", closing_speech="I'm transferring you to a specialist.", voice="nova", data={"reason": "technical_support", "priority": "high"} ) # Web/API redirect to different agent yield TransferSessionEvent( agent_id="technical_support_agent", environment="production", data={"conversation_context": "payment_issue"} )

STTUpdateSettingsEvent#

Dynamically updates Speech-to-Text settings during a conversation. See Speech To Text for model-specific configuration options.

class STTUpdateSettingsEvent(Event): def __init__( self, language: str | None = None, # Language code (e.g., "en", "es", "multi") prompt: str | None = None, # Context prompt for accuracy endpointing: int | None = None, # End-of-speech detection sensitivity noise_reduction_type: str | None = None, # Audio processing type model: str | None = None, # STT model to use )

Usage:

# Switch to Spanish yield STTUpdateSettingsEvent(language="es") # Improve transcription with context yield STTUpdateSettingsEvent( prompt="Technical conversation about software development" ) # Optimize for phone audio yield STTUpdateSettingsEvent( noise_reduction_type="telephony", endpointing=2000 ) # Full configuration update yield STTUpdateSettingsEvent( language="es", model="nova-3", prompt="Conversación técnica en español.", endpointing=500, noise_reduction_type="near_field" )

StartRecordingEvent#

Starts recording the current call session.

class StartRecordingEvent(Event): def __init__( self, status_callback_url: str | None = None # Webhook for recording status )

Usage:

# Start recording yield StartRecordingEvent() # Start recording with webhook yield StartRecordingEvent( status_callback_url="https://your-app.com/webhooks/recording" )

StopRecordingEvent#

Stops the current call recording.

class StopRecordingEvent(Event): pass

Usage:

yield StopRecordingEvent()

InputAllowedEvent#

Enables or disables user input.

class InputAllowedEvent(Event): def __init__( self, allowed: bool # True to enable input, False to disable )

When allowed=False, user input is disabled until either InputAllowedEvent(allowed=True) is yielded or the handler completes.

Usage:

# Disable input during processing yield InputAllowedEvent(allowed=False) # ... do some processing ... # Re-enable input yield InputAllowedEvent(allowed=True)

CustomEvent#

Creates a custom event for client-specific functionality.

class CustomEvent(Event): def __init__( self, name: str, # Custom event name data: dict = {} # Custom event data )

Usage:

yield CustomEvent( name="user_action", data={"action": "button_click", "button_id": "submit"} )

ExternalEvent#

Sends an event to another agent session.

class ExternalEvent(Event): def __init__( self, agent_id: str, # Target agent ID session_id: str, # Target session ID name: str, # Event name data: dict # Event data )

Usage:

yield ExternalEvent( agent_id="supervisor_agent", session_id="session_123", name="escalation", data={"reason": "customer_request", "priority": "high"} )

Enums#

TTSProvider#

Supported Text-to-Speech providers for use with TextToSpeechIdentifier.

class TTSProvider(str, Enum): AZURE = "azure" CARTESIA = "cartesia" CUSTOM = "custom" GOOGLE_CHIRP = "google_chirp" MINIMAX = "minimax" OPENAI = "openai" PRIM_VOICES = "prim_voices" QWEN3 = "qwen3"

Types#

TextToSpeechIdentifier#

Voice specification with provider and identifier for direct provider access.

class TextToSpeechIdentifier(TypedDict): provider: TTSProvider # The TTS provider identifier: str # Voice identifier for that provider

Examples:

{"provider": "azure", "identifier": "en-AU-WilliamNeural"} {"provider": "cartesia", "identifier": "6f84f4b8-58a2-430c-8c79-688dad597532"} {"provider": "google_chirp", "identifier": "laomedeia"} {"provider": "openai", "identifier": "nova"} {"provider": "prim_voices", "identifier": "lyric"}
eventsapireference