fix: preserve adaptive interruption across tool calls - #2290
Merged
Conversation
🦋 Changeset detectedLatest commit: c060966 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 |
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.
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
approved these changes
Aug 21, 2026
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#6564 to preserve adaptive interruption when audible playout pauses for tool execution or resumes during active user speech.
@livekit/agents.Source diff coverage
livekit-agents/livekit/agents/inference/interruption.py->agents/src/inference/interruption/interruption_stream.ts. ExcludesagentEndedoverlaps from backchannel metrics; target event types already carry the marker.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.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 Pythonsend_nowaitordering.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 carryagentEnded. No unsupported wire field is invented.tests/test_agent_session.py->agents/src/voice/agent_activity_tool_output_commit.test.ts. Verifies speech end is observed after entering the tool-callthinkingstate and later ends occur while listening.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.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.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
agentEndedstill 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 withTODO(AGT-3180). Local adaptive interruption behavior and metrics preserve the marker.Validation
pnpm test agents(2120 passed, 5 skipped)pnpm buildpnpm build:agentsafter final refinementpnpm --filter @livekit/agents typecheckpnpm --filter @livekit/agents lintpnpm format:checkcue-clivoice run: post-tool playout was adaptively interrupted,getWeatherexecuted for the replacement turn, and a fresh assistant response was committedSource: 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.