fix: preserve known provider when base_url is set in auxiliary task resolution - #39732
fix: preserve known provider when base_url is set in auxiliary task resolution#39732tino-chen wants to merge 1 commit into
Conversation
|
Independent confirmation of this bug + fix from a separate deployment. We hit the identical issue routing auxiliary vision through a named custom provider (a local OpenAI-compatible router; Isolated it down to the exact two resolution shapes (same key, same request):
Your guard at the I'd independently written the same one-line guard before finding this PR (#47434, now closed in favor of yours). Offering the extra test coverage from it in case it's useful — it asserts a named custom provider ( class TestResolveTaskProviderModelBaseUrlPreservesNamedProvider:
def test_named_custom_provider_preserved_with_base_url(self):
from agent.auxiliary_client import _resolve_task_provider_model
prov, model, base, key, _ = _resolve_task_provider_model(
task="vision", provider="custom:9router-codex",
model="vertex/gemini-2.5-flash",
base_url="http://127.0.0.1:20128/v1", api_key=None,
)
assert prov == "custom:9router-codex"
assert base == "http://127.0.0.1:20128/v1"
def test_anonymous_endpoint_still_collapses_to_custom(self):
from agent.auxiliary_client import _resolve_task_provider_model
for p in (None, "custom", "auto"):
prov, *_ = _resolve_task_provider_model(
task="vision", provider=p, base_url="http://localhost:1234/v1")
assert prov == "custom"Verified on Python 3.11: these fail on |
9d8c09e to
6597a52
Compare
…esolution
When both provider (e.g. 'alibaba') and base_url are configured for an
auxiliary task (vision, compression, etc.), _resolve_task_provider_model
was unconditionally routing to 'custom' whenever base_url was present as
an explicit argument. This caused a double-resolution trap:
1. call_llm resolves once → gets ('alibaba', model, base_url, ...)
2. call_llm passes resolved base_url as explicit arg to
resolve_vision_provider_client
3. resolve_vision_provider_client resolves again with base_url as
explicit arg → provider becomes 'custom'
4. 'custom' path reads OPENAI_API_KEY instead of DASHSCOPE_API_KEY
5. DashScope returns 401 invalid_api_key
Fix: when provider is explicitly set and survived _expand_direct_api_alias
(i.e. it's a known PROVIDER_REGISTRY entry), preserve the provider name
instead of routing to 'custom'. resolve_provider_client already handles
explicit_base_url for known providers correctly.
Added 5 regression tests covering:
- Known provider + base_url preserved
- Auto + base_url → custom (unchanged)
- No provider + base_url → custom (unchanged)
- Direct API alias (e.g. 'openai') → custom (unchanged)
- Config-derived provider + base_url preserved
6597a52 to
d9ef634
Compare
|
@sacwooky Thanks for the detailed confirmation and the additional test cases — really helpful. I've added them to the PR alongside our existing tests: |
MiniMax CN reproduction + validation of this fixJust verified this PR fixes the same bug class for the MiniMax China ( Repro on
|
|
Closing as implemented on main: You were the earliest submitter on this bug and your double-resolution root-cause analysis was spot on. The merged version additionally gates on the provider catalog so unknown provider names still fall back to |
Summary
Fixes a bug where auxiliary tasks (vision, compression, etc.) fail with 401 authentication errors when both
providerandbase_urlare configured for a known provider (e.g.,alibabawith DashScope).Problem
When
auxiliary.visionconfig has bothprovider: alibabaandbase_url: https://dashscope.aliyuncs.com/..., vision calls fail with:Root Cause
A double-resolution trap in
_resolve_task_provider_model:call_llmcalls_resolve_task_provider_modelonce → returns("alibaba", model, base_url, ...)call_llmpasses the resolvedbase_urlas an explicit argument toresolve_vision_provider_clientresolve_vision_provider_clientcalls_resolve_task_provider_modelagain withbase_urlas an explicit argumentbase_urlis present and unconditionally routes to"custom""custom"provider path readsOPENAI_API_KEYinstead ofDASHSCOPE_API_KEYFix
In
_resolve_task_provider_model, when bothprovider(explicit) andbase_url(explicit) are set, preserve the provider name if it's a knownPROVIDER_REGISTRYentry instead of routing to"custom". Theresolve_provider_clientfunction already handlesexplicit_base_urlcorrectly for known providers (line ~3746).Testing
Added 5 regression tests in
TestResolveTaskProviderModelPreservesKnownProvider:All 198 existing tests pass (excluding async tests that require pytest-asyncio plugin).
Impact
This fix resolves authentication failures for users who configure auxiliary tasks with both
providerandbase_urlfor known providers like:alibaba(DashScope)deepseekgeminianthropicThe fix is minimal and backward-compatible: providers not in
PROVIDER_REGISTRY(like"auto","","custom") still route to"custom"as before.Workaround
Until this is merged, users can work around the bug by removing
base_urlfrom theirauxiliary.visionconfig if they haveDASHSCOPE_BASE_URL(or equivalent) set in.env.