From 195fd437127170d4eb744896cfbd7fee1df16f25 Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Fri, 17 Jan 2025 10:12:46 -0500 Subject: [PATCH] Fix an issue where the UserIdleProcessor was blocking the EndFrame --- examples/foundational/31-user-idle.py | 15 ++++++--------- src/pipecat/processors/user_idle_processor.py | 8 ++++---- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/examples/foundational/31-user-idle.py b/examples/foundational/31-user-idle.py index d9dbc92e7..c8beb4b71 100644 --- a/examples/foundational/31-user-idle.py +++ b/examples/foundational/31-user-idle.py @@ -14,7 +14,7 @@ from loguru import logger from runner import configure from pipecat.audio.vad.silero import SileroVADAnalyzer -from pipecat.frames.frames import EndFrame +from pipecat.frames.frames import EndFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner from pipecat.pipeline.task import PipelineParams, PipelineTask @@ -37,7 +37,7 @@ async def handle_user_idle(processor: UserIdleProcessor, retry_count: int) -> bo messages.append( { "role": "system", - "content": "The user has been quiet for a while. Politely ask if they're still there.", + "content": "The user has been quiet for a while. Politely and concisely ask if they're still there.", } ) await task.queue_frames([context_aggregator.user().get_context_frame()]) @@ -47,20 +47,17 @@ async def handle_user_idle(processor: UserIdleProcessor, retry_count: int) -> bo messages.append( { "role": "system", - "content": "The user is still inactive. Ask if they would like to continue the conversation.", + "content": "The user is still inactive. Concisely ask if they would like to continue the conversation.", } ) await task.queue_frames([context_aggregator.user().get_context_frame()]) return True else: # Third attempt: End the conversation - messages.append( - { - "role": "system", - "content": "The user has been inactive for too long. Politely end the conversation.", - } + await task.queue_frames( + [TTSSpeakFrame("It seems like you're busy right now. Have a nice day!")] ) - await task.queue_frames([context_aggregator.user().get_context_frame()]) + await asyncio.sleep(3) await task.queue_frame(EndFrame()) return False diff --git a/src/pipecat/processors/user_idle_processor.py b/src/pipecat/processors/user_idle_processor.py index 9fc2912c7..db3d32ffc 100644 --- a/src/pipecat/processors/user_idle_processor.py +++ b/src/pipecat/processors/user_idle_processor.py @@ -82,10 +82,10 @@ class UserIdleProcessor(FrameProcessor): await super().process_frame(frame, direction) # Check for end frames before processing - if isinstance(frame, StartFrame): - self._create_idle_task() - elif isinstance(frame, (EndFrame, CancelFrame)): - await self._stop() + if isinstance(frame, (EndFrame, CancelFrame)): + await self.push_frame(frame, direction) # Push the frame down the pipeline + await self._stop() # Then stop the idle task + return # Return early since we're ending await self.push_frame(frame, direction)