Skip to content

fix(auxiliary): keep /anthropic base_url for anthropic_messages custom endpoints - #64891

Closed
AlexanderPrendota wants to merge 1 commit into
NousResearch:mainfrom
JetBrains:fix/aux-anthropic-base-url
Closed

AlexanderPrendota wants to merge 1 commit into
NousResearch:mainfrom
JetBrains:fix/aux-anthropic-base-url

Conversation

@AlexanderPrendota

Copy link
Copy Markdown
Contributor

What does this PR do?

The custom + explicit_base_url branch of resolve_provider_client() (in agent/auxiliary_client.py) rewrote a trailing /anthropic to /v1 via _to_openai_base_url() and then passed that rewritten base to the wrap-decision (_wrap_if_needed_maybe_wrap_anthropic) — even when api_mode was anthropic_messages. The Anthropic wrapper therefore never saw the real /anthropic path, so for any custom provider whose base_url ends in /anthropic (a proxied Anthropic gateway — MiniMax, Zhipu/GLM, a LiteLLM proxy, or a self-hosted LLM proxy) every auxiliary task (title generation, compression, vision, web_extract, session_search) hit .../v1/chat/completions on a Messages-only endpoint and failed.

Fix

Guard the wrap base on api_mode: for api_mode == "anthropic_messages" the Anthropic wrapper is built on the raw /anthropic base, while the plain OpenAI client — and the OpenAI-wire fallback taken when the anthropic SDK is unavailable — still uses the /v1-rewritten base so it never lands on /anthropic/chat/completions. The change is scoped: it adds a wrap_base that equals custom_base on every existing path (including the main_runtime named-custom path) and only differs for the explicit-base anthropic_messages case. Non-anthropic paths are unchanged.

Ships with focused regression tests (tests/agent/test_auxiliary_explicit_base_anthropic.py): raw /anthropic base is preserved for the wrapper, the OpenAI-wire fallback stays on /v1, and the non-anthropic /anthropic/v1 rewrite is untouched.

Related

Root cause: #16254 (duplicate: #17086).

A few open PRs already target the same _to_openai_base_url() /anthropic/v1 rewrite:

How this PR differs: it guards the wrap base in the custom + explicit_base_url branch (the path _resolve_auto Step 1 uses for a custom main provider), and it keeps the /v1 rewrite for the OpenAI-wire fallback so that fallback never lands on /anthropic/chat/completions.

Refs #16254

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

…m endpoints

The custom + explicit_base_url branch of resolve_provider_client()
unconditionally rewrote a trailing /anthropic to /v1 via
_to_openai_base_url(), even when api_mode was anthropic_messages. The
Anthropic wrapper then never saw the real /anthropic path, so auxiliary
tasks (title generation, compression, vision, web_extract,
session_search) hit .../v1/chat/completions on a Messages-only endpoint
and failed.

Guard the wrap base on api_mode: for anthropic_messages, pass the raw
/anthropic base to _wrap_if_needed (which builds the Anthropic wrapper),
while the plain OpenAI client keeps the /v1-rewritten base so the
OpenAI-wire fallback (used when the anthropic SDK is unavailable) never
lands on /anthropic/chat/completions.

Refs NousResearch#16254
@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/config Config system, migrations, profiles P3 Low — cosmetic, nice to have labels Jul 15, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Thanks for the focused regression fix. The premise is confirmed on current main: agent/auxiliary_client.py:4796 rewrites an explicit custom /anthropic URL before agent/auxiliary_client.py:4853 supplies it to _wrap_if_needed. _maybe_wrap_anthropic then passes that supplied URL directly to build_anthropic_client (agent/auxiliary_client.py:1642-1675).

The proposed wrap_base keeps the native Anthropic wrapper on the raw endpoint while preserving the rewritten OpenAI client for the SDK-unavailable fallback. This matches the existing named-custom-provider handling at agent/auxiliary_client.py:4916-4958. The regression tests cover the native wrapper, fallback, and non-Anthropic behavior.

Automated hermes-sweeper review.

@teknium1

Copy link
Copy Markdown
Collaborator

Merged via PR #85466 with your commit cherry-picked onto current main — authorship preserved in git log. The keep-/v1-for-fallback nuance in your version was the cleanest of the cluster fixes for this branch. The sibling paths you enumerated (#60753 vision, #61333 class-wide guard) are being evaluated as one cluster decision on top of this. Thanks!

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

Labels

area/config Config system, migrations, profiles comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P3 Low — cosmetic, nice to have provider/anthropic Anthropic native Messages API sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants