diff --git a/cli.py b/cli.py index 4ca07fa0bf51..b99bb1c11731 100644 --- a/cli.py +++ b/cli.py @@ -6930,7 +6930,7 @@ def _handle_model_switch(self, cmd_original: str): try: if ctx is None: raise RuntimeError("inventory context unavailable") - providers = build_models_payload(ctx, max_models=50)["providers"] + providers = build_models_payload(ctx)["providers"] except Exception: providers = [] diff --git a/hermes_cli/inventory.py b/hermes_cli/inventory.py index 2c7d9c5bf5ce..7584dd887e03 100644 --- a/hermes_cli/inventory.py +++ b/hermes_cli/inventory.py @@ -117,7 +117,7 @@ def build_models_payload( pricing: bool = False, capabilities: bool = False, force_fresh_nous_tier: bool = False, - max_models: int = 50, + max_models: int | None = None, ) -> dict: """Build the ``{providers, model, provider}`` shape every consumer needs from a single substrate call. diff --git a/hermes_cli/model_switch.py b/hermes_cli/model_switch.py index a27292747bef..4da54beedf6d 100644 --- a/hermes_cli/model_switch.py +++ b/hermes_cli/model_switch.py @@ -1188,7 +1188,6 @@ def _warm() -> None: current_model=ctx.current_model, user_providers=ctx.user_providers, custom_providers=ctx.custom_providers, - max_models=50, ) except Exception: # Best-effort warmup — never surface errors into the session. @@ -1206,7 +1205,7 @@ def list_authenticated_providers( custom_providers: list | None = None, *, force_fresh_nous_tier: bool = False, - max_models: int = 8, + max_models: int | None = None, current_model: str = "", ) -> List[dict]: """Detect which providers have credentials and list their curated models. @@ -1426,7 +1425,7 @@ def _has_aws_sdk_creds_for_listing(slug: str) -> bool: if hermes_id in _MODELS_DEV_PREFERRED: model_ids = _merge_with_models_dev(hermes_id, model_ids) total = len(model_ids) - top = model_ids[:max_models] + top = model_ids[:max_models] if max_models else model_ids slug = hermes_id pinfo = _mdev_pinfo(mdev_id) @@ -1589,7 +1588,7 @@ def _has_aws_sdk_creds_for_listing(slug: str) -> bool: if hermes_slug in _MODELS_DEV_PREFERRED: model_ids = _merge_with_models_dev(hermes_slug, model_ids) total = len(model_ids) - top = model_ids[:max_models] + top = model_ids[:max_models] if max_models else model_ids results.append({ "slug": hermes_slug, @@ -1664,7 +1663,7 @@ def _has_aws_sdk_creds_for_listing(slug: str) -> bool: if not _cp_model_ids: _cp_model_ids = curated.get(_cp.slug, []) _cp_total = len(_cp_model_ids) - _cp_top = _cp_model_ids[:max_models] + _cp_top = _cp_model_ids[:max_models] if max_models else _cp_model_ids results.append({ "slug": _cp.slug, @@ -2040,7 +2039,7 @@ def list_picker_providers( current_base_url: str = "", user_providers: dict = None, custom_providers: list | None = None, - max_models: int = 8, + max_models: int | None = None, current_model: str = "", ) -> List[dict]: """Interactive-picker variant of :func:`list_authenticated_providers`. @@ -2083,7 +2082,7 @@ def list_picker_providers( except Exception: live_ids = list(p.get("models", [])) p = dict(p) - p["models"] = live_ids[:max_models] + p["models"] = live_ids[:max_models] if max_models else live_ids p["total_models"] = len(live_ids) has_models = bool(p.get("models")) diff --git a/hermes_cli/web_server.py b/hermes_cli/web_server.py index ed619979bfb7..fd371fede63c 100644 --- a/hermes_cli/web_server.py +++ b/hermes_cli/web_server.py @@ -3323,7 +3323,6 @@ def get_model_options(profile: Optional[str] = None): with _profile_scope(profile): return build_models_payload( load_picker_context(), - max_models=50, include_unconfigured=True, picker_hints=True, canonical_order=True, @@ -3398,7 +3397,7 @@ def get_recommended_default_model(provider: str = ""): try: from hermes_cli.inventory import build_models_payload, load_picker_context - payload = build_models_payload(load_picker_context(), max_models=50) + payload = build_models_payload(load_picker_context()) for row in payload.get("providers", []): if str(row.get("slug", "")).lower() == slug: models = row.get("models") or [] diff --git a/tests/hermes_cli/test_inventory.py b/tests/hermes_cli/test_inventory.py index 6eeb7a535be1..c7d761515b1a 100644 --- a/tests/hermes_cli/test_inventory.py +++ b/tests/hermes_cli/test_inventory.py @@ -660,3 +660,31 @@ def test_two_custom_providers_with_overlap_both_survive(): assert a_row["total_models"] == 2 assert b_row["total_models"] == 2 + +def test_build_models_payload_no_max_models_returns_full_list(): + """When max_models is not passed (None), build_models_payload must + return the full model list — not truncate to the old default of 50. + Regression for #48279: Kilo Gateway picker was capped at 50 of 336 + models, making most models undiscoverable via search.""" + full_models = [f"model-{i}" for i in range(100)] + rows = [ + { + "slug": "kilocode", + "name": "Kilo Code", + "models": full_models, + "total_models": len(full_models), + "is_current": False, + "is_user_defined": False, + "source": "built-in", + }, + ] + ctx = _empty_ctx() + with _list_auth_returning(rows): + # No max_models argument — should return all 100 models + payload = build_models_payload(ctx) + + kilo_row = next(r for r in payload["providers"] if r["slug"] == "kilocode") + assert kilo_row["models"] == full_models + assert kilo_row["total_models"] == 100 + assert len(kilo_row["models"]) == 100 + diff --git a/tui_gateway/server.py b/tui_gateway/server.py index f3ceaa956370..d2c29e35e7c8 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -9122,7 +9122,6 @@ def _(rid, params: dict) -> dict: canonical_order=True, pricing=True, capabilities=True, - max_models=50, ) return _ok(rid, payload) except Exception as e: