From a5d1f68c74c0b7817baf7f1c47e5d8adfc6341c1 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Sat, 27 Jun 2026 03:28:58 -0700 Subject: [PATCH] refactor(moa): share one virtual-provider row builder across pickers Follow-up on the gateway-picker salvage: the cherry-picked change added a second copy of the MoA virtual-provider row in model_switch.py, duplicating inventory._moa_provider_row (same slug/name/preset-models, identical extra fields). Make _moa_provider_row take a bare current_provider string and reuse it from the gateway picker path so the row shape lives in one place and the two surfaces can't drift. --- hermes_cli/inventory.py | 12 +++++++++--- hermes_cli/model_switch.py | 23 +++++------------------ 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/hermes_cli/inventory.py b/hermes_cli/inventory.py index c74ebc288..0914cfc03 100644 --- a/hermes_cli/inventory.py +++ b/hermes_cli/inventory.py @@ -163,7 +163,7 @@ def build_models_payload( refresh=refresh, ) - moa_row = _moa_provider_row(ctx) + moa_row = _moa_provider_row(ctx.current_provider) if moa_row is not None: rows = [moa_row] + [r for r in rows if str(r.get("slug", "")).lower() != "moa"] @@ -442,7 +442,13 @@ def _apply_pricing( row["unavailable_models"] = [] -def _moa_provider_row(ctx: ConfigContext) -> dict | None: +def _moa_provider_row(current_provider: str = "") -> dict | None: + """Build the virtual ``moa`` provider row for model pickers. + + Shared by the CLI inventory (:func:`build_models_payload`) and the gateway + picker path (:func:`hermes_cli.model_switch.list_picker_providers`) so the + row shape stays in one place. Returns ``None`` when no MoA presets exist. + """ try: from hermes_cli.config import load_config from hermes_cli.moa_config import normalize_moa_config @@ -454,7 +460,7 @@ def _moa_provider_row(ctx: ConfigContext) -> dict | None: return { "slug": "moa", "name": "Mixture of Agents", - "is_current": (ctx.current_provider or "").lower() == "moa", + "is_current": (current_provider or "").lower() == "moa", "is_user_defined": False, "models": models, "total_models": len(models), diff --git a/hermes_cli/model_switch.py b/hermes_cli/model_switch.py index 048cb9c1d..3e1a133d8 100644 --- a/hermes_cli/model_switch.py +++ b/hermes_cli/model_switch.py @@ -2283,28 +2283,15 @@ def _prepend_moa_picker_provider(providers: List[dict], current_provider: str = ``list_authenticated_providers()`` only returns real/auth-backed providers. The CLI model inventory adds MoA separately so named presets appear next to normal providers; gateway pickers call ``list_picker_providers()`` directly, - so they need the same virtual row here. + so they need the same virtual row here. Reuse the inventory's single row + builder so the row shape stays defined in one place. """ try: - from hermes_cli.config import load_config - from hermes_cli.moa_config import normalize_moa_config + from hermes_cli.inventory import _moa_provider_row - cfg = normalize_moa_config(load_config().get("moa") or {}) - models = list(cfg.get("presets", {}).keys()) - if not models: + moa_row = _moa_provider_row(current_provider) + if moa_row is None: return providers - moa_row = { - "slug": "moa", - "name": "Mixture of Agents", - "is_current": (current_provider or "").lower() == "moa", - "is_user_defined": False, - "models": models, - "total_models": len(models), - "source": "virtual", - "authenticated": True, - "auth_type": "virtual", - "warning": "Aggregator acts as the selected model; references provide analysis before each call.", - } return [moa_row] + [p for p in providers if str(p.get("slug", "")).lower() != "moa"] except Exception: return providers