Skip to content

fix(auxiliary): gate Anthropic base_url override on Anthropic-compatible host (#52608) - #52623

Closed
Tranquil-Flow wants to merge 1 commit into
NousResearch:mainfrom
Tranquil-Flow:fix/52608-aux-anthropic-base-url
Closed

fix(auxiliary): gate Anthropic base_url override on Anthropic-compatible host (#52608)#52623
Tranquil-Flow wants to merge 1 commit into
NousResearch:mainfrom
Tranquil-Flow:fix/52608-aux-anthropic-base-url

Conversation

@Tranquil-Flow

Copy link
Copy Markdown
Contributor

Summary

agent/auxiliary_client.py::_try_anthropic() unconditionally applies cfg["model"]["base_url"] as the auxiliary Anthropic base_url whenever cfg["model"]["provider"] == "anthropic" — even when that URL points at a different provider's endpoint (e.g. OpenRouter, OpenAI).

When operators run with:

model:
  provider: anthropic
  base_url: https://openrouter.ai/api/v1

…the main session works (main code path attaches the right key), but every auxiliary call (memory-provider extractors, reflection extractors, title-generation, vision passes, session-search) hits the override path and sends ANTHROPIC_API_KEY to the foreign host, which rejects it with 401 Missing Authentication header.

Fix

Add a hostname validation gate (_is_anthropic_compatible_host()) before applying the config override. Only api.anthropic.com (and its path variants) are treated as safe Anthropic-compatible endpoints. Non-Anthropic hosts fall back to _ANTHROPIC_DEFAULT_BASE_URL.

Test plan

  • 5 regression tests in test_auxiliary_client_base_url_host_validation_52608.py — all pass with fix
  • 2 tests fail without the fix on upstream/main (RED proven): OpenRouter leak + OpenAI leak
  • 225 existing test_auxiliary_client.py tests pass — no regressions
  • Edge cases: empty base_url, Anthropic default host preserved, Anthropic host with path suffix preserved
python3 -m pytest tests/agent/test_auxiliary_client_base_url_host_validation_52608.py -v -o addopts=
# 5 passed

Fixes #52608

Auto-published by Moonsong via Path B automated pipeline.

…ble host (NousResearch#52608)

When operator config has provider=anthropic with model.base_url pointing
at a non-Anthropic host (e.g. https://openrouter.ai/api/v1 with provider=anthropic),
the auxiliary Anthropic path was unconditionally applying that override.
Main-session traffic routed correctly because the main path attaches the
right credential for the actual destination, but every side-channel call
(memory extractors, reflection, vision, title generation, janus
extractor/promise) sent ANTHROPIC_API_KEY to the foreign host and 401'd.

Gate the override on hostname == api.anthropic.com. Operators routing main
through a non-Anthropic provider must use that provider's own auxiliary
client; the Anthropic aux path now stays pointed at api.anthropic.com.

Regression tests cover openrouter, openai, anthropic-with-path, empty, and
anthropic-default-base_url cases.
@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/anthropic Anthropic native Messages API area/auth Authentication, OAuth, credential pools P2 Medium — degraded but workaround exists labels Jun 25, 2026
@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Salvaged into #52891 (rebased onto current main, 101 commits ahead — cherry-pick applied cleanly). All credit to @Tranquil-Flow for the original fix. Thanks for the contribution!

Note: PR #52888 (AUTHOR_MAP chore) must merge first — it adds the Tranquil-Flow email mappings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists provider/anthropic Anthropic native Messages API type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

auxiliary_client: _try_anthropic() misroutes side-channel calls when main config has provider=anthropic with a non-Anthropic base_url

3 participants