fix: credential pool fallback for custom providers (#4247)

Custom/aliased providers with keys in the credential pool (added via
hermes auth add) were reported unconfigured in the WebUI because provider
detection only checked env vars. Add _has_explicit_pool_credentials() that
checks the pool while filtering the ambient gh_cli entry (so Copilot doesn't
falsely show configured on any machine with gh installed), cache-routed to
avoid the cold per-provider load_pool latency, and resolve provider aliases
before load_pool() at every retrieval site so detection and retrieval read
the same pool (glm->zai, github->copilot, etc.). /api/models/live wrapped in
profile scope; getattr-safe runtime_api_key for OAuth-only entries.

Co-authored-by: akrhin <akrhin@users.noreply.github.com>
This commit is contained in:
nesquena-hermesandakrhin committed 2026-06-16 17:44:10 +00:00
1 parent 8fff266aaa
commit b81a92ecd5
4 files changed
+476 -7

No files matched your search

+20 -1
View File
@@ -6737,7 +6737,9 @@ def handle_get(handler, parsed) -> bool:
return j(handler, get_available_models())
if parsed.path == "/api/models/live":
return _handle_live_models(handler, parsed)
from api.profiles import profile_env_for_active_request
with profile_env_for_active_request("/api/models/live", logger_override=logger):
return _handle_live_models(handler, parsed)
# ── Auxiliary models (GET/POST) ──
if parsed.path == "/api/model/auxiliary":
@@ -12427,6 +12429,23 @@ def _handle_live_models(handler, parsed):
_model_cfg = cfg.get("model", {})
_base_url = _model_cfg.get("base_url")
_api_key = _model_cfg.get("api_key")
# Fallback: try credential pool for base_url + api_key
if (not _base_url or not _api_key) and provider.startswith("custom:"):
try:
from api.config import _has_explicit_pool_credentials, _resolve_provider_alias
if _has_explicit_pool_credentials(provider):
from agent.credential_pool import load_pool as _lpool
_resolved = _resolve_provider_alias(provider)
_lm_pool = _lpool(_resolved)
if _lm_pool:
_lm_entry = _lm_pool.select()
if _lm_entry:
if not _api_key:
_api_key = _lm_entry.runtime_api_key
if not _base_url:
_base_url = str(getattr(_lm_entry, "base_url", "") or "").strip()
except ImportError:
pass
if _base_url and _api_key:
try:
import urllib.request