Gemini Live: fix potential EndFrame-deferral hang by handling turn_complete without usage_metadata

We observed a case where a deferred EndFrame was never released in
Gemini Live, causing the pipeline to hang indefinitely. The EndFrame
deferral mechanism waits for _handle_msg_turn_complete to set
_bot_is_responding back to False, but turn_complete messages were only
processed if they also contained usage_metadata. If Gemini ever sent
turn_complete without usage_metadata, the message would be silently
dropped and the deferred EndFrame would never be released.

Now turn_complete is always handled regardless of usage_metadata
presence, with usage_metadata processing only when available.

Note: we have not actually observed a turn_complete without
usage_metadata in practice, so this is a theoretical fix for the
EndFrame-deferral hang. The actual root cause of the observed hang
may lie elsewhere.
This commit is contained in:
Paul Kompfner
2026-03-24 12:32:14 -04:00
parent cf083b8411
commit 7e42998e9e

View File

@@ -1334,13 +1334,12 @@ class GeminiLiveLLMService(LLMService):
await self.broadcast_interruption()
elif message.server_content and message.server_content.model_turn:
await self._handle_msg_model_turn(message)
elif (
message.server_content
and message.server_content.turn_complete
and message.usage_metadata
):
elif message.server_content and message.server_content.turn_complete:
if not message.usage_metadata:
logger.warning("Received turn_complete without usage_metadata")
await self._handle_msg_turn_complete(message)
await self._handle_msg_usage_metadata(message)
if message.usage_metadata:
await self._handle_msg_usage_metadata(message)
elif message.server_content and message.server_content.input_transcription:
await self._handle_msg_input_transcription(message)
elif message.server_content and message.server_content.output_transcription: