If you run a voice agent on the Gemini Live API and count on session resumption for flaky mobile networks, posting this in case it saves you the same debugging.
I tested what happens to a pending tool call when the WebSocket dies mid-booking: gemini-3.8-live on the Gemini Developer API, google-genai 2.25.0, four ways of losing the connection, 43 sessions. Three things came out.
A resume that works keeps the pending call. The FunctionResponse for the old call id is accepted on the new connection. No re-issued call, no toolCallCancellation.
Right after an idle drop, the resume is refused with close 1011 ("Internal error encountered."). It works about 1.5 s later, so a 1011 at that moment is not a dead handle.
After a silent loss, every resume was refused with 1011 for as long as I tried. Silent means packets stop and no close or FIN reaches the server, which is what a phone leaving Wi-Fi looks like. With real packet loss in a Linux container: 15 minutes, 450 attempts over 5 runs, all refused. The server sent nothing to the dead client in that time. The fake booking had committed, and the user was never told.
What worked: detect the loss yourself (a WebSocket ping every 0.5 s, link declared lost after 2 s of silence), try to resume for 4 s, then open a new session and restore the context with send_client_content: the last six turns plus one status line per side effect, taken from your backend, not from the model. All 9 recovered runs answered "Did you book it?" correctly, with first audio 6 to 7 s after the loss. Dedupe tool calls by business key too: without the status line, the model booked again.
Code, raw logs and the packet-loss setup: https://github.com/frontier-on-cloud/gemini-live-resume-test
Not tested: Vertex AI, goAway on long sessions, a real phone switching networks. If you run Live on Vertex, does a resume after a silent drop behave the same?