Skip to content

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

@simanho88

Description

@simanho88

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existsarea/authAuthentication, OAuth, credential poolscomp/agentCore agent loop, run_agent.py, prompt buildertype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions