gray-finland-12154
12/28/2025, 10:35 PMWhen a session’s time limit expires, how can I signal the main LLM thread to gracefully wrap up—allowing it to finish its final response—and then end the session after the last utterance is fully delivered?
Specifically, I want to avoid the default pattern where the model immediately callsand then emits text. Instead, I want to:end_session
Send an urgent “wrap up now” signal to the main LLM thread
Let the model complete its final turn normally
Scheduleso it is invoked only once the model’s last output has finished streamingend_session
I don’t want to forcibly terminate the session mid-generation. What’s the correct way to detect completion of the model’s final turn and trigger a deferred session end?
tall-airline-16756
12/28/2025, 10:36 PMtall-airline-16756
12/28/2025, 10:36 PM# 1) request final wrap-up
handle = await session.generate_reply(instructions="Please provide a concise closing statement and sign off — time is up.")
# 2) wait until the model's final output has finished streaming/playing
await handle.wait_for_playout()
# 3) end the session after playback completes
await session.shutdown(drain=False)
Key points
• Use the SpeechHandle returned by generate_reply() or say().
• wait_for_playout() is the synchronization point that guarantees the LLM's final utterance (and audio) is fully delivered.
• Call shutdown() (or end_session) only after wait_for_playout() completes. Setting drain=False is appropriate because you've already waited for the last output.
If you want, tell me which SDK/language you’re using (or whether you need handling for text-only responses or streaming clients), and I’ll provide a concrete snippet for that environment.
Sources: Agent speech and audio | LiveKit docs | Uninterruptable Agent | LiveKit docs | Job lifecycle | LiveKit docs