From d712a7fd735fbd2296e62b112397539f45fd467b Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sat, 27 Jun 2026 00:06:34 -0700 Subject: [PATCH] fix(model-picker): surface the current custom/uncurated model in picker rows (#53457) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A model selected via the CLI (e.g. /model openrouter/) was absent from every model picker — the main picker AND the MoA reference/ aggregator slot pickers — because each provider row only carried its curated catalog. Inject the current model at the front of its provider's row so it is selectable and shown everywhere. --- hermes_cli/model_switch.py | 18 ++++++ .../test_user_providers_model_switch.py | 60 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/hermes_cli/model_switch.py b/hermes_cli/model_switch.py index 5349bc3643a..92427967464 100644 --- a/hermes_cli/model_switch.py +++ b/hermes_cli/model_switch.py @@ -2253,6 +2253,24 @@ def list_authenticated_providers( seen_slugs.add(slug.lower()) _section4_emitted_slugs.add(slug.lower()) + # Surface a custom / uncurated model the user selected via the CLI. + # Each row's model list is its curated/live catalog, so a model the user set + # with `/model /` would otherwise be invisible in + # every picker — the main model picker AND the MoA reference/aggregator slot + # pickers, which read these same rows. Inject it at the front of the current + # provider's row (matched by slug) so it is selectable and shown. Done as a + # post-pass so it covers every provider section uniformly, regardless of + # which branch emitted the row. + if current_model: + for _row in results: + if not _row.get("is_current"): + continue + _models = _row.get("models") or [] + if current_model not in _models: + _row["models"] = [current_model, *_models] + _row["total_models"] = _row.get("total_models", len(_models)) + 1 + break + # Sort: current provider first, then by model count descending results.sort(key=lambda r: (not r["is_current"], -r["total_models"])) diff --git a/tests/hermes_cli/test_user_providers_model_switch.py b/tests/hermes_cli/test_user_providers_model_switch.py index a4f201a060b..7cff7e89692 100644 --- a/tests/hermes_cli/test_user_providers_model_switch.py +++ b/tests/hermes_cli/test_user_providers_model_switch.py @@ -1122,3 +1122,63 @@ def test_section3_skips_probe_when_no_key_but_explicit_models(monkeypatch): row = next(p for p in providers if p["slug"] == "public-subset") assert row["models"] == ["only-a", "only-b"] assert row["total_models"] == 2 + + +def test_current_custom_model_is_surfaced_in_builtin_provider_row(monkeypatch): + """A custom/uncurated model selected via the CLI must appear in its + provider's picker row. + + Regression: selecting `/model openrouter/` left the model + invisible in every picker (main model picker AND the MoA reference/aggregator + slot pickers, which read these rows), because the row only carried the + curated catalog. The current model is now injected at the front of the + current provider's list. + """ + monkeypatch.setattr("agent.models_dev.fetch_models_dev", lambda: {}) + monkeypatch.setattr("hermes_cli.providers.HERMES_OVERLAYS", {}) + monkeypatch.setenv("OPENROUTER_API_KEY", "sk-test") + # Pin a small curated catalog so the assertion is deterministic. + monkeypatch.setattr( + "hermes_cli.models.cached_provider_model_ids", + lambda slug, **kw: ["anthropic/claude-opus-4.8", "openai/gpt-5.5"] + if slug == "openrouter" + else [], + ) + + custom = "some-vendor/totally-custom-model-v9" + providers = list_authenticated_providers( + current_provider="openrouter", + current_model=custom, + user_providers={}, + custom_providers=[], + ) + + row = next(p for p in providers if p["slug"] == "openrouter") + assert custom in row["models"], row["models"] + assert row["models"][0] == custom # injected at the front + assert row["total_models"] == 3 + + +def test_current_custom_model_not_leaked_into_other_provider_rows(monkeypatch): + """The current model is only injected into the CURRENT provider's row, + never into other providers (which can't serve it).""" + monkeypatch.setattr("agent.models_dev.fetch_models_dev", lambda: {}) + monkeypatch.setattr("hermes_cli.providers.HERMES_OVERLAYS", {}) + monkeypatch.setenv("OPENROUTER_API_KEY", "sk-test") + monkeypatch.setenv("NOUS_API_KEY", "sk-test") + monkeypatch.setattr( + "hermes_cli.models.cached_provider_model_ids", + lambda slug, **kw: ["curated/one"], + ) + + custom = "some-vendor/totally-custom-model-v9" + providers = list_authenticated_providers( + current_provider="openrouter", + current_model=custom, + user_providers={}, + custom_providers=[], + ) + + for row in providers: + if row["slug"] != "openrouter" and not row.get("is_current"): + assert custom not in row.get("models", []), f"leaked into {row['slug']}"