Skip to content

fix(auxiliary): preserve provider when base_url is passed explicitly - #53688

Closed
rmichelena wants to merge 1 commit into
NousResearch:mainfrom
rmichelena:fix/vision-provider-key-resolution
Closed

fix(auxiliary): preserve provider when base_url is passed explicitly#53688
rmichelena wants to merge 1 commit into
NousResearch:mainfrom
rmichelena:fix/vision-provider-key-resolution

Conversation

@rmichelena

Copy link
Copy Markdown

Fix: preserve provider when base_url is passed explicitly

Fixes #53687

Problem

_resolve_task_provider_model() forces the provider to "custom" whenever base_url is passed as an explicit argument — even when a real provider name ("zai", "openrouter", etc.) was also provided. This causes credential resolution to fail because resolve_provider_client("custom", ...) doesn't know about provider-specific env vars (ZAI_API_KEY, OPENROUTER_API_KEY, etc.) and falls back to "no-key-required", producing 401 errors on every call.

Root Cause

The explicit-args path and the config-based path handle base_url differently:

# BUG — explicit args path (line 5189):
if base_url:
    return "custom", resolved_model, base_url, api_key, resolved_api_mode

# CORRECT — config path (line 5199):
if cfg_base_url and cfg_provider and cfg_provider != "auto":
    return cfg_provider, resolved_model, cfg_base_url, None, resolved_api_mode

The config path correctly preserves cfg_provider when cfg_base_url is set. The explicit path doesn't.

This matters because resolve_vision_provider_client() internally re-calls _resolve_task_provider_model() with explicit args (provider + base_url), which triggers the buggy path:

  1. Config sets provider: zai, base_url: https://api.z.ai/..._resolve_task_provider_model("vision") returns ("zai", model, base_url, None, None)
  2. resolve_vision_provider_client(provider="zai", base_url="https://...", api_key=None) re-calls _resolve_task_provider_model("vision", "zai", ..., base_url="https://...", None) with explicit args
  3. The explicit base_url branch returns ("custom", ...) instead of ("zai", ...)bug
  4. resolve_provider_client("custom", ...)api_key = "no-key-required"401

Fix

Make the explicit-args base_url branch preserve the provider name when one is given (and it's not "auto" or "custom"), mirroring the existing config-based logic:

if base_url:
    if provider and provider not in {"", "auto", "custom"}:
        return provider, resolved_model, base_url, api_key, resolved_api_mode
    return "custom", resolved_model, base_url, api_key, resolved_api_mode

Verification

Tested with ZAI/GLM provider:

  • Before: vision_analyze401: token expired or incorrect (client created with api_key='no-key-required')
  • After: vision_analyze → works correctly (client created with real API key from GLM_API_KEY)
# Before fix:
_resolve_task_provider_model("vision", "zai", "glm-4.6V", "https://api.z.ai/api/coding/paas/v4", None)
→ ("custom", "glm-4.6V", "https://...", None, None)  # ← credentials lost

# After fix:
→ ("zai", "glm-4.6V", "https://...", None, None)  # ← credentials resolved from env

Also updated the docstring to accurately reflect the new behavior.

When _resolve_task_provider_model receives both an explicit provider and
base_url, it was forcing the provider to "custom" — losing the ability to
resolve credentials from provider-specific env vars (ZAI_API_KEY,
OPENROUTER_API_KEY, etc.). The resulting client used 'no-key-required'
and every vision call returned 401.

The config-based path (cfg_base_url + cfg_provider) already had the
correct logic. This fixes the explicit-args path to match.
@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 tool/vision Vision analysis and image generation P3 Low — cosmetic, nice to have duplicate This issue or pull request already exists labels Jun 27, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #16727 (earliest-open canonical) — this is one of several open PRs fixing the same _resolve_task_provider_model() force-to-custom bug (#16727, #39732, #49545, #45330), all preserving the named provider when base_url is set. Same approach as the cluster; flagging for a maintainer to pick the canonical one. Fixes #53687.

@teknium1

teknium1 commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Closing as implemented on main: _preserve_provider_with_base_url() landed in commit a8841e2 (PR #55605, merged Jun 30) and handles the explicit provider + explicit base_url case — first-class providers keep their identity; bare/custom/unknown providers still route through custom. Verified E2E on current main. @tino-chen's #39732 was the earliest report of this bug. Thanks for the contribution!

@teknium1 teknium1 closed this Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have tool/vision Vision analysis and image generation type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: auxiliary vision (and other tasks) get 401 when provider + base_url both set in config

3 participants