Skip to content

feat(voice): expose SpeechHandle.hold_interruptions context manager - #7201

Open
devtechedge wants to merge 2 commits into
livekit:mainfrom
devtechedge:feat/speech-handle-hold-interruptions
Open

feat(voice): expose SpeechHandle.hold_interruptions context manager#7201
devtechedge wants to merge 2 commits into
livekit:mainfrom
devtechedge:feat/speech-handle-hold-interruptions

Conversation

@devtechedge

Copy link
Copy Markdown

Summary

Fixes #7191.

SpeechHandle._hold_interruptions() / _release_interruptions() already implement counted, restoring per-utterance barge-in protection, but were private. Realtime callers that need one say() (or a group of them) to survive server-side turn detection had no supported API: allow_interruptions=False is scrubbed under realtime, and a bare setter does not compose across overlapping holders.

This exposes a public context manager that wraps the existing hold/release, and demotes the realtime input_speech_started "not interruptable" path from logger.exception to logger.debug, since that path is reachable by design once holds are supported (interrupt(force=True) still cuts through).

Changes

  • livekit-agents/livekit/agents/voice/speech_handle.py: add SpeechHandle.hold_interruptions() context manager
  • livekit-agents/livekit/agents/voice/agent_activity.py: debug-level log when realtime barge-in hits a non-interruptable speech
  • tests/test_speech_handle_hold_interruptions.py: unit coverage for restore, nesting, prior-False preserve, and force=True

Usage

handle = session.say(text)
with handle.hold_interruptions():
    await handle.wait_for_playout()

Test plan

  • uv run --directory livekit-agents pytest ../tests/test_speech_handle_hold_interruptions.py -q (4 passed)

Public counted/restoring hold for per-utterance barge-in protection under
server-side turn detection, and demote the realtime input_speech_started
uninterruptible path from exception to debug now that holds are supported.

Fixes livekit#7191
@devtechedge
devtechedge requested a review from a team as a code owner September 9, 2026 22:26
devin-ai-integration[bot]

This comment was marked as resolved.

Assignments while hold_interruptions is active now update the value
restored on final release; effective interruptibility stays false until
then. force=True still cuts through. Covers True/False during nested holds.
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.

Make SpeechHandle interruption holds public, so one utterance can survive barge-in under server-side turn detection

1 participant