From 3b53b3f4f6a43ddf2123548066dfd68a3abb3f27 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 15 Apr 2026 22:20:25 +0000 Subject: [PATCH 1/4] chore: update OpenRouter and provider model lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OpenRouter / _FALLBACK_MODELS (8 → 7 models): - Remove o4-mini (reasoning specialist, not a general-purpose pick) - Remove claude-sonnet-4-5 (superseded by 4.6) - Add gemini-3-flash as fast/cheap Google option - Update gemini-2.5-pro → gemini-3.1-pro (current flagship) - Better provider labels (Google, DeepSeek, Meta instead of 'Other') Direct-API providers: - openai: replace o4-mini with gpt-5.4 (general-purpose pairing with Mini) - google / gemini: gemini-2.5-pro → 3.1-pro, gemini-2.0-flash → 3-flash - Copilot, Nous, opencode-zen: same Gemini updates throughout Test: update test_fallback_still_has_o4_mini → test_fallback_has_gpt54 --- api/config.py | 45 +++++++++++--------------------- tests/test_issues_373_374_375.py | 10 ++++--- 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/api/config.py b/api/config.py index 2f83a11..921249a 100644 --- a/api/config.py +++ b/api/config.py @@ -404,31 +404,15 @@ CLI_TOOLSETS = get_config().get("platform_toolsets", {}).get("cli", _DEFAULT_TOO # ── Model / provider discovery ─────────────────────────────────────────────── # Hardcoded fallback models (used when no config.yaml or agent is available) +# Also used as the OpenRouter model list — keep this curated to current, widely-used models. _FALLBACK_MODELS = [ - {"provider": "OpenAI", "id": "openai/gpt-5.4-mini", "label": "GPT-5.4 Mini"}, - {"provider": "OpenAI", "id": "openai/o4-mini", "label": "o4-mini"}, - { - "provider": "Anthropic", - "id": "anthropic/claude-sonnet-4.6", - "label": "Claude Sonnet 4.6", - }, - { - "provider": "Anthropic", - "id": "anthropic/claude-sonnet-4-5", - "label": "Claude Sonnet 4.5", - }, - { - "provider": "Anthropic", - "id": "anthropic/claude-haiku-4-5", - "label": "Claude Haiku 4.5", - }, - {"provider": "Other", "id": "google/gemini-2.5-pro", "label": "Gemini 2.5 Pro"}, - { - "provider": "Other", - "id": "deepseek/deepseek-chat-v3-0324", - "label": "DeepSeek V3", - }, - {"provider": "Other", "id": "meta-llama/llama-4-scout", "label": "Llama 4 Scout"}, + {"provider": "OpenAI", "id": "openai/gpt-5.4-mini", "label": "GPT-5.4 Mini"}, + {"provider": "Anthropic", "id": "anthropic/claude-sonnet-4.6", "label": "Claude Sonnet 4.6"}, + {"provider": "Anthropic", "id": "anthropic/claude-haiku-4-5", "label": "Claude Haiku 4.5"}, + {"provider": "Google", "id": "google/gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, + {"provider": "Google", "id": "google/gemini-3-flash", "label": "Gemini 3 Flash"}, + {"provider": "DeepSeek", "id": "deepseek/deepseek-chat-v3-0324","label": "DeepSeek V3"}, + {"provider": "Meta", "id": "meta-llama/llama-4-scout", "label": "Llama 4 Scout"}, ] # Provider display names for known Hermes provider IDs @@ -463,7 +447,7 @@ _PROVIDER_MODELS = { ], "openai": [ {"id": "gpt-5.4-mini", "label": "GPT-5.4 Mini"}, - {"id": "o4-mini", "label": "o4-mini"}, + {"id": "gpt-5.4", "label": "GPT-5.4"}, ], "openai-codex": [ {"id": "gpt-5.4", "label": "GPT-5.4"}, @@ -475,7 +459,8 @@ _PROVIDER_MODELS = { {"id": "codex-mini-latest", "label": "Codex Mini (latest)"}, ], "google": [ - {"id": "gemini-2.5-pro", "label": "Gemini 2.5 Pro"}, + {"id": "gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, + {"id": "gemini-3-flash", "label": "Gemini 3 Flash"}, ], "deepseek": [ {"id": "deepseek-chat-v3-0324", "label": "DeepSeek V3"}, @@ -485,7 +470,7 @@ _PROVIDER_MODELS = { {"id": "claude-opus-4.6", "label": "Claude Opus 4.6 (via Nous)"}, {"id": "claude-sonnet-4.6", "label": "Claude Sonnet 4.6 (via Nous)"}, {"id": "gpt-5.4-mini", "label": "GPT-5.4 Mini (via Nous)"}, - {"id": "gemini-2.5-pro", "label": "Gemini 2.5 Pro (via Nous)"}, + {"id": "gemini-3.1-pro", "label": "Gemini 2.5 Pro (via Nous)"}, ], "zai": [ {"id": "glm-5.1", "label": "GLM-5.1"}, @@ -515,7 +500,7 @@ _PROVIDER_MODELS = { {"id": "gpt-4o", "label": "GPT-4o"}, {"id": "claude-opus-4.6", "label": "Claude Opus 4.6"}, {"id": "claude-sonnet-4.6", "label": "Claude Sonnet 4.6"}, - {"id": "gemini-2.5-pro", "label": "Gemini 2.5 Pro"}, + {"id": "gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, ], # OpenCode Zen — curated models via opencode.ai/zen (pay-as-you-go credits) "opencode-zen": [ @@ -564,8 +549,8 @@ _PROVIDER_MODELS = { ], # 'gemini' is the hermes_cli provider ID for Google AI Studio "gemini": [ - {"id": "gemini-2.5-pro", "label": "Gemini 2.5 Pro"}, - {"id": "gemini-2.0-flash", "label": "Gemini 2.0 Flash"}, + {"id": "gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, + {"id": "gemini-3-flash", "label": "Gemini 3 Flash"}, ], } diff --git a/tests/test_issues_373_374_375.py b/tests/test_issues_373_374_375.py index fccd7c9..f3dbc2f 100644 --- a/tests/test_issues_373_374_375.py +++ b/tests/test_issues_373_374_375.py @@ -127,10 +127,12 @@ class TestStaleModelListCleanup: "_FALLBACK_MODELS must keep gpt-5.4-mini as primary OpenAI model (#374)" ) - def test_fallback_still_has_o4_mini(self): - """_FALLBACK_MODELS must still contain o4-mini (reasoning model).""" - assert "o4-mini" in CONFIG_PY, ( - "_FALLBACK_MODELS must keep o4-mini as reasoning model (#374)" + def test_fallback_has_gpt54(self): + """_FALLBACK_MODELS must contain gpt-5.4-mini as the primary OpenAI option.""" + from api.config import _FALLBACK_MODELS + ids = [m["id"] for m in _FALLBACK_MODELS] + assert any("gpt-5.4-mini" in mid for mid in ids), ( + "_FALLBACK_MODELS must include gpt-5.4-mini as the primary OpenAI option" ) def test_copilot_list_unchanged(self): From 4c142da3f6b025e590e4ca49d902cbd17d2a33c3 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 15 Apr 2026 22:27:55 +0000 Subject: [PATCH 2/4] =?UTF-8?q?chore:=20expand=20OpenRouter=20list=20per?= =?UTF-8?q?=20feedback=20=E2=80=94=20Claude=204.5=20gen,=20Opus,=20R1,=20M?= =?UTF-8?q?averick,=20Mistral?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OpenRouter / _FALLBACK_MODELS (7 → 13 models): - Add gpt-5.4 (full OpenAI alongside Mini) - Restore claude-sonnet-4-5 (keep 4.5 generation alongside 4.6) - Add claude-opus-4.6 (flagship) - Add deepseek-r1 (popular reasoning model) - Add llama-4-maverick (larger open-weight option) - Add mistral-large-latest (Mistral via OpenRouter) Structural: - Add mistralai to _PROVIDER_MODELS for correct prefix-stripping routing - Add mistralai to _PROVIDER_DISPLAY for correct group label --- api/config.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/api/config.py b/api/config.py index 921249a..11270db 100644 --- a/api/config.py +++ b/api/config.py @@ -406,13 +406,25 @@ CLI_TOOLSETS = get_config().get("platform_toolsets", {}).get("cli", _DEFAULT_TOO # Hardcoded fallback models (used when no config.yaml or agent is available) # Also used as the OpenRouter model list — keep this curated to current, widely-used models. _FALLBACK_MODELS = [ - {"provider": "OpenAI", "id": "openai/gpt-5.4-mini", "label": "GPT-5.4 Mini"}, - {"provider": "Anthropic", "id": "anthropic/claude-sonnet-4.6", "label": "Claude Sonnet 4.6"}, - {"provider": "Anthropic", "id": "anthropic/claude-haiku-4-5", "label": "Claude Haiku 4.5"}, - {"provider": "Google", "id": "google/gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, - {"provider": "Google", "id": "google/gemini-3-flash", "label": "Gemini 3 Flash"}, - {"provider": "DeepSeek", "id": "deepseek/deepseek-chat-v3-0324","label": "DeepSeek V3"}, - {"provider": "Meta", "id": "meta-llama/llama-4-scout", "label": "Llama 4 Scout"}, + # OpenAI + {"provider": "OpenAI", "id": "openai/gpt-5.4-mini", "label": "GPT-5.4 Mini"}, + {"provider": "OpenAI", "id": "openai/gpt-5.4", "label": "GPT-5.4"}, + # Anthropic — 4.6 flagship + 4.5 generation + {"provider": "Anthropic", "id": "anthropic/claude-opus-4.6", "label": "Claude Opus 4.6"}, + {"provider": "Anthropic", "id": "anthropic/claude-sonnet-4.6", "label": "Claude Sonnet 4.6"}, + {"provider": "Anthropic", "id": "anthropic/claude-sonnet-4-5", "label": "Claude Sonnet 4.5"}, + {"provider": "Anthropic", "id": "anthropic/claude-haiku-4-5", "label": "Claude Haiku 4.5"}, + # Google + {"provider": "Google", "id": "google/gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, + {"provider": "Google", "id": "google/gemini-3-flash", "label": "Gemini 3 Flash"}, + # DeepSeek + {"provider": "DeepSeek", "id": "deepseek/deepseek-chat-v3-0324", "label": "DeepSeek V3"}, + {"provider": "DeepSeek", "id": "deepseek/deepseek-r1", "label": "DeepSeek R1"}, + # Meta + {"provider": "Meta", "id": "meta-llama/llama-4-scout", "label": "Llama 4 Scout"}, + {"provider": "Meta", "id": "meta-llama/llama-4-maverick", "label": "Llama 4 Maverick"}, + # Mistral + {"provider": "Mistral", "id": "mistralai/mistral-large-latest", "label": "Mistral Large"}, ] # Provider display names for known Hermes provider IDs @@ -435,6 +447,7 @@ _PROVIDER_DISPLAY = { "opencode-zen": "OpenCode Zen", "opencode-go": "OpenCode Go", "lmstudio": "LM Studio", + "mistralai": "Mistral", } # Well-known models per provider (used to populate dropdown for direct API providers) @@ -552,6 +565,11 @@ _PROVIDER_MODELS = { {"id": "gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, {"id": "gemini-3-flash", "label": "Gemini 3 Flash"}, ], + # Mistral — prefix used in OpenRouter model IDs (mistralai/mistral-large-latest) + "mistralai": [ + {"id": "mistral-large-latest", "label": "Mistral Large"}, + {"id": "mistral-small-latest", "label": "Mistral Small"}, + ], } From f5c4e110a4d263246b5601bb40b28c94092f42a2 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 15 Apr 2026 22:54:18 +0000 Subject: [PATCH 3/4] chore: add Qwen3 Coder, Qwen3.6 Plus, Grok 4.20; drop Llama - Remove llama-4-scout and llama-4-maverick - Add qwen/qwen3-coder, qwen/qwen3.6-plus, x-ai/grok-4-20 - Add qwen and x-ai to _PROVIDER_MODELS and _PROVIDER_DISPLAY --- api/config.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/api/config.py b/api/config.py index 11270db..23f67b0 100644 --- a/api/config.py +++ b/api/config.py @@ -420,9 +420,11 @@ _FALLBACK_MODELS = [ # DeepSeek {"provider": "DeepSeek", "id": "deepseek/deepseek-chat-v3-0324", "label": "DeepSeek V3"}, {"provider": "DeepSeek", "id": "deepseek/deepseek-r1", "label": "DeepSeek R1"}, - # Meta - {"provider": "Meta", "id": "meta-llama/llama-4-scout", "label": "Llama 4 Scout"}, - {"provider": "Meta", "id": "meta-llama/llama-4-maverick", "label": "Llama 4 Maverick"}, + # Qwen (Alibaba) — strong coding and general models + {"provider": "Qwen", "id": "qwen/qwen3-coder", "label": "Qwen3 Coder"}, + {"provider": "Qwen", "id": "qwen/qwen3.6-plus", "label": "Qwen3.6 Plus"}, + # xAI + {"provider": "xAI", "id": "x-ai/grok-4-20", "label": "Grok 4.20"}, # Mistral {"provider": "Mistral", "id": "mistralai/mistral-large-latest", "label": "Mistral Large"}, ] @@ -448,6 +450,8 @@ _PROVIDER_DISPLAY = { "opencode-go": "OpenCode Go", "lmstudio": "LM Studio", "mistralai": "Mistral", + "qwen": "Qwen", + "x-ai": "xAI", } # Well-known models per provider (used to populate dropdown for direct API providers) @@ -570,6 +574,15 @@ _PROVIDER_MODELS = { {"id": "mistral-large-latest", "label": "Mistral Large"}, {"id": "mistral-small-latest", "label": "Mistral Small"}, ], + # Qwen (Alibaba) — prefix used in OpenRouter model IDs (qwen/qwen3-coder) + "qwen": [ + {"id": "qwen3-coder", "label": "Qwen3 Coder"}, + {"id": "qwen3.6-plus", "label": "Qwen3.6 Plus"}, + ], + # xAI — prefix used in OpenRouter model IDs (x-ai/grok-4-20) + "x-ai": [ + {"id": "grok-4-20", "label": "Grok 4.20"}, + ], } From 9d4c075e2bea3f520eb31e6583b5685e3d0fa9f4 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 15 Apr 2026 23:00:29 +0000 Subject: [PATCH 4/4] fix: correct OpenRouter model slugs from live catalog verification - google/gemini-3.1-pro -> google/gemini-3.1-pro-preview (not GA yet) - google/gemini-3-flash -> google/gemini-3-flash-preview (not GA yet) - x-ai/grok-4-20 -> x-ai/grok-4.20 (dot not dash in slug) - Fix stale label: 'Gemini 2.5 Pro (via Nous)' -> 'Gemini 3.1 Pro Preview (via Nous)' --- api/config.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/api/config.py b/api/config.py index 23f67b0..e7bbd17 100644 --- a/api/config.py +++ b/api/config.py @@ -415,8 +415,8 @@ _FALLBACK_MODELS = [ {"provider": "Anthropic", "id": "anthropic/claude-sonnet-4-5", "label": "Claude Sonnet 4.5"}, {"provider": "Anthropic", "id": "anthropic/claude-haiku-4-5", "label": "Claude Haiku 4.5"}, # Google - {"provider": "Google", "id": "google/gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, - {"provider": "Google", "id": "google/gemini-3-flash", "label": "Gemini 3 Flash"}, + {"provider": "Google", "id": "google/gemini-3.1-pro-preview", "label": "Gemini 3.1 Pro Preview"}, + {"provider": "Google", "id": "google/gemini-3-flash-preview", "label": "Gemini 3 Flash Preview"}, # DeepSeek {"provider": "DeepSeek", "id": "deepseek/deepseek-chat-v3-0324", "label": "DeepSeek V3"}, {"provider": "DeepSeek", "id": "deepseek/deepseek-r1", "label": "DeepSeek R1"}, @@ -424,7 +424,7 @@ _FALLBACK_MODELS = [ {"provider": "Qwen", "id": "qwen/qwen3-coder", "label": "Qwen3 Coder"}, {"provider": "Qwen", "id": "qwen/qwen3.6-plus", "label": "Qwen3.6 Plus"}, # xAI - {"provider": "xAI", "id": "x-ai/grok-4-20", "label": "Grok 4.20"}, + {"provider": "xAI", "id": "x-ai/grok-4.20", "label": "Grok 4.20"}, # Mistral {"provider": "Mistral", "id": "mistralai/mistral-large-latest", "label": "Mistral Large"}, ] @@ -476,8 +476,8 @@ _PROVIDER_MODELS = { {"id": "codex-mini-latest", "label": "Codex Mini (latest)"}, ], "google": [ - {"id": "gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, - {"id": "gemini-3-flash", "label": "Gemini 3 Flash"}, + {"id": "gemini-3.1-pro-preview", "label": "Gemini 3.1 Pro Preview"}, + {"id": "gemini-3-flash-preview", "label": "Gemini 3 Flash Preview"}, ], "deepseek": [ {"id": "deepseek-chat-v3-0324", "label": "DeepSeek V3"}, @@ -487,7 +487,7 @@ _PROVIDER_MODELS = { {"id": "claude-opus-4.6", "label": "Claude Opus 4.6 (via Nous)"}, {"id": "claude-sonnet-4.6", "label": "Claude Sonnet 4.6 (via Nous)"}, {"id": "gpt-5.4-mini", "label": "GPT-5.4 Mini (via Nous)"}, - {"id": "gemini-3.1-pro", "label": "Gemini 2.5 Pro (via Nous)"}, + {"id": "gemini-3.1-pro-preview", "label": "Gemini 3.1 Pro Preview (via Nous)"}, ], "zai": [ {"id": "glm-5.1", "label": "GLM-5.1"}, @@ -517,7 +517,7 @@ _PROVIDER_MODELS = { {"id": "gpt-4o", "label": "GPT-4o"}, {"id": "claude-opus-4.6", "label": "Claude Opus 4.6"}, {"id": "claude-sonnet-4.6", "label": "Claude Sonnet 4.6"}, - {"id": "gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, + {"id": "gemini-3.1-pro-preview", "label": "Gemini 3.1 Pro Preview"}, ], # OpenCode Zen — curated models via opencode.ai/zen (pay-as-you-go credits) "opencode-zen": [ @@ -544,8 +544,8 @@ _PROVIDER_MODELS = { {"id": "claude-sonnet-4", "label": "Claude Sonnet 4"}, {"id": "claude-haiku-4-5", "label": "Claude Haiku 4.5"}, {"id": "claude-3-5-haiku", "label": "Claude 3.5 Haiku"}, - {"id": "gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, - {"id": "gemini-3-flash", "label": "Gemini 3 Flash"}, + {"id": "gemini-3.1-pro-preview", "label": "Gemini 3.1 Pro Preview"}, + {"id": "gemini-3-flash-preview", "label": "Gemini 3 Flash Preview"}, {"id": "glm-5.1", "label": "GLM-5.1"}, {"id": "glm-5", "label": "GLM-5"}, {"id": "kimi-k2.5", "label": "Kimi K2.5"}, @@ -566,8 +566,8 @@ _PROVIDER_MODELS = { ], # 'gemini' is the hermes_cli provider ID for Google AI Studio "gemini": [ - {"id": "gemini-3.1-pro", "label": "Gemini 3.1 Pro"}, - {"id": "gemini-3-flash", "label": "Gemini 3 Flash"}, + {"id": "gemini-3.1-pro-preview", "label": "Gemini 3.1 Pro Preview"}, + {"id": "gemini-3-flash-preview", "label": "Gemini 3 Flash Preview"}, ], # Mistral — prefix used in OpenRouter model IDs (mistralai/mistral-large-latest) "mistralai": [ @@ -581,7 +581,7 @@ _PROVIDER_MODELS = { ], # xAI — prefix used in OpenRouter model IDs (x-ai/grok-4-20) "x-ai": [ - {"id": "grok-4-20", "label": "Grok 4.20"}, + {"id": "grok-4.20", "label": "Grok 4.20"}, ], }