When using the official Python Gemini / genai Live client with send_realtime_input in a text-only Live session, the model:
- Starts responding immediately after the first text input, ignoring the client-controlled end-of-turn.
- Returns WebSocket close code 1007 (invalid frame payload data) when an
activity_end message is sent via send_realtime_input.
We are using send_realtime_input exactly as defined in the library:
send_realtime_input(activity_start=ActivityStart()) – to signal the start of user activity,
send_realtime_input(text="...") – to send user utterances as text (transcriptions from our own STT),
send_realtime_input(activity_end=ActivityEnd()) – to signal the end of user activity.
Only one argument is passed per call, in line with the method’s contract.
This behavior did not occur on the previous Gemini Live preview model, where the same client-side pattern (activity_start → multiple text messages → activity_end) worked as expected.
Our production flow depends on text-only, client-side turn-taking (we have our own STT and end-of-turn detector), so this currently blocks migration to gemini-live-2.5-flash.
Environment details
- Programming language: Python 3.11
- OS: macOS / Linux (reproduced on multiple environments)
- Language runtime version: CPython 3.11.x
- Package: official Python
genai / Gemini Live client
(using session.send_realtime_input(...) exactly as in the library code)
- Model:
google/gemini-live-2.5-flash
- Input: text only (no audio/video sent)
- Output: text only
- Turn / activity detection: server-side VAD / automatic activity detection disabled; turn control is fully on the client
(Exact package and OS versions can be provided if needed.)
Steps to reproduce
-
Create a Gemini Live session using the Python genai client in text-only mode:
- model:
google/gemini-live-2.5-flash,
- response modalities: text,
- no audio / video media sent,
- server-side VAD / automatic activity detection disabled (client-side end-of-turn detection).
-
When the user starts speaking (detected on the client side), call send_realtime_input with activity_start to signal the start of user activity.
-
While the user is speaking, call send_realtime_input with text multiple times, passing consecutive transcribed fragments from STT.
Each call uses exactly one argument: text="..." (no other fields set).
-
When the client-side end-of-turn detector decides that the user has finished speaking, call send_realtime_input with activity_end to signal the end of the user turn.
-
Observe the behavior:
- The model starts generating text responses immediately after the first
text message in step 3, before the activity_end event is sent.
- When
activity_end is eventually sent, the WebSocket connection is closed with:
received 1007 (invalid frame payload data) Request contains an invalid argument.; then sent 1007 (invalid frame payload data) Request contains an invalid argument.
Throughout this sequence, all messages are sent via send_realtime_input with exactly one of the supported arguments (text, activity_start, or activity_end) per call.
Expected behavior
For a text-only Live session with server-side VAD disabled and using this pattern:
send_realtime_input(activity_start=...)
- multiple
send_realtime_input(text=...) calls while the user is speaking
send_realtime_input(activity_end=...) when the user is done
we expect that:
- The model waits for the
activity_end signal before starting to generate a response.
- Sending
activity_end via send_realtime_input(activity_end=...) is treated as a valid payload and does not close the WebSocket.
- The response is only streamed after the client signals the end of the user turn.
This is how the same pattern behaved for us on the earlier Gemini Live preview model.
Actual behavior
With google/gemini-live-2.5-flash and the Python genai client:
- As soon as the first
send_realtime_input(text=...) call is made, the model immediately starts responding, even though activity_end has not been sent yet.
- When
send_realtime_input(activity_end=...) is called at the end of the user turn:
- the WebSocket is closed, and
- we receive 1007 (invalid frame payload data) – Request contains an invalid argument.
As a result:
- client-controlled end-of-turn is effectively ignored, and
- the
activity_end event sent via send_realtime_input is treated as an invalid payload.
Additional context
- We are migrating from the Gemini Live preview model (now being deprecated) to
google/gemini-live-2.5-flash.
- Our system already uses its own STT and end-of-turn detection, so we deliberately disable server-side VAD and depend on client-controlled turns.
- The same
activity_start → text → activity_end pattern previously worked reliably on the preview Live model.
If this is an intended change in behavior rather than a bug, guidance on the correct usage pattern for send_realtime_input with text-only, client-controlled turns (using activity_start / text / activity_end) would be very helpful.
When using the official Python Gemini /
genaiLive client withsend_realtime_inputin a text-only Live session, the model:activity_endmessage is sent viasend_realtime_input.We are using
send_realtime_inputexactly as defined in the library:send_realtime_input(activity_start=ActivityStart())– to signal the start of user activity,send_realtime_input(text="...")– to send user utterances as text (transcriptions from our own STT),send_realtime_input(activity_end=ActivityEnd())– to signal the end of user activity.Only one argument is passed per call, in line with the method’s contract.
This behavior did not occur on the previous Gemini Live preview model, where the same client-side pattern (
activity_start→ multipletextmessages →activity_end) worked as expected.Our production flow depends on text-only, client-side turn-taking (we have our own STT and end-of-turn detector), so this currently blocks migration to
gemini-live-2.5-flash.Environment details
genai/ Gemini Live client(using
session.send_realtime_input(...)exactly as in the library code)google/gemini-live-2.5-flash(Exact package and OS versions can be provided if needed.)
Steps to reproduce
Create a Gemini Live session using the Python
genaiclient in text-only mode:google/gemini-live-2.5-flash,When the user starts speaking (detected on the client side), call
send_realtime_inputwithactivity_startto signal the start of user activity.While the user is speaking, call
send_realtime_inputwithtextmultiple times, passing consecutive transcribed fragments from STT.Each call uses exactly one argument:
text="..."(no other fields set).When the client-side end-of-turn detector decides that the user has finished speaking, call
send_realtime_inputwithactivity_endto signal the end of the user turn.Observe the behavior:
textmessage in step 3, before theactivity_endevent is sent.activity_endis eventually sent, the WebSocket connection is closed with:received 1007 (invalid frame payload data) Request contains an invalid argument.; then sent 1007 (invalid frame payload data) Request contains an invalid argument.Throughout this sequence, all messages are sent via
send_realtime_inputwith exactly one of the supported arguments (text,activity_start, oractivity_end) per call.Expected behavior
For a text-only Live session with server-side VAD disabled and using this pattern:
send_realtime_input(activity_start=...)send_realtime_input(text=...)calls while the user is speakingsend_realtime_input(activity_end=...)when the user is donewe expect that:
activity_endsignal before starting to generate a response.activity_endviasend_realtime_input(activity_end=...)is treated as a valid payload and does not close the WebSocket.This is how the same pattern behaved for us on the earlier Gemini Live preview model.
Actual behavior
With
google/gemini-live-2.5-flashand the Pythongenaiclient:send_realtime_input(text=...)call is made, the model immediately starts responding, even thoughactivity_endhas not been sent yet.send_realtime_input(activity_end=...)is called at the end of the user turn:As a result:
activity_endevent sent viasend_realtime_inputis treated as an invalid payload.Additional context
google/gemini-live-2.5-flash.activity_start→text→activity_endpattern previously worked reliably on the preview Live model.If this is an intended change in behavior rather than a bug, guidance on the correct usage pattern for
send_realtime_inputwith text-only, client-controlled turns (usingactivity_start/text/activity_end) would be very helpful.