From bb00d223c96cb45d31ca2c1264a24bb95fa5407e Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Tue, 13 Jan 2026 14:13:32 -0500 Subject: [PATCH] Update 26a to use context aggregator transcription events --- changelog/3431.changed.md | 1 + .../26a-gemini-live-transcription.py | 37 +++++++++++-------- .../services/google/gemini_live/llm.py | 2 +- 3 files changed, 23 insertions(+), 17 deletions(-) create mode 100644 changelog/3431.changed.md diff --git a/changelog/3431.changed.md b/changelog/3431.changed.md new file mode 100644 index 000000000..0a9164491 --- /dev/null +++ b/changelog/3431.changed.md @@ -0,0 +1 @@ +- Updated `GeminiLiveLLMService` to push `LLMThoughtStartFrame`, `LLMThoughtTextFrame`, and `LLMThoughtEndFrame` when the model returns thought content. diff --git a/examples/foundational/26a-gemini-live-transcription.py b/examples/foundational/26a-gemini-live-transcription.py index 0248ca358..ad91ff2a1 100644 --- a/examples/foundational/26a-gemini-live-transcription.py +++ b/examples/foundational/26a-gemini-live-transcription.py @@ -12,13 +12,16 @@ from loguru import logger from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.audio.vad.vad_analyzer import VADParams -from pipecat.frames.frames import LLMRunFrame, TranscriptionMessage +from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner from pipecat.pipeline.task import PipelineParams, PipelineTask from pipecat.processors.aggregators.llm_context import LLMContext -from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair -from pipecat.processors.transcript_processor import TranscriptProcessor +from pipecat.processors.aggregators.llm_response_universal import ( + AssistantTurnStoppedMessage, + LLMContextAggregatorPair, + UserTurnStoppedMessage, +) from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport from pipecat.services.google.gemini_live.llm import GeminiLiveLLMService @@ -93,17 +96,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ) context_aggregator = LLMContextAggregatorPair(context) - transcript = TranscriptProcessor() + user_aggregator = context_aggregator.user() + assistant_aggregator = context_aggregator.assistant() pipeline = Pipeline( [ transport.input(), - context_aggregator.user(), - transcript.user(), + user_aggregator, llm, transport.output(), - transcript.assistant(), - context_aggregator.assistant(), + assistant_aggregator, ] ) @@ -127,14 +129,17 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info(f"Client disconnected") await task.cancel() - # Register event handler for transcript updates - @transcript.event_handler("on_transcript_update") - async def on_transcript_update(processor, frame): - for msg in frame.messages: - if isinstance(msg, TranscriptionMessage): - timestamp = f"[{msg.timestamp}] " if msg.timestamp else "" - line = f"{timestamp}{msg.role}: {msg.content}" - logger.info(f"Transcript: {line}") + @user_aggregator.event_handler("on_user_turn_stopped") + async def on_user_turn_stopped(aggregator, strategy, message: UserTurnStoppedMessage): + timestamp = f"[{message.timestamp}] " if message.timestamp else "" + line = f"{timestamp}user: {message.content}" + logger.info(f"Transcript: {line}") + + @assistant_aggregator.event_handler("on_assistant_turn_stopped") + async def on_assistant_turn_stopped(aggregator, message: AssistantTurnStoppedMessage): + timestamp = f"[{message.timestamp}] " if message.timestamp else "" + line = f"{timestamp}assistant: {message.content}" + logger.info(f"Transcript: {line}") runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) diff --git a/src/pipecat/services/google/gemini_live/llm.py b/src/pipecat/services/google/gemini_live/llm.py index a00eef34f..13b5fb18c 100644 --- a/src/pipecat/services/google/gemini_live/llm.py +++ b/src/pipecat/services/google/gemini_live/llm.py @@ -1464,7 +1464,7 @@ class GeminiLiveLLMService(LLMService): # so bracket each thought in start/end frames await self.push_frame(LLMThoughtStartFrame()) await self.push_frame(LLMThoughtTextFrame(text)) - await self.push_frame(LLMThoughtEndFrame(signature=part.thought_signature)) + await self.push_frame(LLMThoughtEndFrame()) else: # Regular text response self._bot_text_buffer += text