Skip to content

fix(google): restart the Gemini Live session between turns after a goAway - #2507

Open
anzemur wants to merge 3 commits into
livekit:mainfrom
anzemur:fix/google-realtime-goaway-between-turns
Open

anzemur wants to merge 3 commits into
livekit:mainfrom
anzemur:fix/google-realtime-goaway-between-turns

Conversation

@anzemur

@anzemur anzemur commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

What

handleGoAway set sessionShouldClose immediately, so the session restarted while a generation was in flight. Observed on gemini-3.8-live (agents-js 1.9.0): a goAway with timeLeft: "300s" arrived about a second into a session, the restart cut the opening reply mid-sentence, and the resumed session never produced another generation (only serverContent.interrupted: true in response to later client content).

This waits until no generation is in flight before restarting, polling every 250 ms, and always restarts at timeLeft - 10s so a generation that never completes cannot outlive the connection. Python's _handle_go_away has the same immediate restart (and the same TODO: this isn't a seamless reconnection just yet); happy to port this there too if wanted.

Related observation (not changed here)

With a forced mid-session restart on gemini-3.8-live (an updateTools() call between turns, which reconnects with the resumption handle), the model lost the chat context that was prefilled via clientContent in 2 of 3 runs ("I do not have memory of previous sessions"), while the same restart with the resumption handle dropped (fresh connection + the plugin's own history prefill) kept it in 3 of 3. That suggests session resumption on 3.8 does not restore prefilled clientContent; I have not touched resumption here but can open a follow-up making it opt-out if that matches your reading.

How verified

  • pnpm vitest run plugins/google/src/realtime/realtime_api.test.ts (11 passed, new case for the duration parser).
  • pnpm exec prettier --write on the two files; eslint reports only the three pre-existing no-explicit-any warnings.
  • Deploy-gate smoke of our voice agent (opening, seeded history, typed text, image, injection during a pending tool call, closing TTS) passes with this patch applied to 1.9.0.

Includes a patch changeset for @livekit/agents-plugin-google.

…Away

An immediate restart on goAway cut the reply being spoken; on gemini-3.8-live
the resumed session then never answered again. The server's timeLeft is the
outer bound for waiting out the current generation.
@changeset-bot

changeset-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4c964e0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 39 packages
Name Type
@livekit/agents-plugin-google Patch
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-anthropic Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-azure Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-cerebras Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-did Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-krisp Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-meta Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-mistralai Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-perplexity Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-protoface Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-runway Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugin-soniox Patch
@livekit/agents-plugin-tavus Patch
@livekit/agents-plugins-test Patch
@livekit/agents-plugin-trugen Patch
@livekit/agents-plugin-xai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@anzemur
anzemur requested a review from a team as a code owner September 15, 2026 23:27
devin-ai-integration[bot]

This comment was marked as resolved.

…goAway restart

A finished generation stays assigned to currentGeneration with only _done set,
so the idle check waited until the deadline after the first turn instead of
restarting between turns. Match the completion state onReceiveMessage uses.
devin-ai-integration[bot]

This comment was marked as resolved.

Besides a completed generation, require no pending reply request, no
blocking tool call awaiting its result and no manual user activity before
reconnecting. Automatic activity detection gives the client no signal for an
utterance in progress; the poll interval bounds that window.
this.sessionShouldClose.set();
return;
}
setTimeout(restartWhenIdle, GO_AWAY_IDLE_POLL_MS);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a session config update (such as updateTools()) triggers a reconnect, this timer can fire against the replacement connection. Could we capture the active session when handling goAway and return early if it has changed when the timer fires?

(!this.currentGeneration || this.currentGeneration._done) &&
!(this.pendingGenerationFut && !this.pendingGenerationFut.done) &&
!this.shouldBlockRealtimeInputForPendingTools() &&
!this.inUserActivity;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After sending a blocking tool result, we clear the pending tool ID, but Gemini’s tool reply may not have started yet. Could we keep the turn busy during that wait?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants