fix(voice): prevent activity race during session shutdown - #2125
fix(voice): prevent activity race during session shutdown#2125smorimoto wants to merge 2 commits into
Conversation
🦋 Changeset detectedLatest commit: 6ab681e The changes in this PR will be included in the next version bump. This PR includes changesets to release 39 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 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ae91133f51
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| this.output.transcription = null; | ||
|
|
||
| await this.activity?.close(); | ||
| await activity?.close(); |
There was a problem hiding this comment.
Close an activity resumed during shutdown
When an AgentTask completes while shutdown is awaiting cleanup, agent.ts:761-765 can call _updateActivity(..., { newActivity: 'resume' }); the closing guard at agent_session.ts:1284 blocks only start, so this transition can install and start the resumed activity. This line then closes only the earlier captured activity, and the following assignment clears the reference to the live resumed activity without closing it, allowing model/audio pipelines and background tasks to survive the session's Close event. Shutdown must either prevent resume transitions or also close any replacement activity.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ab681eb9c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (newActivity === 'resume') { | ||
| await this.nextActivity?.close(); |
There was a problem hiding this comment.
Avoid closing the paused activity from its own task
When an AgentTask completes after shutdown has set closing, this resume transition runs from the task that is still registered in the paused activity's speechTasks. Awaiting that activity's close() here makes AgentActivity.close() cancel and wait for the calling task itself; the task cannot finish until _updateActivity() returns, so shutdown stalls for the five-second REPLY_TASK_CANCEL_TIMEOUT (and may exceed the host's shutdown grace period). Defer this close until the caller has unwound, or exclude the current task from the close wait.
Useful? React with 👍 / 👎.
Closes #1871
Problem
AgentSession.closeImplInnerdereferencesthis.activityacross severalawaitboundaries. An in-flight activity transition can clear the session field while shutdown is draining the activity, causing aTypeErroratcurrentSpeech. The remaining cleanup and theCloseevent are then skipped.Solution
Capture the active
AgentActivityonce and use that stable reference for interruption, draining, playout waiting, user-turn commit, input detachment, and final close. This also addresses the review feedback on #1872: the final close no longer reads the mutable session field.A regression test pauses
drain(), clears the session activity, and verifies that shutdown resolves, the captured activity closes, and theCloseevent fires. A patch changeset is included.Verification
pnpm test agents/src/voice/agent_session.test.ts agents/src/voice/agent_session_close_race.test.ts agents/src/voice/agent_session_handoff.test.ts agents/src/voice/agent_activity_close_commit.test.ts(14 tests passed)pnpm --filter @livekit/agents typecheckpnpm build:agentspnpm --filter @livekit/agents throws:checkpnpm -w format:checkThe full
pnpm testrun completed 1,804 tests successfully. Its remaining failures were unrelated environment and integration cases: missing OpenAI and Cerebras API keys, Hugging Face download timeouts, and a Silero VAD fixture failure.