hermes - ✅(Solved) Fix Background Review Agent Fails with Custom Providers (Missing api_key/base_url) [2 pull requests, 1 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#15543Fetched 2026-04-26 05:26:47
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
0
Author
Timeline (top)
labeled ×4cross-referenced ×3commented ×1

Root Cause

In run_agent.py, _spawn_background_review() creates a new AIAgent instance for the background review but only passes the provider name:

review_agent = AIAgent(
    model=self.model,
    max_iterations=8,
    quiet_mode=True,
    platform=self.platform,
    provider=self.provider,
    parent_session_id=self.session_id,
    # ← Missing: api_key, base_url, api_mode
)

The review agent then calls resolve_provider_client(provider_name, ...) which tries to resolve credentials through:

  1. resolve_api_key_provider_credentials() — only works for built-in providers in PROVIDER_REGISTRY
  2. _get_named_custom_provider() — reads from config.yaml's providers: dict, but falls back to os.getenv(key_env) for the API key
  3. If neither works, returns None → raises "No LLM provider configured"

For custom providers where the API key is set via env var (key_env in config.yaml), this works fine because the child thread inherits the environment. But if:

  • The env var is not available in the process environment
  • The credential pool (auth.json) is the only source of credentials

...the review agent fails.

Fix Action

Fixed

PR fix notes

PR #15645: fix(run_agent): forward api_key/base_url/api_mode to background review agent (#15543)

Description (problem / solution / changelog)

Summary

  • _spawn_background_review() now passes api_key, base_url, and api_mode from the parent agent to the review agent constructor
  • Adds 7 regression tests covering credential propagation across provider types

The bug

Custom providers (self-hosted endpoints, proxies) resolve their credentials from config.yaml at AIAgent init time — the resolved api_key and base_url live on the parent instance. When _spawn_background_review() spawned the child agent with only provider=self.provider, the child re-ran credential resolution from scratch. For custom providers not in PROVIDER_REGISTRY, this found nothing and raised:

⚠ Auxiliary background review failed: No LLM provider configured. Run `hermes model` to select a provider, or run `hermes setup` for first-time configuration.

The fix

Three additional kwargs in the AIAgent(...) constructor call inside _run_review():

review_agent = AIAgent(
    model=self.model,
    ...
    api_key=self.api_key,    # ← new: already-resolved credentials
    base_url=self.base_url,  # ← new
    api_mode=self.api_mode,  # ← new
    parent_session_id=self.session_id,
)

The parent's credentials are already fully resolved at this point — no re-resolution needed, and no environment variables or config files need to be consulted again.

Test plan

  • Before: 6/7 credential tests fail without the fix (api_key/base_url/api_mode not in constructor kwargs)
  • After: 7/7 pass
  • Regression guard: reverted the fix → observed AssertionError: assert None == 'sk-custom-key-abcdefgh'; restored → 0 failures
  • Broader suite: tests/run_agent/ — 1058 passed, 1 pre-existing baseline (test_inf_stays_string_for_integer_only fails on clean origin/main)
  • Adjacent tests/run_agent/test_background_review_summary.py — 8 passed

Related

  • Fixes #15543

🤖 Generated with Claude Code

Changed files

  • run_agent.py (modified, +3/-0)
  • tests/run_agent/test_background_review_credentials.py (added, +138/-0)

PR #15884: fix: pass base_url and api_key to background review AIAgent

Description (problem / solution / changelog)

Problem

_spawn_background_review() creates a background review AIAgent without passing base_url or api_key. When the main agent uses a custom or fallback provider (e.g. OpenRouter, Cerebras, SiliconFlow), the review agent cannot:

  1. Look up per-model context overrides from custom_providers (which requires base_url to match)
  2. Query custom endpoint /models APIs for context length detection

This causes the review agent to fall through to live API detection, which may return the model's real context window and trigger the MINIMUM_CONTEXT_LENGTH (64K) guard — silently killing the review thread.

Fix

Pass base_url and api_key through to the review AIAgent constructor so it inherits the same provider configuration as the main agent.

Testing

  • python3 -m py_compile run_agent.py — passes
  • python3 -m pytest tests/run_agent/test_background_review_summary.py -v — 8/8 passed
  • Verified the fix is present via inspect.getsource(AIAgent._spawn_background_review)

Closes #15882

Changed files

  • run_agent.py (modified, +2/-0)

Code Example

Auxiliary background review failed: No LLM provider configured. Run `hermes model` to select a provider, or run `hermes setup` for first-time configuration.

---

review_agent = AIAgent(
    model=self.model,
    max_iterations=8,
    quiet_mode=True,
    platform=self.platform,
    provider=self.provider,
    parent_session_id=self.session_id,
    # ← Missing: api_key, base_url, api_mode
)

---

review_agent = AIAgent(
    model=self.model,
    max_iterations=8,
    quiet_mode=True,
    platform=self.platform,
    provider=self.provider,
    api_key=self.api_key,           # ← pass resolved credentials
    base_url=self.base_url,         # ← pass resolved base URL
    api_mode=getattr(self, "api_mode", None),  # ← pass API mode
    parent_session_id=self.session_id,
)

---

model:
     provider: my-custom-provider
   providers:
     my-custom-provider:
       key_env: CUSTOM_API_KEY
       base_url: https://example.com/v1
RAW_BUFFERClick to expand / collapse

Background Review Agent Fails with Custom Providers (Missing api_key/base_url)

Describe the bug

When using a custom provider defined in config.yaml (e.g. a self-hosted endpoint or a provider not in the built-in PROVIDER_REGISTRY), the background review agent fails with:

⚠ Auxiliary background review failed: No LLM provider configured. Run `hermes model` to select a provider, or run `hermes setup` for first-time configuration.

Root Cause

In run_agent.py, _spawn_background_review() creates a new AIAgent instance for the background review but only passes the provider name:

review_agent = AIAgent(
    model=self.model,
    max_iterations=8,
    quiet_mode=True,
    platform=self.platform,
    provider=self.provider,
    parent_session_id=self.session_id,
    # ← Missing: api_key, base_url, api_mode
)

The review agent then calls resolve_provider_client(provider_name, ...) which tries to resolve credentials through:

  1. resolve_api_key_provider_credentials() — only works for built-in providers in PROVIDER_REGISTRY
  2. _get_named_custom_provider() — reads from config.yaml's providers: dict, but falls back to os.getenv(key_env) for the API key
  3. If neither works, returns None → raises "No LLM provider configured"

For custom providers where the API key is set via env var (key_env in config.yaml), this works fine because the child thread inherits the environment. But if:

  • The env var is not available in the process environment
  • The credential pool (auth.json) is the only source of credentials

...the review agent fails.

Proposed Fix

Pass the main agent's resolved credentials to the review agent:

review_agent = AIAgent(
    model=self.model,
    max_iterations=8,
    quiet_mode=True,
    platform=self.platform,
    provider=self.provider,
    api_key=self.api_key,           # ← pass resolved credentials
    base_url=self.base_url,         # ← pass resolved base URL
    api_mode=getattr(self, "api_mode", None),  # ← pass API mode
    parent_session_id=self.session_id,
)

This ensures the review agent uses the same client configuration as the main agent, regardless of whether credentials come from env vars, auth.json credential pool, OAuth tokens, or custom config.

Steps to Reproduce

  1. Configure a custom provider in config.yaml:

    model:
      provider: my-custom-provider
    providers:
      my-custom-provider:
        key_env: CUSTOM_API_KEY
        base_url: https://example.com/v1
  2. Set the API key only via ~/.hermes/.env or auth.json credential pool (NOT in the shell environment where gateway runs)

  3. Start the gateway and send a message

  4. Observe: Main agent works fine, but background review fails with "No LLM provider configured"

Environment

  • Hermes Agent: v0.11.0
  • Python: 3.11.15
  • OS: Linux (aarch64)

Impact

  • Background memory/skill review is silently broken for users with custom providers when credentials aren't available as plain environment variables
  • This affects any deployment where API keys are sourced from .env files or credential pools rather than exported env vars

extent analysis

TL;DR

Pass the main agent's resolved credentials to the review agent to ensure it uses the same client configuration.

Guidance

  • Verify that the api_key and base_url are being passed correctly to the AIAgent instance in run_agent.py.
  • Check the config.yaml file to ensure that the custom provider is correctly defined with the key_env and base_url parameters.
  • Test the fix by setting the API key via ~/.hermes/.env or auth.json credential pool and verifying that the background review agent works as expected.
  • Review the resolve_provider_client function to ensure it correctly resolves credentials for custom providers.

Example

review_agent = AIAgent(
    model=self.model,
    max_iterations=8,
    quiet_mode=True,
    platform=self.platform,
    provider=self.provider,
    api_key=self.api_key,           # pass resolved credentials
    base_url=self.base_url,         # pass resolved base URL
    api_mode=getattr(self, "api_mode", None),  # pass API mode
    parent_session_id=self.session_id,
)

Notes

This fix assumes that the api_key and base_url are being resolved correctly in the main agent. If issues persist, further debugging may be required to identify the root cause.

Recommendation

Apply the proposed fix by passing the main agent's resolved credentials to the review agent, as this ensures that the review agent uses the same client configuration as the main agent.

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 Background Review Agent Fails with Custom Providers (Missing api_key/base_url) [2 pull requests, 1 comments, 2 participants]