wooden-beard-26644
07/31/2025, 3:11 PMtall-airline-16756
07/31/2025, 3:11 PMtall-airline-16756
07/31/2025, 3:12 PMdelete_room API. This ensures that the call ends properly for all participants and the room is cleaned up from the LiveKit server.
Here is the recommended approach:
1. Wait for any current speech to finish playing out using current_speech.wait_for_playout().
2. Use the delete_room API to delete the room. This ensures that all participants are disconnected and the room is removed from the server.
3. Optionally, provide a farewell message before ending the call.
Here is an example implementation:
from livekit import api, rtc
from livekit.agents import get_job_context
async def hangup_call():
ctx = get_job_context()
if ctx is None:
# Not running in a job context
return
await ctx.api.room.delete_room(
api.DeleteRoomRequest(
room=ctx.room.name,
)
)
For a more integrated approach, you can implement this as a function tool that the agent can call:
@function_tool
async def end_call(self, ctx: RunContext):
"""Called when the user wants to end the call"""
# let the agent finish speaking
current_speech = ctx.session.current_speech
if current_speech:
await current_speech.wait_for_playout()
await hangup_call()
Using the delete_room API is critical because if only the agent session ends without deleting the room, the user will continue to hear silence until they hang up.
Sources: Agents telephony integration | LiveKit Docs | basics/exit_message.pywooden-beard-26644
07/31/2025, 3:13 PMtall-airline-16756
07/31/2025, 3:14 PM@session.on("close")
def on_close(ev: CloseEvent):
print(f"Agent Session closed, reason: {ev.reason}")
• Room Events: When the room is deleted through the server API, a Disconnected room event is sent out, and the room is removed from the server.
• Shutdown Callbacks: Callbacks registered with ctx.add_shutdown_callback usually run when the agent disconnects from the room. That said, it’s a bit unclear whether these callbacks trigger specifically when the agent deletes the room or just when the agent disconnects because the room was deleted.
A handy approach is to explicitly close the session before deleting the room, like this:
await self.session.aclose()
await self.job_context.api.room.delete_room(
api.DeleteRoomRequest(room=self.job_context.room.name)
)
This way, you make sure everything cleans up nicely and your shutdown hooks get called properly. If you want me to dig a bit deeper into how ctx.add_shutdown_callback behaves in this case, just let me know—I’m happy to help get more details for you!
Sources: Events and error handling | LiveKit Docs | livekit-agents/livekit/agents/voice/agent_session.py | Inside a session | LiveKit Docs | main.py | flows/multi_stage_flow.py