From 520b59db1696f37e4b4ff84e668ab2180d4883d2 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Mon, 8 Jun 2026 22:43:00 -0700 Subject: [PATCH] fix(tui): use canonical get_fallback_chain for parity + map author Follow-up to the salvaged fallback-chain fix: - Replace the hand-rolled fallback loader with the shared hermes_cli.fallback_config.get_fallback_chain() helper so the TUI path matches HermesCLI and gateway/run.py exactly: fallback_providers stays first and keeps order, with distinct legacy fallback_model entries merged in after (deduped). Previously the TUI loader picked one key OR the other, diverging from CLI/gateway when both were set. - Update the test to assert the merged canonical semantics. - Add psionic73 to scripts/release.py AUTHOR_MAP (CI gate). --- scripts/release.py | 1 + tests/test_tui_gateway_server.py | 11 +++++++++-- tui_gateway/server.py | 21 ++++++++------------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/scripts/release.py b/scripts/release.py index cab47b7386b..9b3c3830d58 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -58,6 +58,7 @@ AUTHOR_MAP = { "thomas.paquette@gmail.com": "RyTsYdUp", "techxacm@gmail.com": "ProgramCaiCai", "266365592+bmoore210@users.noreply.github.com": "bmoore210", + "157839748+psionic73@users.noreply.github.com": "psionic73", "manishbyatroy@gmail.com": "manishbyatroy", "chilltulpa@gmail.com": "TheGardenGallery", "al@randomsnowflake.me": "randomsnowflake", diff --git a/tests/test_tui_gateway_server.py b/tests/test_tui_gateway_server.py index 1b9d857140a..a7fcf2ed927 100644 --- a/tests/test_tui_gateway_server.py +++ b/tests/test_tui_gateway_server.py @@ -902,7 +902,10 @@ def test_startup_runtime_detects_provider_for_model_env(monkeypatch): ) -def test_load_fallback_model_prefers_fallback_providers(monkeypatch): +def test_load_fallback_model_merges_chain_providers_first(monkeypatch): + # Parity with HermesCLI / gateway: fallback_providers stays first and keeps + # its order, with any distinct legacy fallback_model entry merged in after + # (deduped on provider/model/base_url). fallback_chain = [ {"provider": "openrouter", "model": "openai/gpt-5.5"}, {"provider": "anthropic", "model": "claude-sonnet-4-6"}, @@ -916,7 +919,11 @@ def test_load_fallback_model_prefers_fallback_providers(monkeypatch): }, ) - assert server._load_fallback_model() == fallback_chain + assert server._load_fallback_model() == [ + {"provider": "openrouter", "model": "openai/gpt-5.5"}, + {"provider": "anthropic", "model": "claude-sonnet-4-6"}, + {"provider": "legacy", "model": "legacy-model"}, + ] def test_make_agent_passes_configured_fallback_chain(monkeypatch): diff --git a/tui_gateway/server.py b/tui_gateway/server.py index 7d9e2fd7c57..8515f7ea24d 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -2590,20 +2590,15 @@ def _parse_tui_skills_env() -> list[str]: def _load_fallback_model(): """Return the configured fallback chain for TUI-created agents. - Keep this in parity with ``HermesCLI.__init__``: prefer the new - ``fallback_providers`` list and accept the legacy single-dict - ``fallback_model`` shape. + Delegates to the shared ``get_fallback_chain`` helper so the TUI path + stays in parity with ``HermesCLI.__init__`` and ``gateway/run.py``: + ``fallback_providers`` is the primary source of truth and keeps its + order, with legacy ``fallback_model`` entries merged in afterwards + (deduped on provider/model/base_url). """ - cfg = _load_cfg() - fb = cfg.get("fallback_providers") or cfg.get("fallback_model") or [] - if isinstance(fb, dict): - fb = [fb] if fb.get("provider") and fb.get("model") else [] - if isinstance(fb, list): - return [ - f for f in fb - if isinstance(f, dict) and f.get("provider") and f.get("model") - ] - return [] + from hermes_cli.fallback_config import get_fallback_chain + + return get_fallback_chain(_load_cfg()) def _agent_fallback_model(agent):