hermes - ✅(Solved) Fix Bug: custom_providers not working with auxiliary tasks — custom: prefix stripped by _normalize_aux_provider [1 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#13762Fetched 2026-04-22 08:04:16
View on GitHub
Comments
2
Participants
2
Timeline
7
Reactions
0
Author
Participants
Timeline (top)
labeled ×3commented ×2cross-referenced ×2

When configuring custom_providers in config.yaml for use with auxiliary tasks (session_search, compression, title_generation, etc.), the custom: provider prefix is stripped by _normalize_aux_provider(), making named custom providers unreachable.

Root Cause

In agent/auxiliary_client.py, the function _normalize_aux_provider() converts the provider string to lowercase for matching:

normalized = (provider or "auto").strip().lower()

This strips the custom: prefix distinction. For example, custom:GLM-Aux becomes custom:glm-aux.

However, in hermes_cli/runtime_provider.py, the function _get_named_custom_provider() requires the exact custom: prefixed string to look up named custom providers from the config. Since _normalize_aux_provider returns the lowercased string without preserving the custom: prefix as a recognized category, the downstream code cannot match it to any named custom provider entry.

The result: auxiliary tasks silently fall through to a broken fallback path and fail.

Fix Action

Workaround

Patch _normalize_aux_provider() in auxiliary_client.py to preserve the custom: prefix:

normalized = (provider or "auto").strip().lower()
# Preserve custom: prefix so runtime_provider can match named custom providers
if (provider or "").strip().lower().startswith("custom:"):
    return normalized

PR fix notes

PR #13781: fix(auxiliary): preserve 'custom:' prefix in _normalize_aux_provider (Closes #13762)

Description (problem / solution / changelog)

Summary

When _normalize_aux_provider() was given custom:GLM-Aux, it stripped the custom: prefix and returned just glm-aux. The downstream _get_named_custom_provider() checks startswith("custom:"), so named custom providers defined in config.yaml were unreachable for auxiliary tasks.

Fix

Return f"custom:{suffix}" (preserving the prefix) instead of normalized = suffix (which drops it). The suffix is already lowercased by .strip().lower() so behavior is unchanged.

Changes

  • agent/auxiliary_client.py: In _normalize_aux_provider(), return f"custom:{suffix}" instead of reassigning normalized = suffix

How it works

_get_named_custom_provider receives custom:glm-aux → skips the AuthError path (not a built-in) → goes on to match against f"custom:{name_norm}" entries from config.yaml.

Closes #13762

Changed files

  • agent/auxiliary_client.py (modified, +4/-1)

Code Example

normalized = (provider or "auto").strip().lower()

---

custom_providers:
  - name: MyProvider
    base_url: https://example.com/v1
    key_env: MY_API_KEY
    model: some-model

---

auxiliary:
  session_search:
    provider: custom:MyProvider
    model: some-model
    timeout: 30

---

normalized = (provider or "auto").strip().lower()
# Preserve custom: prefix so runtime_provider can match named custom providers
if (provider or "").strip().lower().startswith("custom:"):
    return normalized
RAW_BUFFERClick to expand / collapse

Description

When configuring custom_providers in config.yaml for use with auxiliary tasks (session_search, compression, title_generation, etc.), the custom: provider prefix is stripped by _normalize_aux_provider(), making named custom providers unreachable.

Environment

  • Hermes Agent version: latest (post v0.6)
  • OS: macOS (M4)
  • Config: custom_providers with alternative base_url (coding-specific API endpoint)

Root Cause

In agent/auxiliary_client.py, the function _normalize_aux_provider() converts the provider string to lowercase for matching:

normalized = (provider or "auto").strip().lower()

This strips the custom: prefix distinction. For example, custom:GLM-Aux becomes custom:glm-aux.

However, in hermes_cli/runtime_provider.py, the function _get_named_custom_provider() requires the exact custom: prefixed string to look up named custom providers from the config. Since _normalize_aux_provider returns the lowercased string without preserving the custom: prefix as a recognized category, the downstream code cannot match it to any named custom provider entry.

The result: auxiliary tasks silently fall through to a broken fallback path and fail.

Steps to Reproduce

  1. Define a custom provider in config.yaml:
custom_providers:
  - name: MyProvider
    base_url: https://example.com/v1
    key_env: MY_API_KEY
    model: some-model
  1. Configure auxiliary tasks to use it:
auxiliary:
  session_search:
    provider: custom:MyProvider
    model: some-model
    timeout: 30
  1. Restart gateway and trigger session_search — it fails with authentication/connection errors because the custom provider is never resolved.

Workaround

Patch _normalize_aux_provider() in auxiliary_client.py to preserve the custom: prefix:

normalized = (provider or "auto").strip().lower()
# Preserve custom: prefix so runtime_provider can match named custom providers
if (provider or "").strip().lower().startswith("custom:"):
    return normalized

Expected Fix

_normalize_aux_provider() should recognize and preserve custom:-prefixed provider strings, or the downstream _get_named_custom_provider() should handle the normalized (lowercased) name without requiring the custom: prefix.

Additional Note

There is a secondary issue: _resolve_task_provider_model() checks cfg_base_url before cfg_provider, meaning if a user sets both base_url and provider: custom:XXX in an auxiliary block, the base_url takes priority and the custom provider lookup is bypassed entirely. This should be documented or the priority reversed.

extent analysis

TL;DR

The most likely fix is to patch _normalize_aux_provider() to preserve the custom: prefix or modify _get_named_custom_provider() to handle lowercased names without the prefix.

Guidance

  • Verify the issue by checking if the custom provider is correctly defined in config.yaml and if the custom: prefix is being stripped by _normalize_aux_provider().
  • Apply the provided workaround by patching _normalize_aux_provider() to preserve the custom: prefix.
  • Consider modifying _get_named_custom_provider() to handle lowercased names without the custom: prefix for a more robust solution.
  • Review the priority of cfg_base_url and cfg_provider in _resolve_task_provider_model() to ensure custom provider lookups are not bypassed.

Example

# Patched _normalize_aux_provider() function
def _normalize_aux_provider(provider):
    normalized = (provider or "auto").strip().lower()
    if normalized.startswith("custom:"):
        return "custom:" + normalized[7:]  # Preserve custom: prefix
    return normalized

Notes

The provided workaround may not be the final solution, and further modifications may be needed to ensure correct functionality. Additionally, the secondary issue with _resolve_task_provider_model() should be addressed to prevent custom provider lookups from being bypassed.

Recommendation

Apply the workaround by patching _normalize_aux_provider() to preserve the custom: prefix, as it provides a temporary solution to the issue. A more robust solution would involve modifying _get_named_custom_provider() to handle lowercased names without the prefix.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix Bug: custom_providers not working with auxiliary tasks — custom: prefix stripped by _normalize_aux_provider [1 pull requests, 2 comments, 2 participants]