Skip to content

fix: preserve adaptive interruption across tool calls - #2290

Merged
chenghao-mou merged 6 commits into
mainfrom
gals-aseptic-hanks
Aug 21, 2026
Merged

fix: preserve adaptive interruption across tool calls#2290
chenghao-mou merged 6 commits into
mainfrom
gals-aseptic-hanks

Conversation

@rosetta-livekit-bot

@rosetta-livekit-bot rosetta-livekit-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Ports livekit/agents#6564 to preserve adaptive interruption when audible playout pauses for tool execution or resumes during active user speech.

  • Treat playout pauses and tool-call thinking gaps as real speech boundaries.
  • Close inconclusive overlaps before resetting the detector and exclude them from backchannel metrics.
  • Restart and serialize overlap inference boundaries when paused playout resumes.
  • Add a patch changeset for @livekit/agents.
Source diff coverage
  • Adapted: livekit-agents/livekit/agents/inference/interruption.py -> agents/src/inference/interruption/interruption_stream.ts. Excludes agentEnded overlaps from backchannel metrics; target event types already carry the marker.
  • Adapted: livekit-agents/livekit/agents/voice/agent_activity.py -> agents/src/voice/agent_activity.ts. Removes pause/resume lifecycle exceptions, ends active speech at tool-call thinking gaps, rearms interruption handling, and removes duplicate pause-cancel teardown. The equivalent target realtime tool path is updated because JS separates pipeline and realtime execution.
  • Adapted: livekit-agents/livekit/agents/voice/audio_recognition.py -> agents/src/voice/audio_recognition.ts. Closes overlap before detector reset, restarts inference when playout resumes over active user speech, preserves endpointing state, and serializes JS async sentinel batches to match Python send_nowait ordering.
  • Adapted: livekit-agents/livekit/agents/voice/remote_session.py -> agents/src/voice/remote_session.ts. Mirrors the source TODO because the remote-session protobuf cannot yet carry agentEnded. No unsupported wire field is invented.
  • Adapted: tests/test_agent_session.py -> agents/src/voice/agent_activity_tool_output_commit.test.ts. Verifies speech end is observed after entering the tool-call thinking state and later ends occur while listening.
  • Adapted: tests/test_false_interruption_resume.py -> agents/src/voice/agent_activity.test.ts. Verifies cancelling already-paused speech does not report a duplicate speech end.
  • Adapted in part: tests/test_interruption/test_overlapping_speech_event.py -> agents/src/inference/interruption/interruption_stream.test.ts. Ports the added agent-ended metric assertion. The existing Python/Pydantic serialization assertion is not applicable to a compile-time TypeScript interface.
  • Adapted: tests/test_realtime_adaptive_interruption.py -> agents/src/voice/realtime_adaptive_interruption.test.ts. Ports overlap-before-reset ordering, idempotent user end, resumed detector restart, and real speech-end assertions.

Protocol gap

agentEnded still cannot be forwarded by remote sessions because the shared AgentSessionEvent protobuf has no field for it. This matches the authoritative source PR, which documents the same limitation with TODO(AGT-3180). Local adaptive interruption behavior and metrics preserve the marker.

Validation

  • pnpm test agents (2120 passed, 5 skipped)
  • pnpm build
  • pnpm build:agents after final refinement
  • pnpm --filter @livekit/agents typecheck
  • pnpm --filter @livekit/agents lint
  • pnpm format:check
  • cue-cli voice run: post-tool playout was adaptively interrupted, getWeather executed for the replacement turn, and a fresh assistant response was committed

Source: livekit/agents#6564


Ported from livekit/agents#6564

Original PR description

Bug: Adaptive interruption could silently drop a user overlap when agent playout resumed after a tool call because the interruption stream received mismatched speech boundaries.

Treat thinking gaps as real speech boundaries and restart overlap inference when playout resumes mid-utterance. Agent-ended overlaps remain inconclusive and no longer count as backchannels; remote forwarding is noted until the protocol carries that marker.

Fixes livekit/agents#6548. Fixes livekit/agents#6548.

@rosetta-livekit-bot
rosetta-livekit-bot Bot requested a review from a team as a code owner August 14, 2026 13:12
@changeset-bot

changeset-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c060966

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-hedra 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-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.

@chenghao-mou chenghao-mou self-assigned this Aug 21, 2026
Do not reopen a resolved overlap when pausing agent audio. End the audible speech interval before waiting for a realtime tool so user speech during the tool gap is not classified as overlap.
devin-ai-integration[bot]

This comment was marked as resolved.

An adaptive-interruption verdict can arrive after the pause path already ended audible speech. Preserve the non-pause fallback without resetting the interruption detector twice.
Realtime replies can stop audible speech before either a tool gap or a no-tool completion. Restore audio-activity interruption at that boundary. When speech resumes over an active user utterance, preserve endpointing overlap state and clear prior overlap verdicts.
Resumed agent playout now carries the active utterance duration and emits one overlap boundary when a realtime speech-start event follows.
The detector resets its audio buffer when agent speech resumes, so elapsed duration cannot restore pre-resume audio. Keep the zero-duration boundary and reject only duplicate opens.
@chenghao-mou
chenghao-mou merged commit d5ee95f into main Aug 21, 2026
6 checks passed
@chenghao-mou
chenghao-mou deleted the gals-aseptic-hanks branch August 21, 2026 16:29
@github-actions github-actions Bot mentioned this pull request Aug 21, 2026
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.

Adaptive interruption: a second agent speech segment (e.g. after a tool call) disarms an open overlap and silently swallows the interruption

1 participant