Skip to content

Google realtime: a response carrying both a terminal server_content and a tool_call kills the receive task #7151

Description

@IngLP

What happens

In livekit-plugins-google, when a single LiveServerMessage carries both a terminal server_content (one with turn_complete) and a tool_call, the receive task raises and the session goes down.

The order is what does it. In the receive loop (realtime_api.py, v1.7.1):

if response.server_content:
    self._handle_server_content(response.server_content)   # L1159
if response.tool_call:
    self._handle_tool_calls(response.tool_call)            # L1161
  1. _handle_server_content sees turn_complete and calls _mark_current_generation_done() (L1382-1383).
  2. That closes the function channel: gen.function_ch.close() (L1424).
  3. _handle_tool_calls then does an unguarded gen.function_ch.send_nowait(...) (L1491) on the closed channel.

The exception propagates out of the receive task, so the whole realtime session is torn down rather than a single turn being lost.

Why the obvious fix doesn't work

Swapping the two dispatch calls moves the problem instead of solving it. _mark_current_generation_done sets _done = True but does not clear self._current_generation, so _handle_server_content would still find a generation and write into the streams _handle_tool_calls had just closed through its own trailing _mark_current_generation_done() (L1498).

Suggested direction

Hold the finalization back for the message that carries both, so the tool call is delivered on an open channel and the generation is finalized once afterwards. This also keeps the invariant #6785 introduced — that every tool call gets answered — which a message like this currently breaks by dropping the call on the floor (or, without a guard, by killing the session).

Notes

We currently carry a local guard that returns early when function_ch.closed, which converts the crash into a dropped tool call plus a warning. We would rather drop the guard than maintain it — happy to send a PR if the direction above looks right to you.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions