Fix: Correct Gemini Live API text input to prevent 1007 WebSocket errors

- Restore TextInputMessage.realtimeInput structure for correct API format
- Remove invalid turnComplete message from _send_user_text method
- turnComplete is only valid for clientContent, not realtimeInput messages
- realtimeInput text completion is automatically inferred by the API

This fixes WebSocket 1007 errors caused by mixing realtimeInput and
clientContent message types in violation of the Gemini Live API contract.
This commit is contained in:
Pete
2025-08-03 10:58:59 -04:00
parent cccd82a617
commit 258e83c904
2 changed files with 4 additions and 7 deletions

View File

@@ -195,7 +195,7 @@ class VideoInputMessage(BaseModel):
class TextInputMessage(BaseModel):
"""Message containing text input data."""
text: str
realtimeInput: RealtimeInput
@classmethod
def from_text(cls, text: str) -> "TextInputMessage":
@@ -207,7 +207,7 @@ class TextInputMessage(BaseModel):
Returns:
A TextInputMessage instance.
"""
return cls(text=text)
return cls(realtimeInput=RealtimeInput(text=text))
class ClientContentMessage(BaseModel):

View File

@@ -976,17 +976,14 @@ class GeminiMultimodalLiveLLMService(LLMService):
with audio and video inputs, preventing temporal misalignment that can occur
when different modalities are processed through separate API pathways.
After sending the text, we signal turn completion to trigger a model response
for text-only interactions.
For realtimeInput, turn completion is automatically inferred by the API based
on user activity, so no explicit turnComplete signal is needed.
Args:
text: The text to send as user input.
"""
evt = events.TextInputMessage.from_text(text)
await self.send_client_event(evt)
# After sending text, we need to signal that the turn is complete.
evt = events.ClientContentMessage.model_validate({"clientContent": {"turnComplete": True}})
await self.send_client_event(evt)
async def _send_user_video(self, frame):
"""Send user video frame to Gemini Live API."""