From 4fdaf0b4d889f8bb9442f82eefa873d90477f2de Mon Sep 17 00:00:00 2001 From: v1b3coder <264291321+v1b3coder@users.noreply.github.com> Date: Sat, 9 May 2026 14:49:22 -0700 Subject: [PATCH] fix: use credential_pool for custom endpoint model listing probes Same-provider /model switches on a 'custom' endpoint kept stale credentials because (a) _resolve_named_custom_runtime's bare-custom + explicit_base_url path went straight to OPENAI_API_KEY/OPENROUTER_API_KEY env fallbacks without consulting the credential pool, and (b) switch_model() guarded against custom-provider re-resolution to preserve base_url, locking in the prior api_key. Now the bare-custom path queries the credential pool first (mirroring the named-custom-provider branch behavior), and the same-provider switch guard is removed since resolve_runtime_provider has since grown a robust custom-resolution path that preserves base_url from model_cfg. Refs #18681 (the gateway-side api_key wiring is still separate), #16254, #12919. --- hermes_cli/model_switch.py | 7 +++---- hermes_cli/runtime_provider.py | 7 +++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/hermes_cli/model_switch.py b/hermes_cli/model_switch.py index dcdd81df4a7..b6cf63442a3 100644 --- a/hermes_cli/model_switch.py +++ b/hermes_cli/model_switch.py @@ -889,10 +889,9 @@ def switch_model( # "ollama-launch" that resolve_runtime_provider doesn't know), keep existing # credentials. Otherwise use the resolved values (picks up credential rotation, # base_url adjustments for OpenCode, etc.). - if runtime.get("provider") != "custom": - api_key = runtime.get("api_key", "") - base_url = runtime.get("base_url", "") - api_mode = runtime.get("api_mode", "") + api_key = runtime.get("api_key", "") + base_url = runtime.get("base_url", "") + api_mode = runtime.get("api_mode", "") except Exception: pass diff --git a/hermes_cli/runtime_provider.py b/hermes_cli/runtime_provider.py index 68c59509f71..fe996d1e399 100644 --- a/hermes_cli/runtime_provider.py +++ b/hermes_cli/runtime_provider.py @@ -492,6 +492,13 @@ def _resolve_named_custom_runtime( requested_norm = (requested_provider or "").strip().lower() if requested_norm == "custom" and explicit_base_url: base_url = explicit_base_url.strip().rstrip("/") + # Check credential pool first — mirrors the named-custom-provider path + # so bare `provider: custom` with a configured custom_providers entry + # also gets its api_key from the pool instead of env var fallbacks. + pool_result = _try_resolve_from_custom_pool(base_url, "custom", None) + if pool_result: + pool_result["source"] = "direct-alias" + return pool_result api_key_candidates = [ (explicit_api_key or "").strip(), os.getenv("OPENAI_API_KEY", "").strip(),