mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-13 14:02:16 +00:00
fix(providers): pass extra headers to model discovery
This commit is contained in:
parent
80a774f972
commit
ab40e952f3
5 changed files with 211 additions and 18 deletions
|
|
@ -23,7 +23,7 @@ from __future__ import annotations
|
|||
import logging
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from typing import List, NamedTuple, Optional
|
||||
from typing import Any, List, NamedTuple, Optional
|
||||
|
||||
from hermes_cli.providers import (
|
||||
ProviderDef,
|
||||
|
|
@ -1362,6 +1362,19 @@ import threading as _threading # noqa: E402
|
|||
_picker_prewarm_done = _threading.Event()
|
||||
|
||||
|
||||
def _extra_headers_from_config(entry: Any) -> dict[str, str]:
|
||||
if not isinstance(entry, dict):
|
||||
return {}
|
||||
headers = entry.get("extra_headers")
|
||||
if not isinstance(headers, dict) or not headers:
|
||||
return {}
|
||||
return {
|
||||
str(key): str(value)
|
||||
for key, value in headers.items()
|
||||
if value is not None
|
||||
}
|
||||
|
||||
|
||||
def prewarm_picker_cache_async() -> Optional["_threading.Thread"]:
|
||||
"""Warm the provider-models disk cache in a background daemon thread.
|
||||
|
||||
|
|
@ -1993,7 +2006,11 @@ def list_authenticated_providers(
|
|||
if should_probe:
|
||||
try:
|
||||
from hermes_cli.models import fetch_api_models
|
||||
live_models = fetch_api_models(api_key, api_url)
|
||||
live_models = fetch_api_models(
|
||||
api_key,
|
||||
api_url,
|
||||
headers=_extra_headers_from_config(ep_cfg) or None,
|
||||
)
|
||||
if live_models:
|
||||
models_list = live_models
|
||||
except Exception:
|
||||
|
|
@ -2130,10 +2147,13 @@ def list_authenticated_providers(
|
|||
"api_key": api_key,
|
||||
"models": [],
|
||||
"discover_models": discover,
|
||||
"extra_headers": _extra_headers_from_config(entry),
|
||||
}
|
||||
else:
|
||||
if api_key and not groups[group_key].get("api_key"):
|
||||
groups[group_key]["api_key"] = api_key
|
||||
if not groups[group_key].get("extra_headers"):
|
||||
groups[group_key]["extra_headers"] = _extra_headers_from_config(entry)
|
||||
# If any entry in this group opts out of discovery,
|
||||
# honour that for the whole grouped row.
|
||||
if not discover:
|
||||
|
|
@ -2240,7 +2260,11 @@ def list_authenticated_providers(
|
|||
try:
|
||||
from hermes_cli.models import fetch_api_models
|
||||
|
||||
live_models = fetch_api_models(api_key, api_url)
|
||||
live_models = fetch_api_models(
|
||||
api_key,
|
||||
api_url,
|
||||
headers=grp.get("extra_headers") or None,
|
||||
)
|
||||
if live_models:
|
||||
grp["models"] = live_models
|
||||
grp["total_models"] = len(live_models)
|
||||
|
|
|
|||
|
|
@ -3451,6 +3451,7 @@ def probe_api_models(
|
|||
base_url: Optional[str],
|
||||
timeout: float = 5.0,
|
||||
api_mode: Optional[str] = None,
|
||||
request_headers: Optional[dict[str, str]] = None,
|
||||
) -> dict[str, Any]:
|
||||
"""Probe a ``/models`` endpoint with light URL heuristics.
|
||||
|
||||
|
|
@ -3497,6 +3498,16 @@ def probe_api_models(
|
|||
headers["Authorization"] = f"Bearer {api_key}"
|
||||
if normalized.startswith(COPILOT_BASE_URL):
|
||||
headers.update(copilot_default_headers())
|
||||
if isinstance(request_headers, dict):
|
||||
# Per-provider custom headers can contain auth/proxy secrets. Merge
|
||||
# last so endpoint-specific config wins, and never log the values.
|
||||
headers.update(
|
||||
{
|
||||
str(key): str(value)
|
||||
for key, value in request_headers.items()
|
||||
if value is not None
|
||||
}
|
||||
)
|
||||
|
||||
for candidate_base, is_fallback in candidates:
|
||||
url = candidate_base.rstrip("/") + "/models"
|
||||
|
|
@ -3529,13 +3540,20 @@ def fetch_api_models(
|
|||
base_url: Optional[str],
|
||||
timeout: float = 5.0,
|
||||
api_mode: Optional[str] = None,
|
||||
headers: Optional[dict[str, str]] = None,
|
||||
) -> Optional[list[str]]:
|
||||
"""Fetch the list of available model IDs from the provider's ``/models`` endpoint.
|
||||
|
||||
Returns a list of model ID strings, or ``None`` if the endpoint could not
|
||||
be reached (network error, timeout, auth failure, etc.).
|
||||
"""
|
||||
return probe_api_models(api_key, base_url, timeout=timeout, api_mode=api_mode).get("models")
|
||||
return probe_api_models(
|
||||
api_key,
|
||||
base_url,
|
||||
timeout=timeout,
|
||||
api_mode=api_mode,
|
||||
request_headers=headers,
|
||||
).get("models")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue