Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions agent/auxiliary_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2221,6 +2221,11 @@ def _wrap_if_needed(client_obj, final_model_str: str, base_url_str: str = "",

creds = resolve_api_key_provider_credentials(provider)
api_key = str(creds.get("api_key", "")).strip()
# An explicit api_key from a custom_providers fallback entry overrides
# the registered credential so the custom endpoint can authenticate even
# when no built-in key is configured for this provider alias.
if explicit_api_key:
api_key = explicit_api_key.strip()
if not api_key:
tried_sources = list(pconfig.api_key_env_vars)
if provider == "copilot":
Expand All @@ -2233,6 +2238,13 @@ def _wrap_if_needed(client_obj, final_model_str: str, base_url_str: str = "",
base_url = _to_openai_base_url(
str(creds.get("base_url", "")).strip().rstrip("/") or pconfig.inference_base_url
)
# An explicit base_url from a custom_providers fallback entry overrides
# the registered provider's default endpoint. This handles the case
# where the fallback provider name aliases to a built-in (e.g. a custom
# provider named "kimi" resolves to "kimi-coding") but the actual target
# is the user-defined custom endpoint, not the built-in one.
if explicit_base_url:
base_url = _to_openai_base_url(explicit_base_url.strip().rstrip("/"))

default_model = _API_KEY_PROVIDER_AUX_MODELS.get(provider, "")
final_model = _normalize_resolved_model(model or default_model, provider)
Expand Down
1 change: 1 addition & 0 deletions hermes_cli/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def show_status(args):
keys = {
"OpenRouter": "OPENROUTER_API_KEY",
"OpenAI": "OPENAI_API_KEY",
"NVIDIA": "NVIDIA_API_KEY",
"Z.AI/GLM": "GLM_API_KEY",
"Kimi": "KIMI_API_KEY",
"StepFun Step Plan": "STEPFUN_API_KEY",
Expand Down
21 changes: 21 additions & 0 deletions run_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -7365,6 +7365,27 @@ def _try_activate_fallback(self, reason: "FailoverReason | None" = None) -> bool
fb_key_env = (fb.get("key_env") or "").strip()
if fb_key_env:
fb_api_key_hint = os.getenv(fb_key_env, "").strip() or None
# When the fallback entry has no explicit base_url, look up
# custom_providers by the original provider name before any
# alias normalization occurs. Without this, names that alias
# to a built-in provider (e.g. "kimi" → "kimi-coding") bypass
# the custom_providers lookup and inherit the primary provider's
# base_url instead of using the correct custom endpoint.
if not fb_base_url_hint:
try:
from hermes_cli.runtime_provider import _get_named_custom_provider
_cp_entry = _get_named_custom_provider(fb_provider)
if _cp_entry and _cp_entry.get("base_url"):
fb_base_url_hint = _cp_entry["base_url"].strip() or None
if not fb_api_key_hint:
_cp_key = (_cp_entry.get("api_key") or "").strip()
if not _cp_key:
_cp_key_env = (_cp_entry.get("key_env") or "").strip()
if _cp_key_env:
_cp_key = os.getenv(_cp_key_env, "").strip()
fb_api_key_hint = _cp_key or None
except Exception:
pass
# For Ollama Cloud endpoints, pull OLLAMA_API_KEY from env
# when no explicit key is in the fallback config. Host match
# (not substring) — see GHSA-76xc-57q6-vm5m.
Expand Down