How to implement call greeting retries in voice agents
Learn how to create a voice agent that repeats a greeting when there's no response, and gracefully ends the call after multiple attempts using the away state.
Last Updated:
This guide demonstrates how to create a voice agent that repeats a greeting when there's no response, and gracefully ends the call after multiple attempts.
Implementation Steps
You can implement a call greeting retry mechanism using the away state, which is triggered when both the agent and user are silent for a specified timeout period. Here's how to set it up:
1. Create a counter to track greeting attempts
Initialize a counter variable to keep track of how many greeting attempts have been made.
2. Set up the initial greeting
Implement the initial greeting in the on_start method, which is called when the agent session begins.
3. Implement retry logic using the away state
Use the on_away callback to detect when both the agent and user have been silent for a period of time, and repeat the greeting if the maximum number of attempts hasn't been reached.
4. Add call termination after maximum retries
After reaching the maximum number of retry attempts, gracefully end the call with a final message.
Code Example
import asyncio
from livekit.agents import ( Agent, AgentServer, AgentSession, JobContext, UserStateChangedEvent, cli,)from livekit.plugins import openai, deepgram, cartesia, silero
server = AgentServer()
@server.rtc_session()async def entrypoint(ctx: JobContext): session = AgentSession( vad=silero.VAD.load(), llm=openai.LLM(model="gpt-4o-mini"), stt=deepgram.STT(), tts=cartesia.TTS(), user_away_timeout=10.0, # seconds before user is marked "away" )
greeting_attempts = 0 max_attempts = 3 inactivity_task: asyncio.Task | None = None
async def handle_inactivity(): nonlocal greeting_attempts greeting_attempts += 1 if greeting_attempts < max_attempts: await session.generate_reply( instructions="The user hasn't responded. Repeat your greeting and ask if they're there." ) else: await session.generate_reply( instructions="Say that you haven't received a response and will end the call now." ) await asyncio.sleep(2) # Let the message play session.shutdown()
@session.on("user_state_changed") def _user_state_changed(ev: UserStateChangedEvent): nonlocal inactivity_task, greeting_attempts if ev.new_state == "away": inactivity_task = asyncio.create_task(handle_inactivity()) return
# User responded - cancel inactivity handling and reset counter if inactivity_task is not None: inactivity_task.cancel() inactivity_task = None greeting_attempts = 0
await session.start( agent=Agent(instructions="You are a friendly assistant. Greet the user warmly."), room=ctx.room )
# Initial greeting await session.generate_reply( instructions="Greet the user and ask how you can help them today." )
if __name__ == "__main__": cli.run_app(server)
How It Works
This implementation will:
- Start the call with the greeting message – The initial greeting is generated using
session.generate_reply()after the session starts - Track the number of attempts made – The
greeting_attemptscounter increments with each retry - Repeat the greeting when no response is detected – The
user_state_changedevent fires withnew_state == "away"when the user has been silent for the configured timeout - End the call after 3 unsuccessful attempts – After reaching
max_attempts, the call is terminated gracefully usingsession.shutdown() - Reset on user response – If the user speaks at any point, the retry counter resets to zero
Configuration
The away state is automatically triggered after a period of silence from both the agent and user. Configure the timeout duration using the user_away_timeout parameter when creating your AgentSession:
session = AgentSession( # ... other config ... user_away_timeout=10.0, # seconds before user is marked "away")
Additional Resources
For more examples and advanced implementations, you can refer to our voice agents examples repository.
Read related documentation
- LiveKit Agents overview - Get started with voice AI agents
- Agent session lifecycle - Manage state across sessions
- Voice pipeline overview - Configure your voice AI pipeline
Find more Agents guides
- How to detect when an agent has finished speaking - Track playback completion events
- Building multi-agent architectures - Best practices for multi-agent systems