fix: Nous portal model IDs + portal provider routing guard — v0.50.157 (closes #854)

Two bugs fixed: (1) _PROVIDER_MODELS["nous"] updated to slash-prefixed IDs that Nous API expects. (2) resolve_model_provider() now routes portal provider models through the portal (not OpenRouter) and preserves the full slash-prefixed model ID. 10 regression tests.
This commit is contained in:
nesquena-hermes
2026-04-22 16:05:27 -07:00
committed by GitHub
parent 1a98f75005
commit 0a75b3f1d3
3 changed files with 191 additions and 4 deletions

View File

@@ -613,10 +613,10 @@ _PROVIDER_MODELS = {
{"id": "deepseek-reasoner", "label": "DeepSeek Reasoner"},
],
"nous": [
{"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-preview", "label": "Gemini 3.1 Pro Preview (via Nous)"},
{"id": "anthropic/claude-opus-4.6", "label": "Claude Opus 4.6 (via Nous)"},
{"id": "anthropic/claude-sonnet-4.6", "label": "Claude Sonnet 4.6 (via Nous)"},
{"id": "openai/gpt-5.4-mini", "label": "GPT-5.4 Mini (via Nous)"},
{"id": "google/gemini-3.1-pro-preview", "label": "Gemini 3.1 Pro Preview (via Nous)"},
],
"zai": [
{"id": "glm-5.1", "label": "GLM-5.1"},
@@ -863,6 +863,21 @@ def resolve_model_provider(model_id: str) -> tuple:
return bare, config_provider, config_base_url
# Unknown prefix (not a named provider) — pass full model_id through.
return model_id, config_provider, config_base_url
# Portal providers (Nous, OpenCode) serve models from multiple upstream
# namespaces. When the active provider is a portal, trust it for cross-
# namespace models rather than rerouting to OpenRouter — the portal
# handles the upstream routing itself. Preserve the full slash-prefixed
# model ID: portals use the provider/model path as the canonical name
# at their /chat/completions endpoint (e.g. Nous rejects a bare
# "claude-opus-4.6" — it needs "anthropic/claude-opus-4.6" to route
# upstream). This keeps the static-dropdown path consistent with the
# live-fetched path (`@nous:anthropic/claude-opus-4.6`), which also
# preserves the slash via the split-at-first-colon in the @-prefix
# branch above.
_PORTAL_PROVIDERS = {"nous", "opencode-zen", "opencode-go"}
if config_provider in _PORTAL_PROVIDERS:
return model_id, config_provider, config_base_url
# If prefix does NOT match config provider, the user picked a cross-provider model
# from the OpenRouter dropdown (e.g. config=anthropic but picked openai/gpt-5.4-mini).
# In this case always route through openrouter with the full provider/model string.