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
1import asyncio23from livekit.agents import (4Agent,5AgentServer,6AgentSession,7JobContext,8UserStateChangedEvent,9cli,10)11from livekit.plugins import openai, deepgram, cartesia, silero1213server = AgentServer()1415@server.rtc_session(agent_name="my-agent")16async def entrypoint(ctx: JobContext):17session = AgentSession(18vad=silero.VAD.load(),19llm=openai.LLM(model="gpt-4o-mini"),20stt=deepgram.STT(),21tts=cartesia.TTS(),22user_away_timeout=10.0, # seconds before user is marked "away"23)2425greeting_attempts = 026max_attempts = 327inactivity_task: asyncio.Task | None = None2829async def handle_inactivity():30nonlocal greeting_attempts31greeting_attempts += 13233if greeting_attempts < max_attempts:34await session.generate_reply(35instructions="The user hasn't responded. Repeat your greeting and ask if they're there."36)37else:38await session.generate_reply(39instructions="Say that you haven't received a response and will end the call now."40)41await asyncio.sleep(2) # Let the message play42session.shutdown()4344@session.on("user_state_changed")45def _user_state_changed(ev: UserStateChangedEvent):46nonlocal inactivity_task, greeting_attempts47if ev.new_state == "away":48inactivity_task = asyncio.create_task(handle_inactivity())49return5051# User responded - cancel inactivity handling and reset counter52if inactivity_task is not None:53inactivity_task.cancel()54inactivity_task = None55greeting_attempts = 05657await session.start(58agent=Agent(instructions="You are a friendly assistant. Greet the user warmly."),59room=ctx.room60)6162# Initial greeting63await session.generate_reply(64instructions="Greet the user and ask how you can help them today."65)6667if __name__ == "__main__":68cli.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:
1session = AgentSession(2# ... other config ...3user_away_timeout=10.0, # seconds before user is marked "away"4)
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