Skip to content

fix: make Claude 200k context window selection take effect - #8409

Open
MaxHTu wants to merge 1 commit into
pingdotgg:mainfrom
MaxHTu:fix/claude-200k-context-window
Open

fix: make Claude 200k context window selection take effect#8409
MaxHTu wants to merge 1 commit into
pingdotgg:mainfrom
MaxHTu:fix/claude-200k-context-window

Conversation

@MaxHTu

@MaxHTu MaxHTu commented Aug 27, 2026

Copy link
Copy Markdown

What Changed

Selecting the 200k context window for Claude models now actually runs the session at 200k. A new catalog helper, resolveClaudeCatalogContextWindowEnv, states the resolved window to the CLI as CLAUDE_CODE_DISABLE_1M_CONTEXT"1" when the manifest resolves the selection to 200k tokens, "0" for any other known window, nothing for models without catalog token data. The adapter injects it into the SDK's flag-settings layer at session start and restates it via applyFlagSettings whenever the resolved value changes mid-thread; ClaudeTextGeneration (commit-message / PR-content / thread-title generation, which spawns the same CLI) applies the same value.

Why

Fixes #8405. Claude Code auto-enables the 1M window for claude-opus-5 / claude-fable-5 / claude-sonnet-5 unless the process opts out, so the bare model slug does not mean 200k — the 200k selection was a silent no-op and every such session ran at 1M (verified empirically via modelUsage[].contextWindow; details in the issue).

Design points, each verified against SDK 0.3.170 + CLI 2.1.247:

  • Catalog-driven, not option-id-driven: the rule keys off the manifest's contextWindowTokens rather than the literal "200k" option id, so remote manifest updates keep working and the synthetic test catalog covers it.
  • Flag settings, not process env: sessions spawn with settingSources: ["user", "project", "local"], and an env block in a user/project settings file overrides the spawned process env — a queryOptions.env-based fix is silently defeated by e.g. "env": {"CLAUDE_CODE_DISABLE_1M_CONTEXT": "0"} in ~/.claude/settings.json. Flag settings (the SDK settings option) outrank those files. Managed policy settings still win; the CLI's own usage report then corrects T3's meter.
  • Two-way, so the window is decided by the selection: stating only the 200k opt-out leaves the mirror-image bug (raised in review): a user/project settings file setting "1" would clamp a 1M selection to 200k while T3's meter claims 1M. Since T3's meter, warnings and maxTokens all derive from the same catalog data, any divergence makes T3 lie to the user — so the value is stated in both directions. Note for maintainers: this means T3 overrides a user's global CLAUDE_CODE_DISABLE_1M_CONTEXT=1 for every 1M-capable model, including claude-opus-4-7/4-8 where T3 offers no selector. The per-selection control in T3's UI is the intended replacement.
  • Mid-thread switches: the flag-settings value outranks an explicit [1m] model suffix, so without restating it a session started at 200k (any default Sonnet session) would silently clamp a later 1M selection. sendTurn restates it whenever the resolved value changes, ahead of setModel. A failure is logged rather than failing the turn, so an older CLI that doesn't know the control request loses only the window, not the turn.
  • Same bug in text generation: ClaudeTextGeneration spawns the same CLI with the same bare slug and already builds a --settings object, so it gets the same conditional spread.

This also makes the context meter agree with reality (#5286): selectedClaudeContextWindow seeds 200k and the CLI now confirms it instead of reporting 1M.

Testing: new/updated unit tests in ClaudeModelCatalog.test.ts (200k / 1m / fixed-window / no-data cases), ClaudeAdapter.test.ts, and ClaudeTextGeneration.test.ts (all on synthetic catalog fixtures); typecheck clean. Behavior verified end-to-end through the real SDK: bare slug → 1,000,000; flag-settings "1" → 200,000 even against a conflicting user-settings env block; flag-settings "0" → 1,000,000 against a project-settings "1"; mid-session applyFlagSettings flip verified in both directions.

Checklist

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

🤖 Generated with Claude Code

Note

Fix Claude 200k context window selection to set CLAUDE_CODE_DISABLE_1M_CONTEXT

  • Adds resolveClaudeCatalogContextWindowEnv to ClaudeModelCatalog.ts, which returns CLAUDE_CODE_DISABLE_1M_CONTEXT=1 for catalog windows ≤200,000 tokens, 0 for larger windows, and undefined when the catalog has no token data for the selection.
  • Session start and per-turn handlers in ClaudeAdapter.ts apply the resolved setting via the SDK applyFlagSettings operation, clearing it with null when a new selection has no catalog token data and caching the applied value to skip redundant calls.
  • Text generation in ClaudeTextGeneration.ts merges the same setting into the Claude CLI settings JSON so commit-message and PR-content generation respect the selected window.
  • Behavioral Change: if applyFlagSettings fails mid-thread, the adapter logs and suppresses the error but leaves the cached setting unchanged, so the next turn retries the same setting rather than advancing to the new one.

Macroscope summarized 1f9e869.


Note

Medium Risk
Changes Claude session configuration and mid-turn SDK flag updates; incorrect env mapping could mis-report context limits or clash with user settings files, though failures are non-fatal on turn apply.

Overview
Claude 200k context window selections now take effect instead of silently running at 1M. A new catalog helper maps manifest-resolved token counts to CLAUDE_CODE_DISABLE_1M_CONTEXT ("1" for ≤200k, "0" for larger known windows, omitted when the catalog has no token data).

ClaudeAdapter merges that env into initial SDK settings at session start and, on sendTurn, calls applyFlagSettings when the resolved window changes (before setModel), clears with env: null when appropriate, and refreshes lastKnownContextWindow so streaming usage is not clamped to the old limit after a mid-thread switch. Failures are logged without aborting the turn.

ClaudeTextGeneration adds the same env block to CLI --settings for commit/PR/title flows. Tests cover catalog resolution, adapter behavior (including custom-alias flows), and text generation args.

Reviewed by Cursor Bugbot for commit 1f9e869. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI lite review requested due to automatic review settings August 27, 2026 15:10

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Aug 27, 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: 38fd0cb7-3d62-400f-b2af-6628ead132d4

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 27, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR changes Claude's runtime context-window configuration at session start, during model switches, and in text generation, including precedence over existing user/project settings for 1M-capable defaults. That product-default behavior change, together with an unresolved startup-configuration risk, warrants human review.

Not approved because:

  • 1 blocking correctness issue found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

@MaxHTu

MaxHTu commented Sep 3, 2026

Copy link
Copy Markdown
Author

Rebased onto current main (conflicts came from the model-catalog refactor in #9084). The fix now lives behind a catalog helper, resolveClaudeCatalogContextWindowEnv, keyed off the manifest's contextWindowTokens rather than the literal "200k" option id, and the tests run on the synthetic catalog fixtures. Behavior is unchanged from the original PR.

// rather than the process env: a user or project settings file's
// `env` block overrides the spawned process env, while flag settings
// outrank both (live-test finding; managed policy settings still win).
...(contextWindowEnv ? { env: contextWindowEnv } : {}),

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.

🟡 Medium Layers/ClaudeAdapter.ts:4353

A fresh session selecting a non-200k context window can still start at 200k: when contextWindowEnv is undefined, settings omits env, so a user/project CLAUDE_CODE_DISABLE_1M_CONTEXT: "1" setting remains effective. The model-switch path already clears this with { env: null }; initial session creation must pass the same clear value so the selected context window is deterministic.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4353:

A fresh session selecting a non-200k context window can still start at 200k: when `contextWindowEnv` is `undefined`, `settings` omits `env`, so a user/project `CLAUDE_CODE_DISABLE_1M_CONTEXT: "1"` setting remains effective. The model-switch path already clears this with `{ env: null }`; initial session creation must pass the same clear value so the selected context window is deterministic.

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.

Sorry, I'm unable to act on this request because you do not have permissions within this repository.

@MaxHTu
MaxHTu force-pushed the fix/claude-200k-context-window branch from 5da0e5b to a135cad Compare September 3, 2026 17:19
Comment thread apps/server/src/provider/Layers/ClaudeAdapter.ts
Claude Code auto-enables the 1M-token context window for models that
support it (claude-opus-5, claude-fable-5, claude-sonnet-5), so passing
a bare model slug does not mean 200k — the session silently runs at 1M
regardless of the selection. State the selection explicitly through
CLAUDE_CODE_DISABLE_1M_CONTEXT ("1" when the catalog resolves the window
to 200k tokens, "0" otherwise), so the session runs the window T3
displays regardless of what a user or project settings file sets.

The rule lives in the model catalog (resolveClaudeCatalogContextWindowEnv),
keyed off the manifest's contextWindowTokens rather than a literal option
id, so remote manifest updates keep working. Models without catalog token
data are left to the user's configuration.

The value goes through the SDK settings option (the flag-settings layer)
instead of the spawned process env, because an `env` block in a user or
project settings file overrides the process env and would silently
defeat the fix. Managed policy settings still outrank it.

Because the flag-settings value also outranks an explicit `[1m]` model
suffix (verified empirically), sendTurn restates it via applyFlagSettings
whenever the resolved value changes, ahead of setModel, and refreshes
the session's cached context window on success so streaming usage isn't
clamped to the pre-switch window until the turn's result message
arrives. A failure applying flag settings is logged rather than failing
the turn, so an older CLI that does not know the control request loses
only the window, not the turn.

ClaudeTextGeneration spawns the same CLI with the same bare slug, so it
gets the same treatment.

Fixes pingdotgg#8405

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxHTu
MaxHTu force-pushed the fix/claude-200k-context-window branch from a135cad to 1f9e869 Compare September 4, 2026 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Claude 200k context window selection is a no-op; sessions always run at 1M

2 participants