Skip to content

fix(fallback): let custom_providers shadow built-in aliases#18185

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-b1a3d770
May 1, 2026
Merged

fix(fallback): let custom_providers shadow built-in aliases#18185
teknium1 merged 1 commit into
mainfrom
hermes/hermes-b1a3d770

Conversation

@teknium1

@teknium1 teknium1 commented May 1, 2026

Copy link
Copy Markdown
Contributor

Summary

When a user defines a custom_providers entry whose name coincidentally matches a built-in alias (e.g. kimikimi-coding), the built-in alias rewriting was hijacking the request before the named-custom lookup ran, so the custom endpoint was unreachable. Fallback activation in particular would silently drop the custom fallback and leave the primary provider's base_url in place.

Fixed at the shared resolution layer so every caller benefits — _try_activate_fallback, resolve_provider_client from auxiliary routing, and _resolve_named_custom_runtime for main provider resolution — not just the fallback path.

Changes

  • hermes_cli/runtime_provider.py_get_named_custom_provider's built-in-wins guard now only fires for canonical provider names (nous, openrouter, …). Raw names that are aliases to a different canonical (kimikimi-coding) no longer block the custom lookup.
  • agent/auxiliary_client.pyresolve_provider_client tries the named-custom lookup with the original (pre-alias-normalization) name before the normalized one. Also honours explicit_base_url / explicit_api_key in the API-key branch so callers that pass explicit hints can override the registered defaults.
  • tests/ — 5 new tests covering: custom kimi shadowing built-in alias, custom nous NOT shadowing canonical (behaviour preserved), bare kimi without custom still routing to built-in, explicit overrides on the API-key branch.

Validation

Scenario Before After
Custom kimi → falls back Routes to built-in api.moonshot.ai Routes to user's custom endpoint
Custom aliyun-singapore → falls back Routes to user's custom endpoint (already worked) Same
Canonical nous with shadow custom Built-in Nous Portal wins Same (unchanged)
Bare kimi without any custom entry Built-in kimi-coding wins Same (unchanged)

Full relevant test suite: tests/hermes_cli/test_runtime_provider_resolution.py + tests/hermes_cli/test_user_providers_model_switch.py + tests/agent/test_auxiliary_named_custom_providers.py167 passed.

Credit

Original PR #17827 by @Feranmi10 identified the same bug class and implemented a narrower fix in _try_activate_fallback. This reshapes the fix to live in the shared resolution layer so all callers benefit; Feranmi10 is credited via Co-authored-by:.

Fixes #15743
Closes #17827

Comment thread agent/auxiliary_client.py Dismissed
Comment thread agent/auxiliary_client.py Dismissed
@alt-glitch alt-glitch added area/config Config system, migrations, profiles comp/agent Core agent loop, run_agent.py, prompt builder comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working labels May 1, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #16342 (same builtin-alias-guard reorder) and #17498 (codex alias fix). This PR provides a comprehensive fix covering all alias-shadowing cases.

When a user defines `custom_providers: [{name: kimi, ...}]` and references
`provider: kimi` from fallback_model or the main config, the built-in alias
rewriting (`kimi` → `kimi-coding`) was hijacking the request before the
named-custom lookup ran.  `_get_named_custom_provider` also refused to
return a match when the raw name resolved to any built-in (including aliases),
so the custom endpoint was unreachable.

Fix at both layers of the resolution chain so every caller benefits, not
just `_try_activate_fallback`:

- hermes_cli/runtime_provider.py: narrow `_get_named_custom_provider`'s
  built-in-wins guard to canonical provider names only.  An alias like
  `kimi` that resolves to a different canonical (`kimi-coding`) no longer
  blocks the custom lookup; a canonical name like `nous` still does.

- agent/auxiliary_client.py: in `resolve_provider_client`, try the named-
  custom lookup with the original (pre-alias-normalization) name before the
  alias-normalized one, so aliased requests reach the user's custom entry.
  Also honour `explicit_base_url` and `explicit_api_key` in the API-key
  provider branch so callers that pass explicit hints (e.g. fallback
  activation) can override the registered defaults.

Tests added for:
- custom `kimi` shadowing built-in alias (regression for #15743)
- custom `nous` NOT shadowing canonical built-in (behaviour preserved)
- bare `kimi` without any custom entry still routing to built-in
- explicit base_url/api_key override on the API-key provider branch

Original PR #17827 by @Feranmi10 identified the same bug class and
implemented a narrower fix in `_try_activate_fallback`; this reshapes the
fix to live in the shared resolution layer so all callers benefit.

Fixes #15743
Co-authored-by: Feranmi10 <89228157+Feranmi10@users.noreply.github.com>
@teknium1 teknium1 force-pushed the hermes/hermes-b1a3d770 branch from 72c7132 to 8097c4d Compare May 1, 2026 03:18
@teknium1 teknium1 merged commit 0ddc8ab into main May 1, 2026
4 checks passed
@teknium1 teknium1 deleted the hermes/hermes-b1a3d770 branch May 1, 2026 03:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/agent Core agent loop, run_agent.py, prompt builder comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fallback provider defined in custom_providers ignores its own base_url, sends request to primary provider's endpoint instead

3 participants