Skip to content

Support newer Claude Code request fields for Grok#56

Open
hassaans wants to merge 1 commit into
raine:mainfrom
hassaans:grok-support-newer-claude-code-request-fields
Open

Support newer Claude Code request fields for Grok#56
hassaans wants to merge 1 commit into
raine:mainfrom
hassaans:grok-support-newer-claude-code-request-fields

Conversation

@hassaans

@hassaans hassaans commented Jul 17, 2026

Copy link
Copy Markdown

Claude Code >= 2.1 sends four request shapes the Grok translator rejects. Together they make current Claude Code unusable against the Grok provider — every request from a real session fails with one of:

400 unsupported Grok request field: diagnostics
400 unsupported system block
400 unsupported tool field: eager_input_streaming
400 tool result supports text children only

Approach

Each field is accepted and dropped rather than forwarded, matching how cache_control is already handled (verified, then not sent upstream). I deliberately did not loosen the translator into ignoring unknown fields — the fail-loud behaviour is clearly intentional, so unknown fields still bail and every existing rejection test is unchanged.

Field Notes
diagnostics Request diagnostics with no Grok equivalent.
cache_control.scope Claude Code now sends scope: "global" alongside type/ttl. valid_cache_control only permitted type/ttl, so any block carrying it failed as unsupported system block — the system block itself was fine, only the scope key was unrecognised.
eager_input_streaming A per-tool streaming hint with no Grok equivalent.
tool_reference children in tool_result Carry no text for the model, so they are skipped while text children are preserved.

Still rejected

An unrecognised cache_control scope, unknown top-level/tool/tool_result keys, and non-text tool_result children all continue to fail loudly. Added grok_translation_rejects_unknown_cache_control_scope to cover the new surface.

Verification

  • Field shapes were taken from a captured Claude Code request rather than guessed.
  • 5 new tests following the existing naming convention.
  • cargo test --locked: 592 passing, 0 failures. cargo fmt --check clean. No new clippy warnings.

Claude Code >= 2.1 sends four request shapes the Grok translator rejects,
which makes current Claude Code unusable against the Grok provider:

  400 unsupported Grok request field: diagnostics
  400 unsupported system block
  400 unsupported tool field: eager_input_streaming
  400 tool result supports text children only

Each is accepted and dropped rather than forwarded, matching how
cache_control is already handled (verified, then not sent upstream):

- diagnostics: request diagnostics with no Grok equivalent.
- cache_control.scope: Claude Code now sends `scope: "global"` alongside
  type/ttl. valid_cache_control only permitted type/ttl, so any block
  carrying it failed as "unsupported system block" - the block itself was
  fine, only the scope key was unrecognised.
- eager_input_streaming: a per-tool streaming hint with no Grok equivalent.
- tool_reference children inside tool_result: carry no text for the model,
  so they are skipped while the text children are preserved.

Unknown fields are still rejected: an unrecognised cache_control scope,
unknown top-level/tool/tool_result keys and non-text tool_result children
all continue to fail loudly, and the existing rejection tests are unchanged.

Field shapes were taken from a captured Claude Code 2.1.197 request.
@wtfsayo

wtfsayo commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

This does fix the issues

@raine

raine commented Jul 17, 2026

Copy link
Copy Markdown
Owner

2.1.212 appears to work for me

Not sure how to reproduce

@hassaans

Copy link
Copy Markdown
Author

Context on the use case, since reproduction came up: this is for running Claude Code's Remote Control (claude.ai / the mobile app) with Grok as the model backend, through claude-code-proxy.

The rejected fields come from the Remote Control / claude.ai-driven request path, not from a plain local claude client — which is likely why it doesn't reproduce with a normal setup. Driving a Remote Control session against the Grok provider, essentially every turn hit one of these 400s until each field was handled.

Happy to attach a full captured request body if it's useful for a regression fixture.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants