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

@MaxHTuMaxHTu 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 take effect via SDK flag settings

  • Adds resolveClaudeCatalogContextWindowEnv in ClaudeModelCatalog.ts to map catalog-resolved token counts to Claude SDK environment settings: ≤200k tokens maps to the 1M-context opt-out state, larger windows map to enabled, and missing token data produces no mapping
  • ClaudeAdapter.startSession in ClaudeAdapter.ts now merges the resolved context-window setting into initial SDK settings; ClaudeAdapter.sendTurn compares the current model's resolved window against tracked session state and applies an SDK flag-settings update before model switching when it changes, clearing with a null payload when catalog data disappears
  • ClaudeTextGeneration.ts now includes the resolved context-window setting in CLI operation settings alongside existing thinking, fast-mode, and ultracode settings
  • Behavioral Change: ClaudeAdapter.sendTurn now issues an SDK flag-settings call on every turn where the context window differs from tracked state; flag-settings failures are logged but do not fail the turn, leaving the prior tracked value so a later turn retries

Macroscope summarized a135cad.

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

CopilotAI 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

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-actionsgithub-actionsBot 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

macroscopeappBot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR changes effective Claude context-window defaults and overrides existing user/project settings across live sessions and CLI text-generation workflows. An unresolved medium-severity concern also remains around stale usage reporting during mid-thread window switches.

Not approved because:

  • 2 blocking correctness issues 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

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.

🟡 MediumLayers/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
Author

Choose a reason for hiding this comment

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

Good catch — reproduced: with a project .claude/settings.json setting CLAUDE_CODE_DISABLE_1M_CONTEXT: "1", a 1M selection ran at 200,000. Fixed in a135cad: the catalog helper now states the resolved window in both directions ("1" for 200k, "0" for any other known window) at session start and on mid-thread switches, so the window is decided by the selection alone. env: null isn't usable at startup (only applyFlagSettings accepts null), hence the explicit "0". Verified: flag-settings "0" beats the project-level "1" → 1,000,000.

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.

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. A failure there
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.
Fixespingdotgg#8405
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxHTu
MaxHTuforce-pushed the fix/claude-200k-context-window branch from 5da0e5b to a135cadCompareSeptember 3, 2026 17:19
}).pipe(Effect.as(false)),
),
);
if (applied) {

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.

🟡 MediumLayers/ClaudeAdapter.ts:4627

Switching from a 200k to a 1M context window leaves context.lastKnownContextWindow at 200k, so streaming usage caps usedTokens at 200k until the terminal result arrives. Update the cached context window when applyFlagSettings succeeds so the new turn's usage is reported against the selected window.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4627:
Switching from a 200k to a 1M context window leaves `context.lastKnownContextWindow` at 200k, so streaming usage caps `usedTokens` at 200k until the terminal result arrives. Update the cached context window when `applyFlagSettings` succeeds so the new turn's usage is reported against the selected window.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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

@MaxHTu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
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

@MaxHTuMaxHTu 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 take effect via SDK flag settings

  • Adds resolveClaudeCatalogContextWindowEnv in ClaudeModelCatalog.ts to map catalog-resolved token counts to Claude SDK environment settings: ≤200k tokens maps to the 1M-context opt-out state, larger windows map to enabled, and missing token data produces no mapping
  • ClaudeAdapter.startSession in ClaudeAdapter.ts now merges the resolved context-window setting into initial SDK settings; ClaudeAdapter.sendTurn compares the current model's resolved window against tracked session state and applies an SDK flag-settings update before model switching when it changes, clearing with a null payload when catalog data disappears
  • ClaudeTextGeneration.ts now includes the resolved context-window setting in CLI operation settings alongside existing thinking, fast-mode, and ultracode settings
  • Behavioral Change: ClaudeAdapter.sendTurn now issues an SDK flag-settings call on every turn where the context window differs from tracked state; flag-settings failures are logged but do not fail the turn, leaving the prior tracked value so a later turn retries

Macroscope summarized a135cad.

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

CopilotAI 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

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-actionsgithub-actionsBot 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

macroscopeappBot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR changes effective Claude context-window defaults and overrides existing user/project settings across live sessions and CLI text-generation workflows. An unresolved medium-severity concern also remains around stale usage reporting during mid-thread window switches.

Not approved because:

  • 2 blocking correctness issues 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

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.

🟡 MediumLayers/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
Author

Choose a reason for hiding this comment

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

Good catch — reproduced: with a project .claude/settings.json setting CLAUDE_CODE_DISABLE_1M_CONTEXT: "1", a 1M selection ran at 200,000. Fixed in a135cad: the catalog helper now states the resolved window in both directions ("1" for 200k, "0" for any other known window) at session start and on mid-thread switches, so the window is decided by the selection alone. env: null isn't usable at startup (only applyFlagSettings accepts null), hence the explicit "0". Verified: flag-settings "0" beats the project-level "1" → 1,000,000.

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.

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. A failure there
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.
Fixespingdotgg#8405
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxHTu
MaxHTuforce-pushed the fix/claude-200k-context-window branch from 5da0e5b to a135cadCompareSeptember 3, 2026 17:19
}).pipe(Effect.as(false)),
),
);
if (applied) {

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.

🟡 MediumLayers/ClaudeAdapter.ts:4627

Switching from a 200k to a 1M context window leaves context.lastKnownContextWindow at 200k, so streaming usage caps usedTokens at 200k until the terminal result arrives. Update the cached context window when applyFlagSettings succeeds so the new turn's usage is reported against the selected window.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4627:
Switching from a 200k to a 1M context window leaves `context.lastKnownContextWindow` at 200k, so streaming usage caps `usedTokens` at 200k until the terminal result arrives. Update the cached context window when `applyFlagSettings` succeeds so the new turn's usage is reported against the selected window.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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

@MaxHTu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

@MaxHTuMaxHTu 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 take effect via SDK flag settings

  • Adds resolveClaudeCatalogContextWindowEnv in ClaudeModelCatalog.ts to map catalog-resolved token counts to Claude SDK environment settings: ≤200k tokens maps to the 1M-context opt-out state, larger windows map to enabled, and missing token data produces no mapping
  • ClaudeAdapter.startSession in ClaudeAdapter.ts now merges the resolved context-window setting into initial SDK settings; ClaudeAdapter.sendTurn compares the current model's resolved window against tracked session state and applies an SDK flag-settings update before model switching when it changes, clearing with a null payload when catalog data disappears
  • ClaudeTextGeneration.ts now includes the resolved context-window setting in CLI operation settings alongside existing thinking, fast-mode, and ultracode settings
  • Behavioral Change: ClaudeAdapter.sendTurn now issues an SDK flag-settings call on every turn where the context window differs from tracked state; flag-settings failures are logged but do not fail the turn, leaving the prior tracked value so a later turn retries

Macroscope summarized a135cad.

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

CopilotAI 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

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-actionsgithub-actionsBot 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

macroscopeappBot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR changes effective Claude context-window defaults and overrides existing user/project settings across live sessions and CLI text-generation workflows. An unresolved medium-severity concern also remains around stale usage reporting during mid-thread window switches.

Not approved because:

  • 2 blocking correctness issues 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

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.

🟡 MediumLayers/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
Author

Choose a reason for hiding this comment

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

Good catch — reproduced: with a project .claude/settings.json setting CLAUDE_CODE_DISABLE_1M_CONTEXT: "1", a 1M selection ran at 200,000. Fixed in a135cad: the catalog helper now states the resolved window in both directions ("1" for 200k, "0" for any other known window) at session start and on mid-thread switches, so the window is decided by the selection alone. env: null isn't usable at startup (only applyFlagSettings accepts null), hence the explicit "0". Verified: flag-settings "0" beats the project-level "1" → 1,000,000.

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.

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. A failure there
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.
Fixespingdotgg#8405
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxHTu
MaxHTuforce-pushed the fix/claude-200k-context-window branch from 5da0e5b to a135cadCompareSeptember 3, 2026 17:19
}).pipe(Effect.as(false)),
),
);
if (applied) {

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.

🟡 MediumLayers/ClaudeAdapter.ts:4627

Switching from a 200k to a 1M context window leaves context.lastKnownContextWindow at 200k, so streaming usage caps usedTokens at 200k until the terminal result arrives. Update the cached context window when applyFlagSettings succeeds so the new turn's usage is reported against the selected window.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4627:
Switching from a 200k to a 1M context window leaves `context.lastKnownContextWindow` at 200k, so streaming usage caps `usedTokens` at 200k until the terminal result arrives. Update the cached context window when `applyFlagSettings` succeeds so the new turn's usage is reported against the selected window.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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

@MaxHTu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

@MaxHTuMaxHTu 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 take effect via SDK flag settings

  • Adds resolveClaudeCatalogContextWindowEnv in ClaudeModelCatalog.ts to map catalog-resolved token counts to Claude SDK environment settings: ≤200k tokens maps to the 1M-context opt-out state, larger windows map to enabled, and missing token data produces no mapping
  • ClaudeAdapter.startSession in ClaudeAdapter.ts now merges the resolved context-window setting into initial SDK settings; ClaudeAdapter.sendTurn compares the current model's resolved window against tracked session state and applies an SDK flag-settings update before model switching when it changes, clearing with a null payload when catalog data disappears
  • ClaudeTextGeneration.ts now includes the resolved context-window setting in CLI operation settings alongside existing thinking, fast-mode, and ultracode settings
  • Behavioral Change: ClaudeAdapter.sendTurn now issues an SDK flag-settings call on every turn where the context window differs from tracked state; flag-settings failures are logged but do not fail the turn, leaving the prior tracked value so a later turn retries

Macroscope summarized a135cad.

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

CopilotAI 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

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-actionsgithub-actionsBot 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

macroscopeappBot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR changes effective Claude context-window defaults and overrides existing user/project settings across live sessions and CLI text-generation workflows. An unresolved medium-severity concern also remains around stale usage reporting during mid-thread window switches.

Not approved because:

  • 2 blocking correctness issues 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

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.

🟡 MediumLayers/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
Author

Choose a reason for hiding this comment

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

Good catch — reproduced: with a project .claude/settings.json setting CLAUDE_CODE_DISABLE_1M_CONTEXT: "1", a 1M selection ran at 200,000. Fixed in a135cad: the catalog helper now states the resolved window in both directions ("1" for 200k, "0" for any other known window) at session start and on mid-thread switches, so the window is decided by the selection alone. env: null isn't usable at startup (only applyFlagSettings accepts null), hence the explicit "0". Verified: flag-settings "0" beats the project-level "1" → 1,000,000.

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.

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. A failure there
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.
Fixespingdotgg#8405
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxHTu
MaxHTuforce-pushed the fix/claude-200k-context-window branch from 5da0e5b to a135cadCompareSeptember 3, 2026 17:19
}).pipe(Effect.as(false)),
),
);
if (applied) {

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.

🟡 MediumLayers/ClaudeAdapter.ts:4627

Switching from a 200k to a 1M context window leaves context.lastKnownContextWindow at 200k, so streaming usage caps usedTokens at 200k until the terminal result arrives. Update the cached context window when applyFlagSettings succeeds so the new turn's usage is reported against the selected window.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4627:
Switching from a 200k to a 1M context window leaves `context.lastKnownContextWindow` at 200k, so streaming usage caps `usedTokens` at 200k until the terminal result arrives. Update the cached context window when `applyFlagSettings` succeeds so the new turn's usage is reported against the selected window.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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

@MaxHTu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
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

@MaxHTuMaxHTu 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 take effect via SDK flag settings

  • Adds resolveClaudeCatalogContextWindowEnv in ClaudeModelCatalog.ts to map catalog-resolved token counts to Claude SDK environment settings: ≤200k tokens maps to the 1M-context opt-out state, larger windows map to enabled, and missing token data produces no mapping
  • ClaudeAdapter.startSession in ClaudeAdapter.ts now merges the resolved context-window setting into initial SDK settings; ClaudeAdapter.sendTurn compares the current model's resolved window against tracked session state and applies an SDK flag-settings update before model switching when it changes, clearing with a null payload when catalog data disappears
  • ClaudeTextGeneration.ts now includes the resolved context-window setting in CLI operation settings alongside existing thinking, fast-mode, and ultracode settings
  • Behavioral Change: ClaudeAdapter.sendTurn now issues an SDK flag-settings call on every turn where the context window differs from tracked state; flag-settings failures are logged but do not fail the turn, leaving the prior tracked value so a later turn retries

Macroscope summarized a135cad.

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

CopilotAI 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

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-actionsgithub-actionsBot 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

macroscopeappBot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR changes effective Claude context-window defaults and overrides existing user/project settings across live sessions and CLI text-generation workflows. An unresolved medium-severity concern also remains around stale usage reporting during mid-thread window switches.

Not approved because:

  • 2 blocking correctness issues 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

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.

🟡 MediumLayers/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
Author

Choose a reason for hiding this comment

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

Good catch — reproduced: with a project .claude/settings.json setting CLAUDE_CODE_DISABLE_1M_CONTEXT: "1", a 1M selection ran at 200,000. Fixed in a135cad: the catalog helper now states the resolved window in both directions ("1" for 200k, "0" for any other known window) at session start and on mid-thread switches, so the window is decided by the selection alone. env: null isn't usable at startup (only applyFlagSettings accepts null), hence the explicit "0". Verified: flag-settings "0" beats the project-level "1" → 1,000,000.

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.

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. A failure there
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.
Fixespingdotgg#8405
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxHTu
MaxHTuforce-pushed the fix/claude-200k-context-window branch from 5da0e5b to a135cadCompareSeptember 3, 2026 17:19
}).pipe(Effect.as(false)),
),
);
if (applied) {

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.

🟡 MediumLayers/ClaudeAdapter.ts:4627

Switching from a 200k to a 1M context window leaves context.lastKnownContextWindow at 200k, so streaming usage caps usedTokens at 200k until the terminal result arrives. Update the cached context window when applyFlagSettings succeeds so the new turn's usage is reported against the selected window.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4627:
Switching from a 200k to a 1M context window leaves `context.lastKnownContextWindow` at 200k, so streaming usage caps `usedTokens` at 200k until the terminal result arrives. Update the cached context window when `applyFlagSettings` succeeds so the new turn's usage is reported against the selected window.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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

@MaxHTu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

@MaxHTuMaxHTu 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 take effect via SDK flag settings

  • Adds resolveClaudeCatalogContextWindowEnv in ClaudeModelCatalog.ts to map catalog-resolved token counts to Claude SDK environment settings: ≤200k tokens maps to the 1M-context opt-out state, larger windows map to enabled, and missing token data produces no mapping
  • ClaudeAdapter.startSession in ClaudeAdapter.ts now merges the resolved context-window setting into initial SDK settings; ClaudeAdapter.sendTurn compares the current model's resolved window against tracked session state and applies an SDK flag-settings update before model switching when it changes, clearing with a null payload when catalog data disappears
  • ClaudeTextGeneration.ts now includes the resolved context-window setting in CLI operation settings alongside existing thinking, fast-mode, and ultracode settings
  • Behavioral Change: ClaudeAdapter.sendTurn now issues an SDK flag-settings call on every turn where the context window differs from tracked state; flag-settings failures are logged but do not fail the turn, leaving the prior tracked value so a later turn retries

Macroscope summarized a135cad.

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

CopilotAI 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

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-actionsgithub-actionsBot 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

macroscopeappBot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR changes effective Claude context-window defaults and overrides existing user/project settings across live sessions and CLI text-generation workflows. An unresolved medium-severity concern also remains around stale usage reporting during mid-thread window switches.

Not approved because:

  • 2 blocking correctness issues 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

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.

🟡 MediumLayers/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
Author

Choose a reason for hiding this comment

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

Good catch — reproduced: with a project .claude/settings.json setting CLAUDE_CODE_DISABLE_1M_CONTEXT: "1", a 1M selection ran at 200,000. Fixed in a135cad: the catalog helper now states the resolved window in both directions ("1" for 200k, "0" for any other known window) at session start and on mid-thread switches, so the window is decided by the selection alone. env: null isn't usable at startup (only applyFlagSettings accepts null), hence the explicit "0". Verified: flag-settings "0" beats the project-level "1" → 1,000,000.

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.

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. A failure there
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.
Fixespingdotgg#8405
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxHTu
MaxHTuforce-pushed the fix/claude-200k-context-window branch from 5da0e5b to a135cadCompareSeptember 3, 2026 17:19
}).pipe(Effect.as(false)),
),
);
if (applied) {

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.

🟡 MediumLayers/ClaudeAdapter.ts:4627

Switching from a 200k to a 1M context window leaves context.lastKnownContextWindow at 200k, so streaming usage caps usedTokens at 200k until the terminal result arrives. Update the cached context window when applyFlagSettings succeeds so the new turn's usage is reported against the selected window.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4627:
Switching from a 200k to a 1M context window leaves `context.lastKnownContextWindow` at 200k, so streaming usage caps `usedTokens` at 200k until the terminal result arrives. Update the cached context window when `applyFlagSettings` succeeds so the new turn's usage is reported against the selected window.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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

@MaxHTu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

@MaxHTuMaxHTu 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 take effect via SDK flag settings

  • Adds resolveClaudeCatalogContextWindowEnv in ClaudeModelCatalog.ts to map catalog-resolved token counts to Claude SDK environment settings: ≤200k tokens maps to the 1M-context opt-out state, larger windows map to enabled, and missing token data produces no mapping
  • ClaudeAdapter.startSession in ClaudeAdapter.ts now merges the resolved context-window setting into initial SDK settings; ClaudeAdapter.sendTurn compares the current model's resolved window against tracked session state and applies an SDK flag-settings update before model switching when it changes, clearing with a null payload when catalog data disappears
  • ClaudeTextGeneration.ts now includes the resolved context-window setting in CLI operation settings alongside existing thinking, fast-mode, and ultracode settings
  • Behavioral Change: ClaudeAdapter.sendTurn now issues an SDK flag-settings call on every turn where the context window differs from tracked state; flag-settings failures are logged but do not fail the turn, leaving the prior tracked value so a later turn retries

Macroscope summarized a135cad.

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

CopilotAI 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

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-actionsgithub-actionsBot 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

macroscopeappBot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR changes effective Claude context-window defaults and overrides existing user/project settings across live sessions and CLI text-generation workflows. An unresolved medium-severity concern also remains around stale usage reporting during mid-thread window switches.

Not approved because:

  • 2 blocking correctness issues 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

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.

🟡 MediumLayers/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
Author

Choose a reason for hiding this comment

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

Good catch — reproduced: with a project .claude/settings.json setting CLAUDE_CODE_DISABLE_1M_CONTEXT: "1", a 1M selection ran at 200,000. Fixed in a135cad: the catalog helper now states the resolved window in both directions ("1" for 200k, "0" for any other known window) at session start and on mid-thread switches, so the window is decided by the selection alone. env: null isn't usable at startup (only applyFlagSettings accepts null), hence the explicit "0". Verified: flag-settings "0" beats the project-level "1" → 1,000,000.

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.

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. A failure there
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.
Fixespingdotgg#8405
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxHTu
MaxHTuforce-pushed the fix/claude-200k-context-window branch from 5da0e5b to a135cadCompareSeptember 3, 2026 17:19
}).pipe(Effect.as(false)),
),
);
if (applied) {

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.

🟡 MediumLayers/ClaudeAdapter.ts:4627

Switching from a 200k to a 1M context window leaves context.lastKnownContextWindow at 200k, so streaming usage caps usedTokens at 200k until the terminal result arrives. Update the cached context window when applyFlagSettings succeeds so the new turn's usage is reported against the selected window.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4627:
Switching from a 200k to a 1M context window leaves `context.lastKnownContextWindow` at 200k, so streaming usage caps `usedTokens` at 200k until the terminal result arrives. Update the cached context window when `applyFlagSettings` succeeds so the new turn's usage is reported against the selected window.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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

@MaxHTu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
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

@MaxHTuMaxHTu 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 take effect via SDK flag settings

  • Adds resolveClaudeCatalogContextWindowEnv in ClaudeModelCatalog.ts to map catalog-resolved token counts to Claude SDK environment settings: ≤200k tokens maps to the 1M-context opt-out state, larger windows map to enabled, and missing token data produces no mapping
  • ClaudeAdapter.startSession in ClaudeAdapter.ts now merges the resolved context-window setting into initial SDK settings; ClaudeAdapter.sendTurn compares the current model's resolved window against tracked session state and applies an SDK flag-settings update before model switching when it changes, clearing with a null payload when catalog data disappears
  • ClaudeTextGeneration.ts now includes the resolved context-window setting in CLI operation settings alongside existing thinking, fast-mode, and ultracode settings
  • Behavioral Change: ClaudeAdapter.sendTurn now issues an SDK flag-settings call on every turn where the context window differs from tracked state; flag-settings failures are logged but do not fail the turn, leaving the prior tracked value so a later turn retries

Macroscope summarized a135cad.

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

CopilotAI 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

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-actionsgithub-actionsBot 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

macroscopeappBot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The PR changes effective Claude context-window defaults and overrides existing user/project settings across live sessions and CLI text-generation workflows. An unresolved medium-severity concern also remains around stale usage reporting during mid-thread window switches.

Not approved because:

  • 2 blocking correctness issues 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

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.

🟡 MediumLayers/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
Author

Choose a reason for hiding this comment

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

Good catch — reproduced: with a project .claude/settings.json setting CLAUDE_CODE_DISABLE_1M_CONTEXT: "1", a 1M selection ran at 200,000. Fixed in a135cad: the catalog helper now states the resolved window in both directions ("1" for 200k, "0" for any other known window) at session start and on mid-thread switches, so the window is decided by the selection alone. env: null isn't usable at startup (only applyFlagSettings accepts null), hence the explicit "0". Verified: flag-settings "0" beats the project-level "1" → 1,000,000.

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.

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. A failure there
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.
Fixespingdotgg#8405
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxHTu
MaxHTuforce-pushed the fix/claude-200k-context-window branch from 5da0e5b to a135cadCompareSeptember 3, 2026 17:19
}).pipe(Effect.as(false)),
),
);
if (applied) {

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.

🟡 MediumLayers/ClaudeAdapter.ts:4627

Switching from a 200k to a 1M context window leaves context.lastKnownContextWindow at 200k, so streaming usage caps usedTokens at 200k until the terminal result arrives. Update the cached context window when applyFlagSettings succeeds so the new turn's usage is reported against the selected window.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/ClaudeAdapter.ts around line 4627:
Switching from a 200k to a 1M context window leaves `context.lastKnownContextWindow` at 200k, so streaming usage caps `usedTokens` at 200k until the terminal result arrives. Update the cached context window when `applyFlagSettings` succeeds so the new turn's usage is reported against the selected window.

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

Labels

size:M30-99 changed lines (additions + deletions).vouch:unvouchedPR 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

@MaxHTu