better-sandwich-65834
03/09/2026, 10:27 AMtall-airline-16756
03/09/2026, 10:27 AMtall-airline-16756
03/09/2026, 10:28 AMsession.once("speech_created", callback)) to be notified when the next speech is created instead of polling session.current_speech.
2) What is the correct pattern for "play goodbye → if interrupted → let agent respond → then hang up"?
• Return from the tool immediately after initiating the goodbye speech. If the goodbye is interrupted, register a one‑time speech_created listener. When speech_created fires, await the new speech handle’s playout completion using candidate.wait_for_playout() and then run your teardown (e.g., delete_room()). This ensures the SDK can schedule the next response (S2) after the tool returns and you wait for the agent turn to finish before hanging up.
3) Is there a way to await the next agent turn completing, rather than watching current_speech?
• There isn’t a single “wait_for_next_turn” helper, but the pattern above (listen for speech_created → get the new speech handle → await its wait_for_playout()) is the correct way to await the agent’s next turn without polling.
4) Does AgentSession expose any wait_for_next_speech() style API?
• No. AgentSession does not expose a wait_for_next_speech() API. Use the speech_created event and then await the returned speech handle’s wait_for_playout().
Recommended implementation sketch
1. When you play the goodbye speech from inside the tool, return from the tool immediately (do not block waiting for S2).
2. If the goodbye speech was interrupted:
◦ Use session.once("speech_created", callback) to catch the next speech.
◦ In the callback, obtain the new speech handle (the callback should receive it or you can read session.current_speech) and await candidate.wait_for_playout() with a reasonable timeout.
◦ After awaiting the new speech playout completion, run your teardown (delete room etc.).
1. If goodbye was not interrupted, carry out teardown immediately.
Notes and timing tips
• Give a slightly larger window for the next speech to appear (your 1s polling window was tight). The speech_created event removes the need to poll and avoids timing races.
• Use a timeout on wait_for_playout() (e.g., 5–10s) to avoid hanging if the agent’s speech never appears or stalls.
If you’d like, I can:
• Show a short async code snippet using session.once("speech_created", ...) and candidate.wait_for_playout().
• Help adapt this pattern into your existing hangup() / _wait_for_reply_and_teardown() flow.
Which would you prefer?
Sources: Agent speech and audio | LiveKit Documentation | Agent session | LiveKit Documentation | Agents telephony integration | LiveKit Documentation | How to detect when an agent has finished speaking | LiveKit