diff --git a/changelog/4434.fixed.md b/changelog/4434.fixed.md new file mode 100644 index 000000000..28ba766ca --- /dev/null +++ b/changelog/4434.fixed.md @@ -0,0 +1 @@ +- Fixed interruptions being delayed when a slow non-uninterruptible frame was processing and an uninterruptible frame was waiting in the queue. The bot would stall until the slow frame finished instead of cancelling it immediately on interruption. diff --git a/src/pipecat/processors/frame_processor.py b/src/pipecat/processors/frame_processor.py index 0ee22a642..05abfceb4 100644 --- a/src/pipecat/processors/frame_processor.py +++ b/src/pipecat/processors/frame_processor.py @@ -877,14 +877,19 @@ class FrameProcessor(BaseObject): current_is_uninterruptible = isinstance( self.__process_current_frame, UninterruptibleFrame ) - if current_is_uninterruptible or self.__process_queue.has_uninterruptible: - # We don't want to cancel an UninterruptibleFrame (either the - # one currently being processed or one waiting in the queue), - # so we simply cleanup the queue keeping only - # UninterruptibleFrames. + if current_is_uninterruptible: + # The frame currently being processed is uninterruptible, so we + # must not cancel it. Just flush non-uninterruptible frames from + # the queue; any uninterruptible ones will be kept and processed + # after the current frame finishes. self.__reset_process_queue() else: - # Cancel and re-create the process task. + # Cancel and re-create the process task. Previously this branch + # was skipped when the queue contained an uninterruptible frame, + # which caused slow non-uninterruptible frames to block + # interruptions. Uninterruptible queued frames are safe here + # because __create_process_task calls __reset_process_queue + # internally, which always preserves them. await self.__cancel_process_task() self.__create_process_task() except Exception as e: