Skip to content

fix(agents): reject late inline tasks during handoff drain - #2488

Open
swayamg20 wants to merge 2 commits into
livekit:mainfrom
swayamg20:fix/2483-handoff-inline-task-deadlock
Open

swayamg20 wants to merge 2 commits into
livekit:mainfrom
swayamg20:fix/2483-handoff-inline-task-deadlock

Conversation

@swayamg20

@swayamg20 swayamg20 commented Sep 12, 2026

Copy link
Copy Markdown

Summary

Fixes #2483.

Handoff holds the session transition lock while draining and closing the outgoing
activity. If an in-flight non-cancellable tool then calls AgentTask.run(), it can
wait for that same lock while activity shutdown waits for the tool to settle.

Reject late inline task admission with ToolError when the owning activity has
blocked new turns or paused scheduling. Check after acquiring the inline-task
slot so a preceding sibling task can finish and resume the parent first. This
covers the handoff's onExit window as well as the later scheduling drain, without
changing the tool cancellation policy or adding a public API.

Each activity also blocks admission at the start of its own drain, before
onExit. This covers queued handoffs whose earlier updateAgent() calls both
blocked the original activity rather than the intermediate activity.

Adds a patch changeset and seven regression cases using real sessions/activities
with a fake LLM: successful sequential completion, late admission during each
handoff window, session shutdown during both windows, and two queued-handoff
cases with and without shutdown. On unmodified main, the sequential control
passes and both original late-admission cases time out. The queued-handoff cases
also time out on the initial PR commit before the drain-side admission fix.
Updates the preemptive-generation regression to assert that drain prevents new
work during onExit, while retaining coverage for cancelling already-parked replies.

Validation

  • Core tests: 2,618 passed, 5 skipped across 158 files
    (vitest run agents/src --maxWorkers=2 --silent).
  • Focused task, shutdown, agent, and preemptive-generation suites: 57 passed,
    including a separate run on Node 22.22.3.
  • Full monorepo build: all 40 packages pass.
  • Core TypeScript typecheck, Throws checks, Prettier, changeset status, and diff
    checks pass.
  • Targeted ESLint: no errors; six existing no-explicit-any warnings on unchanged
    lines of agent_activity.ts.

No live provider/audio integration tests were run.

Reject inline task admission on an outgoing activity before it can wait for the session transition lock held by handoff. Preserve normal sibling task pause/resume and non-cancellable tool behavior.

Add five regression cases covering sequential completion, both handoff windows, and concurrent shutdown, plus an agents patch changeset.

Fixes livekit#2483
@swayamg20
swayamg20 requested a review from a team as a code owner September 12, 2026 23:07
@changeset-bot

changeset-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c2419ee

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

This PR includes changesets to release 39 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-anthropic Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-azure 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-did Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-krisp Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-meta 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-protoface 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

devin-ai-integration[bot]

This comment was marked as resolved.

Make every draining activity block new turns before onExit, including intermediate activities that were not current when updateAgent calls were queued.

Add queued handoff and shutdown regressions, and verify that drain prevents new preemptive generation while preserving parked-reply cancellation coverage.
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.

Handoff drain deadlocks with an in-flight non-cancellable tool that subsequently calls AgentTask.run()

1 participant