Skip to content

fix(voice): bound EndCallTool wait for tool-reply playout - #7186

Open
usmamalik345 wants to merge 2 commits into
livekit:mainfrom
usmamalik345:fix/end-call-tool-reply-timeout
Open

fix(voice): bound EndCallTool wait for tool-reply playout#7186
usmamalik345 wants to merge 2 commits into
livekit:mainfrom
usmamalik345:fix/end-call-tool-reply-timeout

Conversation

@usmamalik345

Copy link
Copy Markdown

Summary

  • _delayed_session_shutdown already wraps the wait for speech_created in asyncio.wait_for(..., timeout=5.0), but then does a bare await speech_handle
  • if that handle never completes, finally never runs and ctx.session.shutdown() is skipped — room/delete_room cleanup never happens (SIP can stay up)
  • wrap the speech-handle await in the same TOOL_REPLY_TIMEOUT, keep the existing warning + shutdown path

Closes #5096 (timeout asymmetry only; not Gemini instruction-following).

Testing

  • pytest tests/test_tools.py::test_delayed_session_shutdown_times_out_when_speech_handle_hangs — fails on main (hangs), passes with the fix
  • also covers: speech_created never fires; handle completes normally
  • ruff check / ruff format clean on touched files

Wrap the speech_handle await in TOOL_REPLY_TIMEOUT so a hanging
tool reply still reaches finally and shuts down the session (livekit#5096).

Co-authored-by: Cursor <cursoragent@cursor.com>
@usmamalik345
usmamalik345 requested a review from a team as a code owner September 9, 2026 10:47
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

devin-ai-integration[bot]

This comment was marked as resolved.

On the timeout path, force-interrupt the hanging speech and call
shutdown(drain=False) so close is not blocked waiting for the same
unfinished reply. Successful playout still drains normally.

Co-authored-by: Cursor <cursoragent@cursor.com>
@usmamalik345

Copy link
Copy Markdown
Author

Addressed the Devin review note:

  • timeout path now interrupt(force=True) on the hanging tool-reply handle (when we have one), then shutdown(drain=False) so drain/close is not blocked on that same unfinished speech
  • successful playout still uses default shutdown() (drain=True)
  • tests assert drain=False on both timeout paths and drain=True when the handle completes normally

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gemini Realtime EndCallTool not working

3 participants