[Bug]: Grok (ACP) ignores selected reasoning effort: reasoningEffort is never mapped to Grok's reasoning_effort option#15251

openedOct 3, 2026byBBirzool

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

  • apps/server

Steps to reproduce

  1. Enable the Grok provider (Grok CLI 1.0.46, grok agent stdio, ACP protocolVersion 1).
  2. Start a Grok thread (or a delegated Grok task) with model grok-4.6 and reasoning effort Low.
  3. Send any prompt.
  4. Check Grok's own session journal (~/.grok/sessions/<cwd>/<session>/chat_history.jsonl).

Expected behavior

Grok runs the turn at the selected effort (low).

Actual behavior

Grok runs at its default xhigh. The run's modelSelection is correct ({"id":"reasoningEffort","value":"low"}), but the value never reaches the ACP session.

Root cause, as far as I can see in the server bundle:

  1. On session/new, Grok advertises effort as a config option with a different id: {"id":"reasoning_effort","category":"thought_level","type":"select","currentValue":"xhigh","options":["xhigh","high","medium","low"]}. session/set_config_option {configId:"reasoning_effort", value:"low"} works (the response shows currentValue:"low").
  2. The generic ACP configureSession applies modelSelection.options only by exact id. reasoningEffort ≠ reasoning_effort, so it logs "ACP session does not expose requested configuration option(s)" and sets nothing.
  3. The Grok flavor's applyModelSelection calls applyGrokAcpModelSelection without requestedReasoningEffort / currentReasoningEffort. Only the text-generation path passes them. The provider event log shows session/set_model with two fields (sessionId, modelId) and no _meta.reasoningEffort.

Impact

  • Major degradation or frequent failure

Every Grok turn and delegated Grok task ignores the chosen effort. This costs latency and quota, and orchestration that relies on cheap low-effort Grok workers gets xhigh runs.

Version or commit

0.0.46-nightly.20261003.2623

Environment

macOS (Apple Silicon), T3 Code Nightly desktop app, Grok CLI 1.0.46 (stable).

Logs or stack traces

1provider event log (delegated Grok task): method "session/set_model", status "started", request {"valueType":"object","fieldCount":2}
2modelSelection of the same run: {"instanceId":"grok","model":"grok-4.6","options":[{"id":"reasoningEffort","value":"low"}]}

Workaround

A local patch that resolves an option by category when the exact id is missing (reasoningEffort → the select option with category thought_level), then calls setConfigOption with the found option's own id. Another possible fix: pass requestedReasoningEffort and currentReasoningEffort from the Grok flavor's applyModelSelection, as the text-generation path already does.

Note

Grok responding on behalf of Julius.

Triage

Thanks @Birzool for the protocol trace and the two candidate fixes. I didn't find another open issue for this.

Confirmed on current main (aad732901e). Nightly 0.0.46-nightly.20261003.2623 has the same code path. A checked-in Grok session/new transcript already advertises effort as reasoning_effort (category: "thought_level", values xhigh / high / medium / low). Whatever the default is, the selected low is never written.

What I found

The composer stores the effort under the model-capability id (buildGrokModelCapabilities publishes it as reasoningEffort), not under the session-config id. Your modelSelection matches that.

Thread turns and delegated turns both go through configureSession, and two things drop the value there:

  1. Grok's applyModelSelection calls applyGrokAcpModelSelection with only the model id. It doesn't pass requestedReasoningEffort or currentReasoningEffort. On protocol version 1, session/set_model can carry _meta.reasoningEffort, but only when those arguments are present. Without them, a model change sends { sessionId, modelId } (your fieldCount: 2), and if the session is already on that model, set_model is skipped entirely. GrokTextGeneration already passes both.
  2. The generic option loop matches modelSelection.options by exact config id. The session exposes reasoning_effort, not reasoningEffort, so the loop logs "ACP session does not expose requested configuration option(s)" and never calls session/set_config_option.

Likely fix area

  • Pass the stored reasoningEffort into applyGrokAcpModelSelection, along with the current effort from session setup, the way text generation already does. On protocol version 1, that sends session/set_model with _meta.reasoningEffort, including a same-model change from the CLI default to low.
  • Alternatively, resolve reasoningEffort to the thought_level select and call set_config_option with that option's own id. That's a wider ACP change. It would also cover protocols newer than 1, where applyModelSelection uses setModel and drops _meta.

A maintainer will decide on the fix direction.