Claude Code reads ANTHROPIC_DEFAULT_MODEL as its lowest-priority startup
model (after --model, ANTHROPIC_MODEL and the settings `model` field). It is
a plain model id, so behind a proxy a bare value is clamped to 200k exactly
like the tier keys. Add it to EXTRA_EXTENDED_CONTEXT_MODEL_ENV_KEYS so
--1m/--no-1m and the saved preference toggle it with the rest.
The `--settings` launch overlay only carried the routing keys plus the five
Anthropic tier keys. Claude Code applies the settings `env` block on top of
the process environment, so a bare CLAUDE_CODE_SUBAGENT_MODEL or
ANTHROPIC_DEFAULT_MODEL persisted on disk silently undid the resolved
--1m result (and a saved [1m] undid --no-1m). Overlay the extended-context
extra keys too.
Verified with a stub Claude binary reading the overlay file:
ccs claude --no-1m -> ANTHROPIC_DEFAULT_MODEL=claude-opus-5, CLAUDE_CODE_SUBAGENT_MODEL=claude-sonnet-5
ccs claude --1m -> both keys suffixed with [1m]
The previous commit assumed Claude Code's fable resolver strips [1m] and
therefore never wrote the suffix into ANTHROPIC_DEFAULT_FABLE_MODEL. That
premise only holds when ANTHROPIC_BASE_URL is unset or points at
api.anthropic.com. Behind a proxy (CLIProxy, headroom, ...) Claude Code
2.1.259 does the opposite:
- the fable alias resolver passes the env value through untouched, so a
saved `claude-fable-5-1[1m]` reaches the model picker as-is;
- the context-window resolver grants 1M unconditionally when the model id
carries [1m], and otherwise trusts a natively-1M model only when the base
URL is first-party. Bare `claude-fable-5-1` via 127.0.0.1 is clamped to
200k even though CLIProxy's /v1/models advertises max_input_tokens 1M.
So the suffix is the only thing that turns the long window on for CCS, and
stripping it from the Fable key is what kept `ccs claude --model fable` at
200k. A headroom settings profile with the suffix saved on that key showed
the 1M window in the same Claude Code build, which is how the inversion was
caught.
Changes:
- Drop the suffix-stripping key guard; ANTHROPIC_DEFAULT_FABLE_MODEL now
receives and keeps [1m] exactly like the opus/sonnet tiers.
- On a long-context launch (explicit --1m, or a saved [1m] on any Anthropic
tier key) fill a missing Fable tier with the catalog Fable model plus
[1m]. The model-neutral claude profile pins no Fable model, so `--model
fable` used to fall back to Claude Code's bare default and lose the window
even when every other tier asked for 1M. An explicit mapping always wins,
--no-1m never fills, and providers without a catalog Fable model are left
alone.
- Add getDefaultFableTierModel() to the model catalog for that default.
Verified with a stub Claude binary that dumps its environment:
ccs claude --model fable -> ANTHROPIC_DEFAULT_FABLE_MODEL=claude-fable-5-1[1m]
ccs claude --1m -> ANTHROPIC_DEFAULT_FABLE_MODEL=claude-fable-5-1[1m]
ccs claude --no-1m --model fable -> no Fable tier written, ANTHROPIC_MODEL stripped
Claude Code resolves ANTHROPIC_DEFAULT_FABLE_MODEL through a resolver that
strips the [1m] suffix before use, unlike the opus/sonnet resolvers which
pass their env value through untouched. The stripped value is then treated
as an env-supplied default and held to the standard 200k window instead of
the model's native 1M, so writing [1m] into that key costs the long context
window rather than granting it.
Measured against a Claude Code 2.1.259 session (`/context` on a live proxy
endpoint):
ANTHROPIC_MODEL=claude-fable-5-1[1m] -> 1m window
ANTHROPIC_MODEL=claude-fable-5-1 -> 200k window
ANTHROPIC_DEFAULT_FABLE_MODEL=claude-fable-5-1[1m] -> 200k window
The fix is key-scoped rather than model-scoped, since the suffix is what
grants 1M on every other key. Adds envKeyAcceptsExtendedContextSuffix() as
the single place recording which keys reject the suffix, enforces it as a
floor inside applyExtendedContextPreferenceToAnthropicModels() so no caller
can bypass it, and strips a previously saved suffix from that key on the
next launch through the auto path.
Also extends the preference to CLAUDE_CODE_SUBAGENT_MODEL. Subagent windows
come from the same resolver as the main loop (the Explore inheritCap bounds
the model tier, not the context window), so a bare subagent model id sits at
200k while the suffixed form gets 1M. The new key list is kept separate from
ANTHROPIC_MODEL_ENV_KEYS, which also drives routing, model-id normalization
and profile validation.
Claude-Session: https://claude.ai/code/session_01NPkafQjVf4pSwPBwBistGk