NousResearch/hermes-agent

Model picker behavior for multi-model custom providers

Cluster 5248 · hermes cli. Data as of

2 open items. Fix merged in #21211 on 7 May 2026. Check it covers your case.

The short answer

1open issue
1open PR
8items grouped
Known?
Yes. 8 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #21211. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this unresolved. That is separate from the fix event.
Still open
1 issue and 1 PR.

Most members concern how the model picker and model discovery handle custom or user-defined providers, including auto-selection of a saved or first model, list ordering, and discovery via /v1/models. One member is a broader salvage of model/provider resolution PRs, so it fits the theme less directly.

Open issues1

  • Issue#5248[Bug]: Model selection picker bypasses user choice — saved model auto-selected, list reordered unpredictably

Open PRs1

  • PR#24829fix(model-picker): add saved-model pre-menu and preserve list order

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #7187 fix(model): salvage model/provider resolution PRs #6860 #6844 #6863 #6943

    merged to main

    files: agent/auxiliary_client.py, agent/error_classifier.py, cli.py, hermes_cli/main.py, hermes_cli/model_normalize.py, hermes_cli/model_switch.py, run_agent.py, tests/agent/test_auxiliary_named_custom_providers.py, tests/agent/test_error_classifier.py, tests/hermes_cli/test_codex_models.py, tests/hermes_cli/test_custom_provider_model_switch.py, tests/hermes_cli/test_model_normalize.py, tests/hermes_cli/test_opencode_go_in_model_list.py, tests/run_agent/test_fallback_model.py, tests/run_agent/test_run_agent.py, tests/run_agent/test_switch_model_context.py

  • #21211 fix(model_switch): live model discovery for custom_providers in /model picker (salvage #19072)

    merged to main

    files: hermes_cli/model_switch.py, tests/hermes_cli/test_model_switch_custom_providers.py

    Show the diff
    • hermes_cli/model_switch.py
      @@ -1637,7 +1637,8 @@ def _has_aws_sdk_creds_for_listing(slug: str) -> bool:
                               groups[group_key]["models"].append(m)
       
               _section4_emitted_slugs: set = set()
      -        for grp in groups.values():
      +        for grp_key, grp in groups.items():
      +            api_url, api_key = [redacted:secret-assignment]
                   slug = grp["slug"]
                   # If the slug is already claimed by a built-in / overlay /
                   # user-provider row (sections 1-3), skip this custom group
      @@ -1675,6 +1676,18 @@ def _has_aws_sdk_creds_for_listing(slug: str) -> bool:
                   _grp_url_norm = _pair_key[1]
                   if _grp_url_norm and _grp_url_norm in _builtin_endpoints:
                       continue
      +            # Live model discovery from custom provider endpoints (matches
      +            # Section 3 behavior for user ``providers:`` entries).
      +            if api_url and api_key:
      +                try:
      +                    from hermes_cli.models import fetch_api_models
      +
      +                    live_models = fetch_api_models(api_key, api_url)
      +                    if live_models:
      +                        grp["models"] = live_models
      +                        grp["total_models"] = len(live_models)
      +                except Exception:
      +                    pass
                   results.append({
                       "slug": slug,
                       "name": grp["name"],
    • tests/hermes_cli/test_model_switch_custom_providers.py
      @@ -506,3 +506,64 @@ def _fake_fetch(api_key=None, base_url=None, timeout=5.0):
           )
       
           assert "base_url" not in captured
      +
      +
      +def test_custom_providers_uses_live_models_for_multi_model_endpoint(monkeypatch):
      +    """Custom providers with api_key + base_url should prefer live /models.
      +
      +    Custom providers (section 4 of list_authenticated_providers) point at
      +    gateways like Bifrost that expose hundreds of models.  Reading only the
      +    static ``models:`` dict from config.yaml leaves the /model picker with
      +    a stale subset.  Live discovery fills the picker with all available
      +    models from the endpoint.
      +    """
      +    monkeypatch.setattr("agent.models_dev.fetch_models_dev", lambda: {})
      +    monkeypatch.setattr("hermes_cli.providers.HERMES_OVERLAYS", {})
      +
      +    calls = []
      +
      +    def fake_fetch_api_models(api_key, base_url):
      +        calls.append((api_key, base_url))
      +        return ["gateway-model-a", "gateway-model-b", "gateway-model-c"]
      +
      +    monkeypatch.setattr("hermes_cli.models.fetch_api_models", fake_fetch_api_models)
      +
      +    custom_providers = [
      +        {
      +            "name": "my-gateway",
      +            "api_key": "[redacted:secret-assignment]",
      +            "base_url": "https://gateway.example.com/v1",
      +            "model": "gateway-model-a",
      +            "models": {
      +                "gateway-model-a": {"context_length": 128000},
      +                "gateway-model-b": {"context_length": 128000},
      +            },
      +        }
      +    ]
      +
      +    providers = list_authenticated_providers(
      +        current_provider="openrouter",
      +        current_base_url="https://openrouter.ai/api/v1",
      +        custom_providers=custom_providers,
      +        max_models=50,
      +    )
      +
      +    gateway_prov = next(
      +        (
      +            p
      +            for p in providers
      +            if p.get("api_url") == "https://gateway.example.com/v1"
      +        ),
      +        None,
      +    )
      +
      +    assert gateway_prov is not None, "Custom provider group not found in results"
      +    assert calls == [("sk-gateway-key", "https://gateway.example.com/v1")], (
      +        "fetch_api_models must be called with the custom provider's credentials"
      +    )
      +    assert gateway_prov["models"] == [
      +        "gateway-model-a",
      +        "gateway-model-b",
      +        "gateway-model-c",
      +    ], "Live models must replace the static subset"
      +    assert gateway_prov["total_models"] == 3

3 PRs closed without merging

From the close comments: closed without comment 1 · done elsewhere 1 · merged via another change 1

  • #5425 fix: model picker no longer auto-selects or reorders saved model (#5248) · closed without comment
  • #6863 fix: always show model selection for multi-model custom providers · merged via another change → #7187
  • #7132 feat: auto-discover models for custom/user-defined providers via /v1/models · done elsewhere → #21211, #17023
Closed issues · 1
  • Closed#6862hermes model locks to first model on multi-model custom endpoints
How this cluster was grouped
  • Link evidence (partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
  • Members outside that structural core may belong to a different underlying problem.
  • Pairwise link density 0.23: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
hermes cli
Merged PRs
#7187, #21211
Closed issues
1
Attempts
3 PRs closed without merging
Fix link checked
7 May 2026

For your agent

The same facts, typed.