> When a session’s time limit expires, how can ...
# ask-ai
g
When 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 calls
end_session
and then emits text. Instead, I want to:
Send an urgent “wrap up now” signal to the main LLM thread
Let the model complete its final turn normally
Schedule
end_session
so it is invoked only once the model’s last output has finished streaming
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?
t
Thanks for reaching out, Emily. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — you're asking how to signal the main LLM thread to wrap up, let it finish its final reply, and only then end the session (not forcibly cut generation). Below is the correct, minimal pattern to do that. 1) Send an urgent “wrap up” prompt to the agent’s main thread (so the model knows to produce a final concise closing turn). 2) Capture the returned SpeechHandle from the reply call. 3) Await the SpeechHandle’s completion (this waits for TTS synthesis + playback). 4) Call session shutdown/end only after the handle finishes. Example sequence (conceptual Python):
Copy code
# 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