Skip to content

fix(voice): avoid AgentTask close deadlock#1776

Open
rosetta-livekit-bot[bot] wants to merge 1 commit into
1.5.0from
prickled-ghettoes-tacos
Open

fix(voice): avoid AgentTask close deadlock#1776
rosetta-livekit-bot[bot] wants to merge 1 commit into
1.5.0from
prickled-ghettoes-tacos

Conversation

@rosetta-livekit-bot

@rosetta-livekit-bot rosetta-livekit-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Ports livekit/agents#6071 to agents-js.\n\nChanges:\n- register AgentTask handoff-blocked tasks before awaiting the activity transition\n- keep drain-blocked tasks accumulated across concurrent pause/drain paths\n- skip starting a new activity once the session is closing\n- avoid handoff back when the AgentTask activity never started during close\n\nVerification:\n- pnpm test -- agents/src/voice/agent_session_handoff.test.ts agents/src/voice/agent.test.ts agents/src/voice/agent_activity_handoff.test.ts\n- pnpm build:agents


Ported from livekit/agents#6071

Original PR description

Fixes a deadlock where the session never closes when a participant disconnects while on_enter (or a function tool) is about to await AgentTask()AgentSession.aclose() then times out after 60s. Reported in https://community.livekit.io/t/solved-session-never-closes-when-participant-disconnects-before-agenttask/1411.

Root cause

aclose() drains the current activity while holding the activity lock and waits for all speech tasks, including the on_enter task. Meanwhile the AgentTask handoff calls pause() on the same activity, which blocks on that lock — a circular wait: drain → scheduling task → on_enter → drain's lock. The existing blocked_tasks mechanism was designed to break exactly this edge, but it was only threaded as an argument through pause(), so a drain initiated by the session close never knew about the blocked tasks.

Fix

  • AgentTask.__await_impl now registers the handoff-blocked tasks on the old activity (_add_drain_blocked_tasks, before any await), so any drain — including one initiated by the session close — excludes them from its wait. _drain_blocked_tasks is now a set; _pause_scheduling_task merges into it instead of overwriting, and it's cleared on resume.
  • _update_activity bails out early when the session is closing instead of pausing the previous activity for a handoff that will be skipped anyway.
  • AgentTask.__await_impl skips the parent handoff in its finally when the activity never started due to the close, instead of resuming the parent activity mid-close.
  • pause() returns early on an already-closed activity.

The AgentTask now completes with the existing ToolError("activity doesn't start ...") and the session closes promptly. Added a regression test that deterministically reproduces the race (it deadlocks without the fix).

@changeset-bot

changeset-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: db8d164

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 34 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-cerebras Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hedra Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-mistralai Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-perplexity Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-runway Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugin-soniox Patch
@livekit/agents-plugin-tavus Patch
@livekit/agents-plugins-test Patch
@livekit/agents-plugin-trugen Patch
@livekit/agents-plugin-xai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@rosetta-livekit-bot rosetta-livekit-bot Bot requested a review from longcw June 12, 2026 04:36

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

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.

0 participants