model.context_length is the user's profile-wide ceiling. It was read from
config.yaml in exactly one place — agent construction — and cached twice:
agent._config_context_length (switch/fallback resolution plus every display and
/usage surface) and context_compressor._config_context_length (the compressor's
own re-resolution).
Every live path that re-resolved a runtime then touched only one copy, or cleared
it without re-reading the config:
- switch_model nulled agent._config_context_length and re-derived the intent from
custom_providers metadata alone, so a ceiling that only exists as
model.context_length was dropped for the rest of the process;
- the Desktop/TUI compression hot-reload updated the compressor's copy only, so an
open session showed a pinned ceiling while compressing against provider
metadata / the 256K fallback.
Both now route through one pair of helpers in agent/agent_init.py:
set_config_context_length (one place that knows where the pin is cached) and
config_context_length_for_runtime (re-read from live config, scoped exactly like
construction, so an unrelated route still never inherits the pin).
(cherry picked from commit 986ff16dadb9966f7328e55f295af5cfa1eb5c88)