fix(code): hide "Recent" section during onboarding model selection (#4198)

Onboarding model selection no longer shows a spurious "Recent" model on
a fresh install.

---

On a fresh install, the onboarding "Choose a Recommended Model" screen
showed a "Recent" entry for a model the user never picked. The startup
default-fallback resolution auto-detects a provider and persists it to
the recent-models MRU (`save_recent_model` / `touch_recent_model`),
which the curated onboarding picker then surfaced as "Recent". The fix
skips loading recents in curated (onboarding) mode, so the section only
appears once a user has genuinely switched models.

Made by [Open
SWE](https://openswe.vercel.app/agents/1188b11f-a113-c648-0ba7-b0a91b2f5c0c)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
Mason Daugherty
2026-06-24 01:38:22 -04:00
committed by GitHub
parent 0827bf1b63
commit af882e4f6c
2 changed files with 80 additions and 4 deletions
@@ -481,6 +481,12 @@ class ModelSelectorScreen(ModalScreen[tuple[str, str] | None]):
return i
return 0
def _initial_selected_index(self) -> int:
"""Return the default highlighted row for the current selector mode."""
if self._curated:
return 0
return self._find_current_model_index()
def compose(self) -> ComposeResult:
"""Compose the screen layout.
@@ -533,6 +539,7 @@ class ModelSelectorScreen(ModalScreen[tuple[str, str] | None]):
cli_override: dict[str, Any] | None,
*,
include_uninstalled: bool = True,
include_recent: bool = True,
) -> _ModelData:
"""Gather model discovery data synchronously.
@@ -547,6 +554,12 @@ class ModelSelectorScreen(ModalScreen[tuple[str, str] | None]):
install-required rows; (2) the provider is installed but its
upstream profiles omit the model, added as normal selectable
rows.
include_recent: When `True`, load the recent-models MRU so the
pinned "Recent" section can render. Onboarding sets this
`False`: first-run users have never picked a model, and the
startup default-fallback resolution writes its auto-detected
pick into the MRU, which would otherwise surface as a bogus
"Recent" entry the user never chose.
Returns:
A `_ModelData` bundle of the discovered models, default spec,
@@ -612,7 +625,7 @@ class ModelSelectorScreen(ModalScreen[tuple[str, str] | None]):
all_models.extend(uninstalled_recommended)
profiles = get_model_profiles(cli_override=cli_override)
recent_specs = load_recent_models()
recent_specs = load_recent_models() if include_recent else []
return _ModelData(
all_models,
config.default_model,
@@ -701,6 +714,7 @@ class ModelSelectorScreen(ModalScreen[tuple[str, str] | None]):
self._load_model_data,
self._cli_profile_override,
include_uninstalled=True,
include_recent=not self._curated,
)
except Exception:
logger.exception("Failed to load model data for /model selector")
@@ -728,7 +742,7 @@ class ModelSelectorScreen(ModalScreen[tuple[str, str] | None]):
self._install_extras = data.install_extras
self._all_models = self._apply_subset(self._unfiltered_models)
self._filtered_models = list(self._all_models)
self._selected_index = self._find_current_model_index()
self._selected_index = self._initial_selected_index()
self._loaded = True
# Re-apply any filter text the user typed while data was loading
@@ -816,7 +830,7 @@ class ModelSelectorScreen(ModalScreen[tuple[str, str] | None]):
query = self._filter_text.strip()
if not query:
self._filtered_models = list(self._all_models)
self._selected_index = self._find_current_model_index()
self._selected_index = self._initial_selected_index()
return
tokens = query.split()
@@ -837,7 +851,7 @@ class ModelSelectorScreen(ModalScreen[tuple[str, str] | None]):
exc_info=True,
)
self._filtered_models = list(search_models)
self._selected_index = self._find_current_model_index()
self._selected_index = self._initial_selected_index()
return
self._filtered_models = [
@@ -626,6 +626,47 @@ class TestRecentModelsSection:
specs = [spec for spec, _ in screen._filtered_models]
assert "anthropic:claude-sonnet-4-5" in specs
async def test_recent_section_hidden_during_onboarding(
self, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Curated onboarding never shows Recent, even if the MRU is populated.
Guards the `include_recent` gating in `_load_model_data` (see its
docstring for why the startup auto-detected fallback must not surface
as a "Recent" entry the user never chose).
"""
from deepagents_code.widgets import model_selector
recent_called = False
def _tracked_load_recent_models() -> list[str]:
nonlocal recent_called
recent_called = True
# Deliberately a recommended model so it survives curated filtering:
# on a revert it would reach the rendered "Recent" header, keeping
# the header assertion below an effective regression guard.
return ["anthropic:claude-opus-4-7"]
monkeypatch.setattr(
model_selector,
"load_recent_models",
_tracked_load_recent_models,
)
app = ModelSelectorTestApp()
async with app.run_test() as pilot:
screen = ModelSelectorScreen(curated=True)
app.push_screen(screen)
await pilot.pause()
assert recent_called is False
assert screen._recent_specs == []
headers = [
str(h.content)
for h in screen.query(".model-provider-header").results(Static)
]
assert not any("Recent" in h for h in headers)
async def test_recent_section_hidden_during_filter(
self, monkeypatch: pytest.MonkeyPatch
) -> None:
@@ -1345,6 +1386,21 @@ class TestCuratedModelSelection:
("openai:gpt-5.3-codex", "openai"),
]
def test_curated_initial_selection_starts_at_top(self) -> None:
"""Onboarding should highlight the first model, not the current one."""
screen = ModelSelectorScreen(
current_model="claude-opus-4-7",
current_provider="anthropic",
curated=True,
)
screen._filtered_models = [
("openai:gpt-5.5", "openai"),
("anthropic:claude-opus-4-7", "anthropic"),
]
assert screen._find_current_model_index() == 1
assert screen._initial_selected_index() == 0
class TestFormatOptionLabel:
"""Tests for _format_option_label."""
@@ -1860,8 +1916,10 @@ class TestModelSelectorInstallRouting:
_cli_override: dict[str, Any] | None,
*,
include_uninstalled: bool = True,
include_recent: bool = True,
) -> model_selector._ModelData:
captured["include_uninstalled"] = include_uninstalled
captured["include_recent"] = include_recent
return model_selector._ModelData(
[("baseten:zai-org/GLM-5.2", "baseten")],
None,
@@ -1888,6 +1946,10 @@ class TestModelSelectorInstallRouting:
await pilot.pause()
assert captured["include_uninstalled"] is True
# Curated onboarding must skip the recent-models MRU at the call site,
# independent of the rendering-level guard in
# test_recent_section_hidden_during_onboarding.
assert captured["include_recent"] is False
async def test_load_model_data_surfaces_uninstalled_recommended(
self, monkeypatch: pytest.MonkeyPatch