Skip to content

fix(grok): interrupt mid-turn sends and surface usage-limit errors - #8286

Open
mavenskylab wants to merge 4 commits into
pingdotgg:mainfrom
mavenskylab:fix/grok-interrupt-and-usage-limit
Open

fix(grok): interrupt mid-turn sends and surface usage-limit errors#8286
mavenskylab wants to merge 4 commits into
pingdotgg:mainfrom
mavenskylab:fix/grok-interrupt-and-usage-limit

Conversation

@mavenskylab

@mavenskylab mavenskylab commented Aug 26, 2026

Copy link
Copy Markdown

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/prompt is serialized, so the adapter's steer waited for the current prompt to finish instead of cancelling it. A steer now sends session/cancel and re-prompts on the same turn.

Grok reports exhausted usage through _x.ai/session/prompt_complete with stopReason: "rate_limit" (or "error"). T3 normalized those unknown stop reasons to end_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

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

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/prompt and sending the new instruction on the same turn, instead of waiting behind serialized prompts. GrokAdapter adds promptEpoch / discardBeforeEpoch so superseded prompts never start, a promptLifecycle semaphore to order cancel→prompt, and forks the prompt RPC so session/cancel can target the right in-flight work.

xAI _x.ai/session/prompt_complete with rate_limit or error no longer looks like a silent success. XAiAcpExtension fails the pending prompt with AcpRequestError (usage-limit message and code -32003 for rate limits), so the adapter surfaces a failed turn, session returns to ready, and the selected model is unchanged.

AcpSessionRuntime.cancel awaits agent.cancel on 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 GrokAdapter

  • sendTurn now treats a mid-turn send as a steer that cancels any in-flight ACP prompt and continues the same turn, using a monotonic promptEpoch and a promptLifecycle semaphore to serialize cancel-then-prompt and discard stale epochs
  • xAI completions with rate_limit or error stop reasons now fail the pending standard prompt with a structured AcpRequestError instead of resolving as a normal response; settleXAiPromptCompletion maps rate_limit to code -32003 ("Grok usage limit reached") and error to an internal error
  • AcpSessionRuntime.cancel now awaits the cancel request write instead of fire-and-forget, ensuring the cancel is sent before proceeding
  • Mock agent gains T3_ACP_EMIT_XAI_RATE_LIMIT_THEN_HANG, T3_ACP_EMIT_XAI_ERROR_THEN_HANG, and T3_ACP_EMIT_XAI_ERROR_WITHOUT_RESULT_THEN_HANG env toggles to simulate these scenarios
  • Behavioral Change: discarded or interrupted prompts no longer emit completions; only the last remaining prompt settles the turn. Steering calls acp.cancel and waits for it before starting the new prompt, which changes the timing of cancel delivery versus the prior fire-and-forget path in AcpSessionRuntime.ts

Macroscope summarized 78debe5.

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.
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3aa2866d-a060-4d8d-8b60-3376deb018a4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 26, 2026
Comment thread apps/server/src/provider/Layers/GrokAdapter.ts Outdated
Comment thread apps/server/src/provider/Layers/GrokAdapter.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Comment thread apps/server/src/provider/acp/XAiAcpExtension.ts
Comment thread apps/server/src/provider/acp/XAiAcpExtension.ts Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread apps/server/src/provider/Layers/GrokAdapter.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.
@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Aug 26, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Comment thread apps/server/src/provider/acp/XAiAcpExtension.ts Outdated
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.

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Comment thread apps/server/src/provider/acp/XAiAcpExtension.ts
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

1 participant