From a388ff927c5d92573df446baf6793e96bfefcd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Sun, 14 Dec 2025 12:29:25 -0800 Subject: [PATCH] LLMUserAggregator: broadcast user started/stopped speaking frames --- .../processors/aggregators/llm_response_universal.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pipecat/processors/aggregators/llm_response_universal.py b/src/pipecat/processors/aggregators/llm_response_universal.py index 241b5dbac..145dec0ec 100644 --- a/src/pipecat/processors/aggregators/llm_response_universal.py +++ b/src/pipecat/processors/aggregators/llm_response_universal.py @@ -402,8 +402,9 @@ class LLMUserAggregator(LLMContextAggregator): if self._params.enable_user_speaking_frames: logger.debug(f"User started speaking (user turn start strategy: {strategy})") - await self.push_frame(UserStartedSpeakingFrame()) - await self.push_frame(InterruptionFrame()) + # TODO(aleix): These frames should really come from the top of the pipeline. + await self.broadcast_frame(UserStartedSpeakingFrame, emulated=strategy is None) + await self.broadcast_frame(InterruptionFrame) async def _trigger_bot_turn_start(self, strategy: BaseBotTurnStartStrategy): if not self._user_speaking: @@ -418,7 +419,8 @@ class LLMUserAggregator(LLMContextAggregator): if self._params.enable_user_speaking_frames: logger.debug(f"User stopped speaking (bot turn start strategy: {strategy})") - await self.push_frame(UserStoppedSpeakingFrame()) + # TODO(aleix): This frame should really come from the top of the pipeline. + await self.broadcast_frame(UserStoppedSpeakingFrame, emulated=strategy is None) # Always push context frame. await self.push_aggregation()