Grok /live: overlapping function-call batches abort session with hard error
Summary
While using /live with the Grok (xAI) realtime backend, the session can terminate with:
Error: Grok issued new function calls before the previous function-call batch completed.This is emitted by omp itself (not a raw xAI API message) when Grok sends a new delegation/tool-call batch before the prior batch’s function_call_output replies have all been submitted.
Reproduction
- Start
/livewith Grok available (/login xaiorXAI_API_KEY, providergrokorautowhen Codex is unavailable). - Ask for something that triggers
delegate_to_agent(coding / repo work). - Let Grok delegate while the agent turn is still running (or slow), or interrupt / speak again before the delegation finishes.
- When Grok completes another realtime
responsethat includes new function calls, live mode errors out and stops.
(Exact trigger timing varies; repro is intermittent but has been hit in normal use.)
Expected
- Queue or coalesce overlapping Grok delegation batches, or
- Block new Grok responses until pending function outputs are flushed, or
- Degrade gracefully (warn + continue) instead of killing the live session.
Actual
GrokLiveTransport treats overlap as fatal and reports a terminal error via #reportFailure, which ends the live session.
Code path
Error site — packages/coding-agent/src/live/grok-transport.ts:
#dispatchFunctionCalls(): void {
if (this.#queuedFunctionCalls.length === 0) return;
if (this.#pendingFunctionOutputIds.size > 0) {
this.#reportFailure("Grok issued new function calls before the previous function-call batch completed.");
return;
}
// ...
}Flow today
- Grok emits
response.function_call_arguments.done→ calls queued. - On
response.done,#dispatchFunctionCalls()firesdelegation.createdevents. - Each call id stays in
#pendingFunctionOutputIdsuntil speakable delegation context is appended and#completeFunctionCall()sendsfunction_call_output+response.create. - If Grok starts a new response (new function calls) while step 3 is still in flight → hard error above.
Controller coupling — packages/coding-agent/src/live/controller.ts tracks a single #activeDelegationId and only completes the Grok function call after the delegated agent turn finishes and speakable chunks are sent. Slow or overlapping delegations widen the window for overlap.
Related
- #7947 — original xAI voice
/liverequest (implemented viaGrokLiveTransport) - #11404 —
/liveprovider picker / Codex exhaustion fallback (same surface area)
Suggested fix directions
- Queue: buffer
#queuedFunctionCallswhile#pendingFunctionOutputIds.size > 0, dispatch when the prior batch drains. - Backpressure: suppress
response.create/ inbound audio handling until pending outputs complete (if xAI protocol allows). - Controller: support multiple concurrent delegation ids (Grok can batch several calls per response).
- Tests: unit-test
GrokLiveTransport.handleServerMessagefor overlappingresponse.done+ function-call sequences (no live WebSocket needed).
Environment
- Feature:
/livetalk mode, Grok realtime (grok-voice-think-fast-2.0) - Reported: 2026-09-17 during normal live-mode use
Source: can1357/oh-my-pi