Merge pull request #4147 from pipecat-ai/cb/gemini-transcript-fixes
Fix Gemini Live to handle bundled server_content fields
This commit is contained in:
1
changelog/4147.fixed.md
Normal file
1
changelog/4147.fixed.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
- Fixed Gemini Live message handling to process all `server_content` fields independently. Gemini 3.x can bundle multiple fields (e.g. `model_turn` and `output_transcription`) on the same message, but the previous `elif` chain only processed the first match, silently dropping the rest.
|
||||||
@@ -1371,7 +1371,12 @@ class GeminiLiveLLMService(LLMService):
|
|||||||
# Reset failure counter if connection has been stable
|
# Reset failure counter if connection has been stable
|
||||||
self._check_and_reset_failure_counter()
|
self._check_and_reset_failure_counter()
|
||||||
|
|
||||||
if message.server_content and message.server_content.interrupted:
|
# server_content fields are NOT mutually exclusive —
|
||||||
|
# Gemini 3.x can bundle multiple content fields and
|
||||||
|
# turn_complete on the same message, so process the
|
||||||
|
# content-bearing fields before closing the turn.
|
||||||
|
sc = message.server_content
|
||||||
|
if sc and sc.interrupted:
|
||||||
# NOTE: while the service triggers interruptions in
|
# NOTE: while the service triggers interruptions in
|
||||||
# the specific case of barge-ins, it does *not*
|
# the specific case of barge-ins, it does *not*
|
||||||
# emit UserStarted/StoppedSpeakingFrames, as the
|
# emit UserStarted/StoppedSpeakingFrames, as the
|
||||||
@@ -1384,23 +1389,30 @@ class GeminiLiveLLMService(LLMService):
|
|||||||
# turn strategies.
|
# turn strategies.
|
||||||
logger.debug("Gemini VAD: interrupted signal received")
|
logger.debug("Gemini VAD: interrupted signal received")
|
||||||
await self.broadcast_interruption()
|
await self.broadcast_interruption()
|
||||||
elif message.server_content and message.server_content.model_turn:
|
if sc and sc.model_turn:
|
||||||
await self._handle_msg_model_turn(message)
|
await self._handle_msg_model_turn(message)
|
||||||
elif message.server_content and message.server_content.turn_complete:
|
if sc and sc.input_transcription:
|
||||||
|
await self._handle_msg_input_transcription(message)
|
||||||
|
if sc and sc.output_transcription:
|
||||||
|
await self._handle_msg_output_transcription(message)
|
||||||
|
if (
|
||||||
|
sc
|
||||||
|
and sc.grounding_metadata
|
||||||
|
and not sc.model_turn
|
||||||
|
and not sc.output_transcription
|
||||||
|
):
|
||||||
|
# model_turn/output_transcription already defer
|
||||||
|
# bundled grounding metadata to turn_complete.
|
||||||
|
await self._handle_msg_grounding_metadata(message)
|
||||||
|
if sc and sc.turn_complete:
|
||||||
if not message.usage_metadata:
|
if not message.usage_metadata:
|
||||||
logger.warning("Received turn_complete without usage_metadata")
|
logger.warning("Received turn_complete without usage_metadata")
|
||||||
await self._handle_msg_turn_complete(message)
|
await self._handle_msg_turn_complete(message)
|
||||||
if message.usage_metadata:
|
if message.usage_metadata:
|
||||||
await self._handle_msg_usage_metadata(message)
|
await self._handle_msg_usage_metadata(message)
|
||||||
elif message.server_content and message.server_content.input_transcription:
|
if message.tool_call:
|
||||||
await self._handle_msg_input_transcription(message)
|
|
||||||
elif message.server_content and message.server_content.output_transcription:
|
|
||||||
await self._handle_msg_output_transcription(message)
|
|
||||||
elif message.server_content and message.server_content.grounding_metadata:
|
|
||||||
await self._handle_msg_grounding_metadata(message)
|
|
||||||
elif message.tool_call:
|
|
||||||
await self._handle_msg_tool_call(message)
|
await self._handle_msg_tool_call(message)
|
||||||
elif message.session_resumption_update:
|
if message.session_resumption_update:
|
||||||
self._handle_msg_resumption_update(message)
|
self._handle_msg_resumption_update(message)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if not self._disconnecting:
|
if not self._disconnecting:
|
||||||
|
|||||||
Reference in New Issue
Block a user