fix(voice): avoid AgentTask close deadlock#1776
Open
rosetta-livekit-bot[bot] wants to merge 1 commit into
Open
fix(voice): avoid AgentTask close deadlock#1776rosetta-livekit-bot[bot] wants to merge 1 commit into
rosetta-livekit-bot[bot] wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: db8d164 The changes in this PR will be included in the next version bump. This PR includes changesets to release 34 packages
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 toawait 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 theon_entertask. Meanwhile theAgentTaskhandoff callspause()on the same activity, which blocks on that lock — a circular wait: drain → scheduling task → on_enter → drain's lock. The existingblocked_tasksmechanism was designed to break exactly this edge, but it was only threaded as an argument throughpause(), so a drain initiated by the session close never knew about the blocked tasks.Fix
AgentTask.__await_implnow 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_tasksis now a set;_pause_scheduling_taskmerges into it instead of overwriting, and it's cleared on resume._update_activitybails out early when the session is closing instead of pausing the previous activity for a handoff that will be skipped anyway.AgentTask.__await_implskips the parent handoff in itsfinallywhen 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
AgentTasknow completes with the existingToolError("activity doesn't start ...")and the session closes promptly. Added a regression test that deterministically reproduces the race (it deadlocks without the fix).