fix(grok): interrupt mid-turn sends and surface usage-limit errors - #8286
fix(grok): interrupt mid-turn sends and surface usage-limit errors#8286mavenskylab wants to merge 4 commits into
Conversation
Sending a follow-up on a Grok thread waited behind the in-flight ACP prompt instead of interrupting like Claude/Codex. A steer now cancels the current prompt and continues the same turn immediately. Grok reports exhausted usage via a private prompt_complete stop reason that T3 treated as a successful empty turn. Those completions now fail the turn with a visible usage-limit message. Fixes pingdotgg#8283 Fixes pingdotgg#8282 Made by Grok 4.6 via the Grok harness.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
There was a problem hiding this comment.
Effect service conventions review of the changed provider/ACP code. Two findings, both in the new settleXAiPromptCompletion branch for stopReason === "error" in apps/server/src/provider/acp/XAiAcpExtension.ts. The steering-cancel change in GrokAdapter.ts and its tests look consistent with the surrounding conventions.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a4e927f. Configure here.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR changes the production prompt lifecycle for Grok with concurrent cancellation, stale-prompt suppression, and same-turn re-prompting, while also modifying shared ACP cancellation ordering. Although focused tests cover the new scenarios, the hot-path state-management and cross-provider runtime impact merit human review. You can add or adjust custom eligibility rules. Learn more. |
Steers now discard superseded prompt epochs and start session/prompt under a prompt-lifecycle lock after awaiting session/cancel, so a follow-up cannot start before cancel is on the wire or miss the in-flight RPC. Grok error completions use a fixed AcpRequestError message with method, requestId, and agentResult data instead of echoing the wire payload into the user-facing message. Made by Grok 4.6 via the Grok harness.
There was a problem hiding this comment.
One finding: the new stopReason: "error" path copies the raw xAI wire payload into both data and cause. See inline comment.
Posted via Macroscope — Effect Service Conventions
Do not copy agentResult onto AcpRequestError.data, which would leak the raw wire payload through toProtocolError. The fixed message plus method/requestId stay as the public attributes; the payload is cause. Made by Grok 4.6 via the Grok harness.
There was a problem hiding this comment.
One finding on the new xAI prompt-completion failure mapping: the rate-limit branch drops the request context that the sibling error branch keeps.
Posted via Macroscope — Effect Service Conventions
Rate-limit completions now carry the same session/prompt method and requestId as the sibling error path so a usage-limit failure still identifies which prompt failed. Made by Grok 4.6 via the Grok harness.

What Changed
Grok follow-ups sent while a turn is running now interrupt the in-flight ACP prompt and continue the same turn immediately, matching Claude and Codex.
Grok usage-limit exhaustion is no longer treated as a successful empty completion. The turn fails once with a visible usage-limit message, the session returns to ready, and the selected model stays selected.
Why
Sending a message on a Grok thread did not interrupt the session. ACP
session/promptis serialized, so the adapter's steer waited for the current prompt to finish instead of cancelling it. A steer now sendssession/canceland re-prompts on the same turn.Grok reports exhausted usage through
_x.ai/session/prompt_completewithstopReason: "rate_limit"(or"error"). T3 normalized those unknown stop reasons toend_turn, so the thread completed with no message. The xAI completion fallback now fails those prompts.Fixes #8283
Fixes #8282
Related: #6396
UI Changes
None. This is a server-only Grok ACP prompt-lifecycle change.
Checklist
Made by Grok 4.6 via the Grok harness.
Note
Medium Risk
Changes Grok turn/prompt lifecycle and ACP cancel ordering on the hot path for sends; regressions could affect steering, hangs, or error surfacing, though coverage is extensive.
Overview
Mid-turn Grok messages now steer like Claude/Codex by cancelling the in-flight ACP
session/promptand sending the new instruction on the same turn, instead of waiting behind serialized prompts.GrokAdapteraddspromptEpoch/discardBeforeEpochso superseded prompts never start, apromptLifecyclesemaphore to order cancel→prompt, and forks the prompt RPC sosession/cancelcan target the right in-flight work.xAI
_x.ai/session/prompt_completewithrate_limitorerrorno longer looks like a silent success.XAiAcpExtensionfails the pending prompt withAcpRequestError(usage-limit message and code-32003for rate limits), so the adapter surfaces a failed turn, session returns to ready, and the selected model is unchanged.AcpSessionRuntime.cancelawaitsagent.cancelon the wire so a replacement prompt cannot race ahead of cancel. Mock-agent env flags and tests cover steer, prep-time steer, rate-limit/error completions, and adapter behavior.Reviewed by Cursor Bugbot for commit 78debe5. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Interrupt mid-turn sends and surface xAI usage-limit errors in
GrokAdaptersendTurnnow treats a mid-turn send as a steer that cancels any in-flight ACP prompt and continues the same turn, using a monotonicpromptEpochand apromptLifecyclesemaphore to serialize cancel-then-prompt and discard stale epochsrate_limitorerrorstop reasons now fail the pending standard prompt with a structuredAcpRequestErrorinstead of resolving as a normal response;settleXAiPromptCompletionmapsrate_limitto code-32003("Grok usage limit reached") anderrorto an internal errorAcpSessionRuntime.cancelnow awaits the cancel request write instead of fire-and-forget, ensuring the cancel is sent before proceedingT3_ACP_EMIT_XAI_RATE_LIMIT_THEN_HANG,T3_ACP_EMIT_XAI_ERROR_THEN_HANG, andT3_ACP_EMIT_XAI_ERROR_WITHOUT_RESULT_THEN_HANGenv toggles to simulate these scenariosacp.canceland waits for it before starting the new prompt, which changes the timing of cancel delivery versus the prior fire-and-forget path in AcpSessionRuntime.tsMacroscope summarized 78debe5.