PipelineTask: don't add RTVIObserver if already there
This commit is contained in:
1
changelog/3610.fixed.md
Normal file
1
changelog/3610.fixed.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
- Fixed `PipelineTask` adding duplicate `RTVIProcessor` and `RTVIObserver` when they were already provided in the pipeline or observers list. They are now detected and skipped, with appropriate warnings and errors logged for mismatched configurations.
|
||||||
@@ -49,7 +49,7 @@ from pipecat.pipeline.pipeline import Pipeline, PipelineSink, PipelineSource
|
|||||||
from pipecat.pipeline.task_observer import TaskObserver
|
from pipecat.pipeline.task_observer import TaskObserver
|
||||||
from pipecat.processors.aggregators.llm_response import LLMUserContextAggregator
|
from pipecat.processors.aggregators.llm_response import LLMUserContextAggregator
|
||||||
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor, FrameProcessorSetup
|
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor, FrameProcessorSetup
|
||||||
from pipecat.processors.frameworks.rtvi import RTVIObserverParams, RTVIProcessor
|
from pipecat.processors.frameworks.rtvi import RTVIObserver, RTVIObserverParams, RTVIProcessor
|
||||||
from pipecat.utils.asyncio.task_manager import BaseTaskManager, TaskManager, TaskManagerParams
|
from pipecat.utils.asyncio.task_manager import BaseTaskManager, TaskManager, TaskManagerParams
|
||||||
from pipecat.utils.tracing.setup import is_tracing_available
|
from pipecat.utils.tracing.setup import is_tracing_available
|
||||||
from pipecat.utils.tracing.turn_trace_observer import TurnTraceObserver
|
from pipecat.utils.tracing.turn_trace_observer import TurnTraceObserver
|
||||||
@@ -315,14 +315,33 @@ class PipelineTask(BasePipelineTask):
|
|||||||
|
|
||||||
# RTVI support
|
# RTVI support
|
||||||
self._rtvi = None
|
self._rtvi = None
|
||||||
if enable_rtvi:
|
external_rtvi = self._find_processor(pipeline, RTVIProcessor)
|
||||||
|
external_observer_found = any(isinstance(o, RTVIObserver) for o in observers)
|
||||||
|
|
||||||
|
if external_rtvi and not external_observer_found:
|
||||||
|
logger.error(
|
||||||
|
f"{self}: RTVIProcessor found in pipeline but no RTVIObserver in observers. "
|
||||||
|
"Make sure to add both."
|
||||||
|
)
|
||||||
|
elif not external_rtvi and external_observer_found:
|
||||||
|
logger.error(
|
||||||
|
f"{self}: RTVIObserver found in observers but no RTVIProcessor in pipeline. "
|
||||||
|
"Make sure to add both."
|
||||||
|
)
|
||||||
|
elif external_rtvi and external_observer_found:
|
||||||
|
logger.warning(
|
||||||
|
f"{self}: RTVIProcessor and RTVIObserver found, skipping default ones. "
|
||||||
|
"They are both added by default, no need to add them yourself."
|
||||||
|
)
|
||||||
|
elif enable_rtvi:
|
||||||
self._rtvi = rtvi_processor or RTVIProcessor()
|
self._rtvi = rtvi_processor or RTVIProcessor()
|
||||||
observers.append(self._rtvi.create_rtvi_observer(params=rtvi_observer_params))
|
|
||||||
|
|
||||||
@self.rtvi.event_handler("on_client_ready")
|
@self.rtvi.event_handler("on_client_ready")
|
||||||
async def on_client_ready(rtvi: RTVIProcessor):
|
async def on_client_ready(rtvi: RTVIProcessor):
|
||||||
await rtvi.set_bot_ready()
|
await rtvi.set_bot_ready()
|
||||||
|
|
||||||
|
observers.append(self._rtvi.create_rtvi_observer(params=rtvi_observer_params))
|
||||||
|
|
||||||
# This is the idle event. When selected frames are pushed from any
|
# This is the idle event. When selected frames are pushed from any
|
||||||
# processor we consider the pipeline is not idle. We use an observer
|
# processor we consider the pipeline is not idle. We use an observer
|
||||||
# which will be listening any part of the pipeline.
|
# which will be listening any part of the pipeline.
|
||||||
@@ -1012,7 +1031,7 @@ class PipelineTask(BasePipelineTask):
|
|||||||
start_metadata = {}
|
start_metadata = {}
|
||||||
|
|
||||||
# NOTE(aleix): Remove when OpenAILLMContext/LLMUserContextAggregator is removed.
|
# NOTE(aleix): Remove when OpenAILLMContext/LLMUserContextAggregator is removed.
|
||||||
if self._find_deprecated_openaillmcontext(self._pipeline):
|
if self._find_processor(self._pipeline, LLMUserContextAggregator):
|
||||||
start_metadata["deprecated_openaillmcontext"] = True
|
start_metadata["deprecated_openaillmcontext"] = True
|
||||||
|
|
||||||
# Update with user provided metadata.
|
# Update with user provided metadata.
|
||||||
@@ -1020,12 +1039,15 @@ class PipelineTask(BasePipelineTask):
|
|||||||
|
|
||||||
return start_metadata
|
return start_metadata
|
||||||
|
|
||||||
def _find_deprecated_openaillmcontext(self, processor: FrameProcessor) -> bool:
|
def _find_processor(
|
||||||
"""Check whether there is a deprecated LLMUserContextAggregator in the pipeline."""
|
self, processor: FrameProcessor, processor_type: Type[FrameProcessor]
|
||||||
if isinstance(processor, LLMUserContextAggregator):
|
) -> Optional[FrameProcessor]:
|
||||||
return True
|
"""Recursively find a processor of the given type in the pipeline."""
|
||||||
|
if isinstance(processor, processor_type):
|
||||||
|
return processor
|
||||||
|
|
||||||
for p in processor.processors:
|
for p in processor.processors:
|
||||||
if self._find_deprecated_openaillmcontext(p):
|
found = self._find_processor(p, processor_type)
|
||||||
return True
|
if found:
|
||||||
return False
|
return found
|
||||||
|
return None
|
||||||
|
|||||||
Reference in New Issue
Block a user