Skip to content

fix(delegation): prevent credential pool from overriding explicit delegation.base_url - #61258

Closed
kyssta-exe wants to merge 1 commit into
NousResearch:mainfrom
kyssta-exe:fix/61195-delegation-base-url-override
Closed

fix(delegation): prevent credential pool from overriding explicit delegation.base_url#61258
kyssta-exe wants to merge 1 commit into
NousResearch:mainfrom
kyssta-exe:fix/61195-delegation-base-url-override

Conversation

@kyssta-exe

Copy link
Copy Markdown
Contributor

Description

Fixes #61195

When delegation.base_url is explicitly configured (e.g. https://api.anthropic.com) while the primary model uses a different provider (e.g. openrouter), the subagent's agent.base_url, agent.provider, and agent.api_mode are correctly resolved to the delegation values throughout init_agent(). However, the credential pool leasing in _run_single_child() could later call _swap_credential(), which overwrites self.base_url (and self._client_kwargs['base_url']) with values from the pool entry — potentially restoring the parent agent's OpenRouter endpoint and causing 401 authentication failures.

Fix

Skip credential pool assignment in _build_child_agent() when override_base_url is set from the delegation config (delegation.base_url). This ensures the explicitly configured endpoint is always honored and never overwritten by a stale pool entry.

Rationale

When the user explicitly configures delegation.base_url, they are directing subagents to a specific endpoint. A credential pool that was loaded for the same provider name (e.g. anthropic) may contain entries with a different runtime_base_url than the one configured in delegation.base_url, because the pool was set up for a different use case (e.g. rate-limiting rotation on the parent's provider).

The credential pool is still available for subagents that inherit the parent's provider (where override_base_url is not set), preserving the rate-limit rotation feature for the default case.

Test Plan

  • pytest tests/tools/test_delegate.py -v
  • pytest tests/tools/test_async_delegation.py -v
  • Manual: configure delegation.base_url to a different provider than the primary model, trigger delegate_task, verify the subagent's API calls go to the configured endpoint

…egation.base_url (NousResearch#61195)

When delegation.base_url is explicitly configured, the child agent's
base_url, provider, and api_mode are correctly resolved to the delegation
values throughout init_agent(). However, the credential pool leasing in
_run_single_child() could later call _swap_credential(), which overwrites
self.base_url (and self._client_kwargs['base_url']) with values from the
pool entry — potentially restoring the parent agent's OpenRouter endpoint
and causing 401 authentication failures.

Fix: skip credential pool assignment when override_base_url is set from
the delegation config, ensuring the explicitly configured endpoint is
always honored.
@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/delegate Subagent delegation P2 Medium — degraded but workaround exists duplicate This issue or pull request already exists labels Jul 9, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #13752 (earliest open PR for this fix). Both skip the child credential-pool binding when override_base_url (from delegation.base_url) is set — the identical guard on the same _resolve_child_credential_pool call in tools/delegate_tool.py, so _swap_credential can't clobber the child's explicit endpoint. Related: #59670 and #39862 fix the same root cause (subagent credential-pool contamination) via a different mechanism (kill-pool-on-any-explicit-override / provider-match guard). Marking this a duplicate of the canonical #13752; maintainers should choose between the guard approaches.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for tracing the credential-pool lease path. This is an automated hermes-sweeper review; current main already prevents the reported OpenRouter-to-Anthropic endpoint retargeting, so this PR is redundant.

  • tools/delegate_tool.py:3061-3063 resolves direct https://api.anthropic.com delegation as provider="anthropic" with anthropic_messages transport.
  • tools/delegate_tool.py:2980-2988 reuses a parent credential pool only for the same provider; otherwise it loads the child's provider-scoped pool. An OpenRouter parent pool cannot therefore be attached to this Anthropic child.
  • tools/delegate_tool.py:1743-1752 leases only the pool already attached to the child.
  • This provider-isolated child-pool behavior and its regression coverage were introduced by f2c11ff30cd5601a4017cae64cbbeac0a481f5c9; current coverage remains at tests/tools/test_delegate.py:1717-1726.
  • The linked report [Bug]: delegation.base_url correctly resolved through init_agent() but subagent's actual API call still routes to OpenRouter → 401 #61195 was also verified and closed against current main on this basis.

The proposed unconditional skip would also remove valid child-provider credential rotation for every explicit direct endpoint.

@teknium1 teknium1 closed this Jul 10, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jul 10, 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 P2 Medium — degraded but workaround exists sweeper:implemented-on-main Sweeper: behavior already present on current main tool/delegate Subagent delegation type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: delegation.base_url correctly resolved through init_agent() but subagent's actual API call still routes to OpenRouter → 401

3 participants