better-crayon-37219
12/26/2025, 6:06 PMtall-airline-16756
12/26/2025, 6:06 PMtall-airline-16756
12/26/2025, 6:06 PMon_exit causes the agent process to be disconnected/terminated before shutdown hooks run.
What’s happening
• Calling delete_room from on_exit forces an immediate room-wide disconnect.
• That terminates the agent session out-of-band, so the framework hits the process timeout and kills the job (~10s), preventing registered shutdown callbacks from executing (so your transcript publish never runs).
What to change (two safe options)
• Preferred: Move transcript publish and room deletion into a shutdown callback so they run after session shutdown.
a. Register a shutdown hook with ctx.add_shutdown_callback() that publishes the transcript first, then calls ctx.api.room.delete_room(...).
b. In on_participant_disconnected, call self.session.shutdown(drain=True) but do NOT call delete_room.
• Alternative: Use automatic cleanup by enabling delete_room_on_close=True when starting the session (Python only). That deletes the room after the session fully closes and preserves shutdown hook execution.
Quick example (shutdown hook approach)
async def shutdown_hook():
await publish_transcript(...)
await ctx.api.room.delete_room(api.DeleteRoomRequest(room=ctx.room.name))
ctx.add_shutdown_callback(shutdown_hook)
# on participant disconnect:
await self.session.shutdown(drain=True) # do not delete room here
If you'd like, share the exact hooks/code snippets for on_exit, the shutdown registration, and where you call delete_room and I’ll point out the minimal edits to apply.
Sources: Job lifecycle | LiveKit docs | Agent session | LiveKit docsbetter-crayon-37219
12/26/2025, 6:24 PMtall-airline-16756
12/26/2025, 6:24 PMself.session.shutdown(drain=True) can take tens of seconds before shutdown callbacks run, leaving the room open and the user alone. That’s frustrating; here’s how to fix it.
Why it delays
• drain=True waits for the agent to finish any queued audio (TTS or playing responses). If the agent is mid-response or has long queued speech, shutdown waits for that to finish, which can take many seconds. Shutdown callbacks don’t run until the drain completes.
Options to make shutdown prompt and avoid leaving the user alone
• Immediate shutdown: call self.session.shutdown(drain=False) (or await session.aclose()) to close the session right away and let shutdown callbacks run immediately. Use this if you don’t need to finish playing remaining audio.
• Shorten drain time: keep agent responses short so draining finishes faster.
• Always delete the room after session ends in a shutdown callback so the user isn’t left alone:
async def shutdown_hook():
await publish_transcript(...)
await ctx.api.room.delete_room(api.DeleteRoomRequest(room=ctx.room.name))
ctx.add_shutdown_callback(shutdown_hook)
• Or use delete_room_on_close=True when starting the session (Python only) so the room is removed after the session fully closes.
Questions to help me give exact edits
• Do you need the agent’s remaining audio to play out, or is immediate stop acceptable?
• Are you using Python and can enable delete_room_on_close, or do you prefer explicit delete_room in a shutdown hook?
Tell me which option you prefer and I’ll give the minimal code changes to implement it.
Sources: Job lifecycle | LiveKit docsbetter-crayon-37219
12/26/2025, 6:36 PMtall-airline-16756
12/26/2025, 6:36 PMself.session.shutdown() on participant disconnect, on_exit runs immediately, but your shutdown callback only fires 30+ seconds later and you want it to run right away. Here are concise, actionable options and one quick question.
Why this happens
• shutdown() starts a graceful shutdown that waits for pending media/speech/drain and internal cleanup; shutdown callbacks run only after that completes, which can take tens of seconds.
Options to make the shutdown callback run immediately
• Immediate async close (recommended if you don't need to finish playing audio):
await self.session.aclose()
This forces the session to close synchronously so shutdown callbacks run right away.
• Use shutdown without draining (may still have small delay):
self.session.shutdown(drain=False)
This stops draining but can still incur connection-cleanup delay.
• Put time-sensitive logic in on_exit (runs immediately on session exit):
class MyAgent(Agent):
async def on_exit(self):
# urgent tasks here
• Combine approaches: run the urgent steps (e.g., delete room) directly on participant disconnect or in on_exit, and reserve longer work (publish transcript) for shutdown callbacks.
Quick question
• Do you need any remaining agent audio to finish playing for the user? If no, use await self.session.aclose() and I’ll show the minimal code change. If yes, we’ll need a different approach (e.g., move only urgent cleanup to on_exit). Sources: Job lifecycle | LiveKit docs | Server lifecycle | LiveKit docs | Agent speech and audio | LiveKit docs