fix(aux): honor model.default_headers on auxiliary client too (#40033)

The salvaged main-agent fix (sanidhyasin) applies model.default_headers
to the primary OpenAI client, but the auxiliary client (title generation,
context compression, vision routing) builds its own clients and did not
read the override. For a `provider: custom` endpoint behind a gateway/WAF
that rejects the OpenAI SDK's identifying headers, the main turn would
succeed while auxiliary calls to the same endpoint still failed with the
opaque 502/4xx from #40033.

Add agent.auxiliary_client._apply_user_default_headers() (user values win
over provider/SDK defaults; no-op when unconfigured) and apply it at every
OpenAI-wire client construction site:
- _try_custom_endpoint() — config-level `model.provider: custom`
- the named custom-provider branch (custom_providers/providers entries),
  including the anthropic-SDK-missing OpenAI-wire fallback
- the api-key-provider, async-conversion, and main resolve_provider_client
  fallback branches

To prevent the two clients ever drifting on precedence/value handling,
AIAgent._apply_user_default_headers (run_agent.py) now delegates the config
read + merge to this shared helper (run_agent already imports from
auxiliary_client). Native Anthropic/Bedrock branches are untouched (they
don't use the OpenAI wire).

8 new tests (helper semantics + config-level custom + named custom);
full aux + attribution header suites green (295).
This commit is contained in:
kshitijk4poor 2026-06-07 13:50:06 +05:30 committed by kshitij
parent a216ff839b
commit ffe665277c
3 changed files with 202 additions and 12 deletions

View file

@ -3828,23 +3828,19 @@ class AIAgent:
reach such an upstream instead of failing with an opaque 4xx/502 even
though the same body works under ``curl``. (#40033)
Delegates the config read + merge to
``agent.auxiliary_client._apply_user_default_headers`` so the main and
auxiliary clients can never drift on precedence or value handling.
No-op for Anthropic/Bedrock modes, which don't use the OpenAI client,
and when no overrides are configured.
"""
if self.api_mode in ("anthropic_messages", "bedrock_converse"):
return
try:
from hermes_cli.config import cfg_get, load_config
user_headers = cfg_get(load_config(), "model", "default_headers")
except Exception:
return
if not isinstance(user_headers, dict) or not user_headers:
return
merged = dict(self._client_kwargs.get("default_headers") or {})
for key, value in user_headers.items():
if value is None:
continue
merged[str(key)] = str(value)
from agent.auxiliary_client import (
_apply_user_default_headers as _merge_user_headers,
)
merged = _merge_user_headers(self._client_kwargs.get("default_headers"))
if merged:
self._client_kwargs["default_headers"] = merged