From 15bc1dd999020960f6c7ba714f9da43b6259d4bb Mon Sep 17 00:00:00 2001 From: Mark Backman Date: Tue, 13 Jan 2026 14:13:00 -0500 Subject: [PATCH] Update GeminiLiveLLMService to push Thought frames when thought content is returned --- .../services/google/gemini_live/llm.py | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/pipecat/services/google/gemini_live/llm.py b/src/pipecat/services/google/gemini_live/llm.py index 4b0be986d..a00eef34f 100644 --- a/src/pipecat/services/google/gemini_live/llm.py +++ b/src/pipecat/services/google/gemini_live/llm.py @@ -44,6 +44,9 @@ from pipecat.frames.frames import ( LLMMessagesAppendFrame, LLMSetToolsFrame, LLMTextFrame, + LLMThoughtEndFrame, + LLMThoughtStartFrame, + LLMThoughtTextFrame, LLMUpdateSettingsFrame, StartFrame, TranscriptionFrame, @@ -1455,10 +1458,19 @@ class GeminiLiveLLMService(LLMService): await self._set_bot_is_responding(True) await self.push_frame(LLMFullResponseStartFrame()) - self._bot_text_buffer += text - self._search_result_buffer += text # Also accumulate for grounding - frame = LLMTextFrame(text=text) - await self.push_frame(frame) + # Check if this is a thought + if part.thought: + # Gemini Live emits fully-formed thoughts rather than chunks, + # 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)) + else: + # Regular text response + self._bot_text_buffer += text + self._search_result_buffer += text # Also accumulate for grounding + frame = LLMTextFrame(text=text) + await self.push_frame(frame) # Check for grounding metadata in server content if msg.server_content and msg.server_content.grounding_metadata: