STTMuteFilter should call frame.complete() when InterruptionFrame is blocked

This commit is contained in:
Aleix Conchillo Flaqué
2026-02-06 09:45:20 -08:00
parent a352b2d7a0
commit d5105a78e6
2 changed files with 35 additions and 0 deletions

View File

@@ -234,6 +234,12 @@ class STTMuteFilter(FrameProcessor):
await self.push_frame(frame, direction)
else:
logger.trace(f"{frame.__class__.__name__} suppressed - STT currently muted")
# When muted, the InterruptionFrame won't propagate further
# and will never reach the pipeline sink. Complete it here so
# push_interruption_task_frame_and_wait() doesn't hang.
if isinstance(frame, InterruptionFrame):
frame.complete()
else:
# Pass all other frames through
await self.push_frame(frame, direction)

View File

@@ -4,6 +4,7 @@
# SPDX-License-Identifier: BSD 2-Clause License
#
import asyncio
import unittest
from pipecat.frames.frames import (
@@ -14,6 +15,7 @@ from pipecat.frames.frames import (
FunctionCallsStartedFrame,
InputAudioRawFrame,
InterimTranscriptionFrame,
InterruptionFrame,
TranscriptionFrame,
UserStartedSpeakingFrame,
UserStoppedSpeakingFrame,
@@ -327,6 +329,33 @@ class TestSTTMuteFilter(unittest.IsolatedAsyncioTestCase):
expected_down_frames=expected_returned_frames,
)
async def test_interruption_frame_completed_when_muted(self):
"""Test that InterruptionFrame.complete() is called when the frame is
suppressed due to muting, so push_interruption_task_frame_and_wait()
doesn't hang."""
filter = STTMuteFilter(config=STTMuteConfig(strategies={STTMuteStrategy.ALWAYS}))
event = asyncio.Event()
frames_to_send = [
BotStartedSpeakingFrame(),
InterruptionFrame(event=event),
BotStoppedSpeakingFrame(),
]
expected_returned_frames = [
BotStartedSpeakingFrame,
BotStoppedSpeakingFrame,
]
await run_test(
filter,
frames_to_send=frames_to_send,
expected_down_frames=expected_returned_frames,
)
self.assertTrue(event.is_set(), "InterruptionFrame.complete() should be called when muted")
if __name__ == "__main__":
unittest.main()