Skip to content

gemini-3.1-flash-live-preview: no turnComplete for 50s+ after inputTranscription, sometimes with duplicate re-transcription of the same utterance #1346

Description

@kitexex

Model / SDK
Model: gemini-3.1-flash-live-preview
SDK: google-genai 2.19.0
Python 3.12.10, Windows 11
Modalities: audio in + audio out, video in, input & output transcription enabled
Description
Mid-session, the server accepts and transcribes user audio (serverContent.inputTranscription arrives with correct text) and then produces nothing — no audio parts, no turnComplete, no goAway, no error. Socket stays open. The gap is 50+ seconds and resolves one of two ways:

The server emits a duplicate inputTranscription of the identical utterance, then answers.
Nothing arrives until the client times out and reconnects.
This may be related to the VAD turn-thrashing behaviour in #1262 — a duplicate re-transcription of one utterance looks consistent with the server re-opening/re-processing a turn it already segmented.

Repro logs
Stalled turn (duplicate transcription, 55s apart, from a single spoken utterance):

[ 6.2s] inputTranscription: 'Hey Kite, did you see that? I just took second place.'
[ 61.5s] inputTranscription: 'Hey Kite, did you see that? I just took second place.' <-- identical, 55s later
[ 65.4s] turnComplete
Healthy turn, same script/config, minutes apart:

[ 6.2s] inputTranscription: 'Hey Kite, did you see that? I just took second place.'
[ 10.7s] turnComplete
~4.5s normally vs ~55s when it stalls. Intermittent, roughly 1 in 3 runs in my testing.

Minimal repro

# Stream continuous 16k mono PCM. Feed one pre-recorded utterance, then keep
# streaming digital silence forever (never stop sending). Log every
# inputTranscription with a timestamp and wait for turnComplete.
async with client.aio.live.connect(model=MODEL, config=CONFIG) as session:
    async def feed():
        for i in range(0, len(speech_pcm), STEP):
            await session.send_realtime_input(
                audio=types.Blob(data=speech_pcm[i:i+STEP],
                                 mime_type="audio/pcm;rate=16000"))
            await asyncio.sleep(0.1)
        while True:                       # never stop the stream
            await session.send_realtime_input(
                audio=types.Blob(data=SILENCE, mime_type="audio/pcm;rate=16000"))
            await asyncio.sleep(0.1)

    asyncio.create_task(feed())
    async for msg in session.receive():
        ...  # log inputTranscription / turnComplete with elapsed time

Run repeatedly — roughly 1 in 3 runs shows the 50s+ gap.

Config in use
Mic: 16kHz mono int16 PCM, 100ms chunks, sent continuously via send_realtime_input(audio=...), never paused (see "ruled out" below)
Video: 960x540 JPEG @ 1 FPS via send_realtime_input(video=...)
context_window_compression: sliding window, trigger 9000 / target 4500
session_resumption enabled
thinking_level: minimal
temperature: 1.0 (Google's recommended default for Gemini 3.x — see below, does not fix it)
Ruled out
Each checked with a dedicated repro script before filing:

Stopping the audio stream — reliably hangs a turn 100% of the time (distinct, apparently by-design behavior, not this bug). Client streams silence continuously and never stops; the 55s stall still happens.

Lossy audio — dropping 30% of mic chunks only degrades transcription accuracy, does not cause the stall.

Barge-in — interrupted fires and turnComplete follows normally (~0.6s later).

Text injection mid-stream — via send_realtime_input(text=...), completes normally.

Client-side send contention — instrumented, no send >1s, stalls occur with no backlog.

Uplink bandwidth — tested via the packet-loss case above; a constrained (1.63 Mbps) uplink degrades transcription only, not this.

Temperature — this thread discusses a similar-sounding dead-pause, and a Google rep in that thread confirms the recommended default for Gemini 3.x is temperature=1.0. I ran 10 independent single-turn trials at that exact default (fresh session each time, same utterance, continuous silence afterward so the stream itself never stops):

  1. STALL 29.0s to turnComplete
  2. ok 8.9s
  3. ok 6.8s
  4. ok 3.6s
  5. HARD TIMEOUT -- no turnComplete at all within 90s
  6. ok 5.1s
  7. ok 9.3s
  8. ok 4.1s
  9. HARD TIMEOUT -- no turnComplete at all within 90s
  10. ok 7.7s
    3/10 stalled (30%), two never recovering within 90s. Normal trials were tight (mean 6.5s, max 9.3s) — a clean bimodal split, not baseline variance. So this reproduces at the documented recommended setting, not a misconfiguration edge case.

Impact
Fatal to a live conversational agent's UX: user speaks, gets nothing, repeats themselves, still gets nothing. Any client timeout that recovers via reconnect discards the reply that was eventually coming and loses session context. One reporter on the temperature thread described the resulting failure mode well: the agent "loses initiative" and needs an external kick to recover — matches exactly what I see here.

Is there a recommended mitigation beyond reconnect-on-timeout? Is this tracked anywhere already?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions