fix(model): default /model switches to session scope everywhere

Flip the resolve_persist_behavior() fallback from persist-to-config to
session-only. A plain /model <name> (typed or via any picker — CLI,
TUI/Desktop, gateway) now affects only the current session; --global
persists explicitly, and model.persist_switch_by_default: true restores
the old opt-out behavior for users who want switches to stick.

This is the root cause behind the recurring 'session switch applied
globally' bug class (#61458, #63083, #58290, #61190): every surface
funnels its no-flag default through this one function, so per-surface
patches kept missing paths. Fixing the default fixes all surfaces at
once: CLI typed + picker, TUI/Desktop config.set + slash, gateway typed
+ inline picker.

Builds on liuhao1024's #58371 (--provider session scoping, cherry-picked
as the previous commit) and supersedes the per-surface #61488.
This commit is contained in:
Teknium 2026-07-20 01:10:45 -07:00
parent 0d6d73525d
commit 8b6fde3a35
8 changed files with 75 additions and 43 deletions

View file

@ -159,11 +159,11 @@ async def test_model_global_persists_when_config_has_proper_dict_model(tmp_path,
@pytest.mark.asyncio
async def test_model_no_flag_persists_by_default(tmp_path, monkeypatch):
"""A plain ``/model X`` (no --global) now persists to config.yaml.
async def test_model_no_flag_is_session_scoped_by_default(tmp_path, monkeypatch):
"""A plain ``/model X`` (no --global) does NOT persist to config.yaml.
This is the user-facing fix: switching models in one session survives
into the next without re-typing the switch every time.
This is the user-facing fix: switches are session-scoped unless the user
opts in with ``--global`` or sets ``model.persist_switch_by_default: true``.
"""
cfg_path = _setup_isolated_home(
tmp_path,
@ -178,7 +178,7 @@ async def test_model_no_flag_persists_by_default(tmp_path, monkeypatch):
assert result is not None
assert "gpt-5.5" in result
written = yaml.safe_load(cfg_path.read_text(encoding="utf-8"))
assert written["model"]["default"] == "gpt-5.5"
assert written["model"]["default"] == "old-model"
@pytest.mark.asyncio