fix(auxiliary): keep /anthropic base_url for anthropic_messages custom endpoints - #64891
AlexanderPrendota wants to merge 1 commit into
Conversation
…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
|
Thanks for the focused regression fix. The premise is confirmed on current main: The proposed Automated hermes-sweeper review. |
|
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! |
What does this PR do?
The
custom+explicit_base_urlbranch ofresolve_provider_client()(inagent/auxiliary_client.py) rewrote a trailing/anthropicto/v1via_to_openai_base_url()and then passed that rewritten base to the wrap-decision (_wrap_if_needed→_maybe_wrap_anthropic) — even whenapi_modewasanthropic_messages. The Anthropic wrapper therefore never saw the real/anthropicpath, so for anycustomprovider whosebase_urlends 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/completionson a Messages-only endpoint and failed.Fix
Guard the wrap base on
api_mode: forapi_mode == "anthropic_messages"the Anthropic wrapper is built on the raw/anthropicbase, while the plain OpenAI client — and the OpenAI-wire fallback taken when theanthropicSDK is unavailable — still uses the/v1-rewritten base so it never lands on/anthropic/chat/completions. The change is scoped: it adds awrap_basethat equalscustom_baseon every existing path (including themain_runtimenamed-custom path) and only differs for the explicit-baseanthropic_messagescase. Non-anthropic paths are unchanged.Ships with focused regression tests (
tests/agent/test_auxiliary_explicit_base_anthropic.py): raw/anthropicbase is preserved for the wrapper, the OpenAI-wire fallback stays on/v1, and the non-anthropic/anthropic→/v1rewrite is untouched.Related
Root cause: #16254 (duplicate: #17086).
A few open PRs already target the same
_to_openai_base_url()/anthropic→/v1rewrite:api_modeisanthropic_messages(closest to this PR)/anthropicbase_url for the custom vision provider withanthropic_messages/apps/anthropicHow this PR differs: it guards the wrap base in the
custom+explicit_base_urlbranch (the path_resolve_autoStep 1 uses for acustommain provider), and it keeps the/v1rewrite for the OpenAI-wire fallback so that fallback never lands on/anthropic/chat/completions.Refs #16254
Type of Change