fix(delegation): preserve configured_provider name when runtime returns 'custom'

Named custom providers (e.g. crof.ai) resolve to provider='custom' at the
runtime level, causing subagents to lose their intended provider identity.
On retry/fallback, resolve_provider_client('custom', model=...) searches all
providers advertising that model and picks non-deterministically, routing to
Z.AI or Bailian instead of the configured target.

The fix preserves configured_provider when runtime['provider'] == 'custom',
restoring the original provider name so routing stays correct through retries.
Adds a named constant _RUNTIME_PROVIDER_CUSTOM instead of a magic string.

Adds three regression tests:
- test_named_custom_provider_preserves_provider_name: the #26954 case
- test_standard_provider_not_overwritten_by_configured_name: openrouter/nous
  must still return their own identity, not the configured name
- test_custom_provider_with_empty_configured_provider_falls_back_to_runtime:
  empty provider triggers the early-return None path as before
This commit is contained in:
Mind-Dragon 2026-05-16 16:28:40 +02:00 committed by Teknium
parent 08a66b2ae3
commit 84667cbc21
2 changed files with 71 additions and 1 deletions

View file

@ -31,6 +31,11 @@ from concurrent.futures import (
from typing import Any, Dict, List, Optional
from toolsets import TOOLSETS
# Sentinel value used by the runtime provider system for providers that are
# not natively known (named custom providers, third-party aggregators, etc.).
# Must match hermes_cli.runtime_provider.RUNTIME_PROVIDER_TYPE_CUSTOM.
_RUNTIME_PROVIDER_CUSTOM = "custom"
from tools import file_state
from tools.terminal_tool import set_approval_callback as _set_subagent_approval_cb
from utils import base_url_hostname, is_truthy_value
@ -2442,7 +2447,7 @@ def _resolve_delegation_credentials(cfg: dict, parent_agent) -> dict:
return {
"model": configured_model or runtime.get("model") or None,
"provider": runtime.get("provider"),
"provider": configured_provider if runtime.get("provider") == _RUNTIME_PROVIDER_CUSTOM else runtime.get("provider"),
"base_url": runtime.get("base_url"),
"api_key": api_key,
"api_mode": runtime.get("api_mode"),