Skip to content

fix: run Grok 4.7's 500k variants in max mode using Cursor's isMaxMode marker - #95

Merged
oakimov merged 24 commits into
mainfrom
fix/max-mode-variant-marker
Oct 17, 2026
Merged

oakimov merged 24 commits into
mainfrom
fix/max-mode-variant-marker

Conversation

@oakimov

@oakimov oakimov commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

Fixes #67. Includes the model-selection fixes from #84 and #86.

Grok 4.7’s 500k variants were sent with max_mode=false, causing not_found. Max mode now follows Cursor’s variant markers and supportsNonMaxMode, with the 1M fallback retained when a marker is absent.

  • Separate 500k/Fast entries expose the matching host context limit and pricing. Explicit selections keep their advertised parameter tuple; effort hints preserve the selected tier’s defaults and thinking mode.
  • Saved 500k variants remain on the original base/Fast entries, including their existing labels. These legacy selections keep their original static host budget; the dedicated 500k entries expose the full budget.
  • Foreign-history budgets use the resolved variant’s context, including marked 300k Fast variants.
  • Terminal error messages neutralize OpenCode 1.x retry triggers. The remaining final-5xx retry case is handled by fix: classify Cursor errors like Cursor CLI and stop host retries of final errors #97.

Validation: source/test typecheck, build, full unit suite with coverage, post-build architecture and pricing checks. Local HTTP/2 regressions verify saved selections through both catalog formats. Contributor live results confirm the 500k, 1M and 300k Fast windows on OpenCode 2.

willowite and others added 8 commits October 14, 2026 17:29
…arameter

Cursor names the parameter reasoning_effort for Grok 4.7, Gemini 3.8 Flash and Gemini 4 Argon. effortOf only matched effort and reasoning, so the hint never selected a variant and the default ran. Fixes #83.
Cursor declares a Fast variant as the default for Grok 4.7, 4.6 and 4.5.
The resolver's non-Fast pool drops it, so with no effort hint step 4 fell
through to the first non-Fast variant, the lowest effort. It now takes the
declared default's non-Fast twin first.

Refs #85
Grok 4.7's 500k variants went out with max_mode=false because max mode
was inferred only from a 1m context, and Cursor answered every Run with
not_found. AvailableModelVariant carries is_max_mode (field 3); Cursor
CLI requires max mode exactly when a variant is marked. Record the
marker in the model cache (schema 4 forces a refetch) and use it for the
request bit, for the max-tier effort pool and for the maxMode-hint
fallback, keeping the 1m rule only for unmarked variants.

A maxMode hint also takes the non-Fast twin of a Fast declared max
default (Grok 4.7 500k High, GPT-5.2 High), sharing the twin rule step 4
uses for the non-max default.

Fixes #67
@codecov

codecov Bot commented Oct 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[High impact] No new blocking issue was found; the final-error retry assessment depends on PR #97.

Summary

This PR uses Cursor’s max-mode markers and adds dedicated 500k model entries.

  • Cursor’s marked variants now send the matching max-mode flag.
  • Effort hints stay with the requested tier’s default variant.
  • Grok’s 500k variants now have their own catalog entries.
  • History rebases use the selected variant’s context size.
  • Terminal errors no longer match OpenCode 1.x retry words.
  • The operator notes now include the changelog merge lesson.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Cursor model list] --> B[Preserve variant markers and defaults]
  B --> C[Build shared host catalog]
  C --> D[Base and legacy selections]
  C --> E[Dedicated context entries]
  D --> F[Resolve advertised parameters]
  E --> F
  F --> G[Choose max-mode flag]
  F --> H[Check foreign-history budget]
  G --> I[Start Cursor Run]
  H --> I
Loading

Reviews (8) · Last reviewed commit: "Merge PR #86 while retaining max-tier se..." · Reviewed by Greptile

@oakimov

oakimov commented Oct 17, 2026

Copy link
Copy Markdown
Owner Author

I integrated the fixes from #84/#86 and pushed 25bc872: tier selection now precedes speed preference, and 500k entries have matching context limits and pricing. Regression coverage added; typecheck, build and all 2,279 tests passed.

Comment thread src/models.ts Outdated
…rt ties

- Size the foreign-history rebase budget from the resolved variant's context;
  Opus 300k Fast is marked max mode but is not a 1M window.
- Break reasoning-effort ties toward the tier default, as Cursor CLI does, so
  a hint no longer switches Claude to its non-thinking variant.
- Remove the unused effort override in buildRequestedModelParams.
- Price an exact wire id before stripping a context-like suffix.
- Name the model in the invalid isMaxMode error; attribute changelog entries.
@oakimov

oakimov commented Oct 17, 2026

Copy link
Copy Markdown
Owner Author

Review fixes (6292269)

An adversarial review of #84, #86 and this PR (which merges both) found these issues. All are fixed in 6292269:

  • Context budget for marked base-tier variants (regression in this PR). Cursor marks Claude Opus 300k Fast variants isMaxMode, so they now run in max mode, as Cursor CLI does. assertForeignHistoryRebaseFits then budgeted them against maxContextForMaxMode (1M) instead of 300k. The budget now comes from the resolved variant's context parameter. Test: test/turn-provenance.test.ts.
  • Effort hint dropped Claude thinking (pre-existing). The hint took the first variant with a matching effort, and Claude lists thinking=false first. Ties now break toward the tier default, as Cursor CLI's variant scoring does, so a hint changes only the effort. Test: test/model-effort-review.test.ts; it fails on the previous head.
  • Dead effort override removed. Nothing called buildRequestedModelParams's effort override anymore, and that override is how fix: honor reasoning effort hint for models with a reasoning_effort parameter #84's synthesized tuples happened. src/protocol/thinking.ts is deleted; advertised tuples are copied verbatim.
  • Pricing lookup. The widened -<n>k/-<n>m suffix stripping now runs only after an exact wire-id lookup, so a real id with such a suffix keeps its own rate. No current id is affected. Test: test/pricing.test.ts.
  • Minor. The invalid isMaxMode error now names the model. Unlinked changelog entries are attributed, the reasoning_effort entry also lists Claude Sonnet/Haiku 5.5, and the README and lessons are updated.

Validation: bun run typecheck, bun run build, bun test (2315 pass), bun run test:node-http2 and bun run check:pricing all pass locally. No live host run yet.

Open, not changed:

- Neutralize OpenCode 1.x SessionRetry message triggers (resource_exhausted,
  status-like digits, retry wording) in terminal host messages; a live
  usage-limit refusal was sent six times on 1.x, now once.
- Run every variant in max mode when Cursor reports supportsNonMaxMode=false,
  as Cursor CLI does; bump the model cache schema so it is discovered.
- Retain the declared default effort in a max tier that lacks the declared
  default's context.
@oakimov

oakimov commented Oct 17, 2026

Copy link
Copy Markdown
Owner Author

Live test and follow-up fixes (386e5c9)

Live results

Tested on OpenCode 1.19.3 and OpenCode 2.0.32 with this branch built locally. The two hosts gave identical results. "Cursor-reported window" is the context window from Cursor's own checkpoint.

Entry Parameters sent max_mode Cursor-reported window
composer-2.5, composer-2.5-fast fast=false/true false 200,000 (catalog 200,000)
grok-4.7, grok-4.7-fast context=256k, reasoning_effort=high false 256,000 (catalog 256,000)
grok-4.7-500k, grok-4.7-500k-fast context=500k, reasoning_effort=high true 500,000 (catalog 500,000)
grok-4.7 + reasoningEffort: "low" context=256k, reasoning_effort=low, fast=false false 256,000
grok-4.7 + maxMode: true context=500k, reasoning_effort=high, fast=false true 500,000

For Claude Opus 4.8 (300k, 300k High Fast, 1M), Sonnet 4.6 (200k, 1M), GPT-5.5 (272k, 1M), Gemini 3.8 Flash and Kimi K3, the requests are built as expected:

  • 300k: max_mode=false
  • 300k Fast: max_mode=true, because Cursor marks it max mode
  • 1M: max_mode=true

Cursor's reported window for these entries is not confirmed live yet.

Fixed in 386e5c9

  • OpenCode 1.x retried requests Cursor marked non-retryable. 1.x SessionRetry matches message text (resource_exhausted, and bare 429/500 digits such as $1500 or 500k) even when isRetryable is false. Terminal host messages now neutralize those triggers. Live, a refused request went from 6 sends to 1. OpenCode 2 already honors x-should-retry and sent it once. Test: test/errors.test.ts.
  • supportsNonMaxMode: false. Every variant of such a model now runs in max mode, matching Cursor CLI's requiresMaxMode. All current models report true. The model cache schema is bumped to 6. Test: test/model-selection-review.test.ts.
  • Default effort in a second max tier. A max-tier entry that lacks the declared default's context now keeps the declared default effort. Test: test/model-selection-review.test.ts.

Unit suite: 2318 pass.

Still open: 1.x also always retries any status >= 500. A non-retryable Cursor internal/unknown error still maps to 500, as AGENTS.md specifies, so 1.x can still retry it.

@nkoynov, could you test this branch against #67 in your setup? cursor/grok-4.7-500k, its Fast variant and a 500k variant picked from grok-4.7 should all run without not_found and report a 500k window. If you can, please also try a 1M entry (for example claude-opus-4-8-1m or gpt-5.5-1m) and an Opus 300k Fast variant, and share whether each turn succeeds. With CURSOR_PROVIDER_DEBUG=1, the checkpoint: … context=N/M line shows the window Cursor reports.

@nkoynov

nkoynov commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Tested 386e5c9 against main 530bd29 on OpenCode 2.0.31 with our real key, two short turns per entry. Every entry on #95 passed both turns, and the window in the checkpoint line matches the tier. On main the 500k tier is a variant of grok-4.7 / grok-4.7-fast, and picking it still gives the #67 not_found.

Entry main 530bd29 #95 386e5c9 Window (#95)
grok-4.7-500k no such entry; grok-4.7#Grok 4.7 High 500k fails with not_found, max_mode=false ok, context=500k, max_mode=true 500,000
grok-4.7-500k-fast no such entry; grok-4.7-fast#… High Fast 500k Fast fails with not_found, max_mode=false ok, max_mode=true 500,000
grok-4.7 + maxMode: true (config variant) ok, but sends context=256k, reasoning_effort=low, window 256,000 ok, context=500k, reasoning_effort=high, max_mode=true 500,000
claude-opus-5-5-1m#Claude Opus 5.5 1M High not run ok, max_mode=true 1,000,000
gpt-5.6-sol-1m#GPT-5.6 Sol 1M Low not run ok, max_mode=true 1,000,000
claude-opus-5-5#Claude Opus 5.5 High Fast not run ok, max_mode=true 300,000

One side effect: since the 500k tier moved from variants of grok-4.7 to its own entries, a saved selection like grok-4.7#Grok 4.7 High 500k comes back as "Variant unavailable" after the update. I didn't cover OpenCode 1.x.

@oakimov

oakimov commented Oct 17, 2026

Copy link
Copy Markdown
Owner Author

I fixed the saved-selection regression in 6b034f3. Existing 500k labels remain available on the original base/Fast entries, including collision labels and Fast-only tiers. Dedicated 500k entries still expose the full context budget; legacy selections retain their original static budget.

Both catalog formats and their Run requests are covered. Typecheck, build, architecture, pricing checks and all 2,325 tests pass; changed runtime coverage is 9/9 lines. The older final-5xx retry issue noted above is covered by #97.

@nkoynov

nkoynov commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

Rechecked 6b034f3 on OpenCode 2.0.31 with our real key: grok-4.7#Grok 4.7 High 500k and grok-4.7-fast#Grok 4.7 High Fast 500k Fast are offered again and both run with max_mode=true and a 500,000 window, and grok-4.7-500k still does the same, so the saved-label side effect is gone.

@oakimov

oakimov commented Oct 17, 2026

Copy link
Copy Markdown
Owner Author

Live confirmation against real Cursor is now complete (catalog fix 6b034f3, built from combined head 541b60b):

  • OpenCode 2.0.32: pre-fix base/Fast saved 500k selections both returned “Variant unavailable”. After upgrading those same sessions, both resumed successfully without model/variant flags and sent context=500k, max_mode=true; Cursor reported a 500,000-token window.
  • Fresh 2.0 base/Fast selections also survived a process restart, retaining the conversation and identical RequestContext hash.
  • OpenCode 1.19.3: both legacy selections passed live, including continuation with --variant. Its noninteractive CLI requires repeating that flag; the dedicated 500k entry retained its tier across restart without it.
  • Dedicated 500k and 500k Fast entries also passed on 2.0.32.

CI, Codecov and Greptile now pass on both #95 and #97.

@oakimov
oakimov force-pushed the fix/max-mode-variant-marker branch from 6b034f3 to 56e2fb4 Compare October 17, 2026 20:20
@oakimov
oakimov force-pushed the fix/max-mode-variant-marker branch from 56e2fb4 to 4fe4979 Compare October 17, 2026 20:21
oakimov added a commit that referenced this pull request Oct 17, 2026
@oakimov
oakimov merged commit b2289a7 into main Oct 17, 2026
6 checks passed
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.

Grok 4.7 500k variants fail with not_found: max mode is only set for 1m context

3 participants