diff --git a/examples/foundational/07ae-interruptible-hume.py b/examples/foundational/07ae-interruptible-hume.py index e30cfff98..eae9edaa9 100644 --- a/examples/foundational/07ae-interruptible-hume.py +++ b/examples/foundational/07ae-interruptible-hume.py @@ -13,7 +13,8 @@ from pipecat.audio.turn.smart_turn.base_smart_turn import SmartTurnParams from pipecat.audio.turn.smart_turn.local_smart_turn_v3 import LocalSmartTurnAnalyzerV3 from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.audio.vad.vad_analyzer import VADParams -from pipecat.frames.frames import Frame, LLMRunFrame, TTSTextFrame, format_pts +from pipecat.frames.frames import LLMRunFrame, TTSTextFrame +from pipecat.observers.loggers.debug_log_observer import DebugLogObserver, FrameEndpoint from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner from pipecat.pipeline.task import PipelineParams, PipelineTask @@ -21,7 +22,6 @@ from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, ) -from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.processors.frameworks.rtvi import RTVIConfig, RTVIObserver, RTVIProcessor from pipecat.processors.transcript_processor import TranscriptProcessor from pipecat.runner.types import RunnerArguments @@ -29,6 +29,7 @@ from pipecat.runner.utils import create_transport from pipecat.services.deepgram.stt import DeepgramSTTService from pipecat.services.hume.tts import HUME_SAMPLE_RATE, HumeTTSService from pipecat.services.openai.llm import OpenAILLMService +from pipecat.transports.base_output import BaseOutputTransport from pipecat.transports.base_transport import BaseTransport, TransportParams from pipecat.transports.daily.transport import DailyParams from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams @@ -36,24 +37,6 @@ from pipecat.transports.websocket.fastapi import FastAPIWebsocketParams load_dotenv(override=True) -class TimestampLogger(FrameProcessor): - """Frame processor that logs TTSTextFrame objects with their timestamps. - - This helps verify that word timestamps are working correctly by showing - when each word is spoken with its presentation timestamp (PTS). - """ - - async def process_frame(self, frame: Frame, direction: FrameDirection): - await super().process_frame(frame, direction) - - if isinstance(frame, TTSTextFrame): - pts_str = format_pts(frame.pts) if frame.pts else "no PTS" - logger.info(f"🎯 Word timestamp: '{frame.text}' at {pts_str}") - - # Always push all frames through - await self.push_frame(frame, direction) - - # We store functions so objects (e.g. SileroVADAnalyzer) don't get # instantiated. The function will be called when the desired transport gets # selected. @@ -107,9 +90,6 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # Add transcript processor to show timestamps in conversation history transcript = TranscriptProcessor() - # Add timestamp logger to verify word timestamps are being generated - timestamp_logger = TimestampLogger() - pipeline = Pipeline( [ transport.input(), # Transport user input @@ -119,7 +99,6 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context_aggregator.user(), # User responses llm, # LLM tts, # TTS (HumeTTSService with word timestamps) - timestamp_logger, # Log word timestamps for verification transport.output(), # Transport bot output transcript.assistant(), # Assistant transcripts with timestamps context_aggregator.assistant(), # Assistant spoken responses @@ -134,7 +113,14 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): audio_out_sample_rate=HUME_SAMPLE_RATE, ), idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, - observers=[RTVIObserver(rtvi)], + observers=[ + RTVIObserver(rtvi), + DebugLogObserver( + frame_types={ + TTSTextFrame: (BaseOutputTransport, FrameEndpoint.DESTINATION), + } + ), + ], ) @rtvi.event_handler("on_client_ready") @@ -152,7 +138,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") logger.info( - "💡 Word timestamps are enabled! Watch for '🎯 Word timestamp' logs showing each word with its PTS." + "💡 Word timestamps are enabled! Watch the console for TTSTextFrame logs showing each word with its PTS." ) # Kick off the conversation. messages.append({"role": "system", "content": "Please introduce yourself to the user."})