Skip to content

[Bug]: Gateway and CLI ignore model.provider config — fall back to OpenRouter when OPENROUTER_API_KEY exists #5358

@MillionthOdin16

Description

@MillionthOdin16

Problem

When running Hermes via the gateway (Discord/Telegram) or CLI, the agent ignores the explicitly configured model.provider and model.base_url in config.yaml and routes all requests through OpenRouter if OPENROUTER_API_KEY is present in the environment.

This causes unexpected billing on OpenRouter even when the user has configured a different provider (e.g., MiniMax, Ollama Cloud, Anthropic) and never intended to use OpenRouter.

Root Cause

In gateway/run.py, _resolve_runtime_agent_kwargs() calls:

runtime = resolve_runtime_provider(
    requested=os.getenv("HERMES_INFERENCE_PROVIDER"),
)

This passes only the env var — not the config's model.provider. When HERMES_INFERENCE_PROVIDER is unset, resolve_runtime_provider() defaults to "auto", which eventually falls through to _resolve_openrouter_runtime() at runtime_provider.py:727-733.

The _resolve_openrouter_runtime() function only respects model.base_url when model.provider is "auto" or "custom":

if requested_norm == "auto":
    if not cfg_provider or cfg_provider == "auto":
        use_config_base_url = True

If the user has configured model.provider: minimax (or any specific provider), the config base_url is ignored and OpenRouter is used instead.

The CLI has the same bug at cli.py:1220-2077 — it checks CLI_CONFIG["model"].get("provider") but still passes requested="auto" to resolve_runtime_provider() when no env var is set, triggering the same fallback path.

Reproduction

  1. Configure Hermes with a non-OpenRouter provider:
model:
  base_url: https://api.minimax.io/anthropic
  default: MiniMax-M2.7
  provider: minimax
  1. Ensure OPENROUTER_API_KEY is set in ~/.hermes/.env (from a previous config or fresh key)
  2. Start the gateway: hermes gateway (or use CLI: hermes chat)
  3. Send a message via Discord/Telegram (or chat in CLI)
  4. Expected: Requests go to api.minimax.io using MiniMax-M2.7
  5. Actual: Requests go to openrouter.ai — model may be auto-selected (e.g., GLM-5), and OpenRouter credits are consumed

Impact

  • Severity: High — users unknowingly billed for API calls when they configured a different provider
  • Affected users: Anyone using the gateway or CLI with a non-OpenRouter provider who also has OPENROUTER_API_KEY in their environment
  • Financial impact: Direct — unexpected API charges on OpenRouter

Related Issues

Proposed Fix

gateway/run.py:_resolve_runtime_agent_kwargs() and CLI initialization should read model.provider and model.base_url from config and pass them as explicit overrides to resolve_runtime_provider():

def _resolve_runtime_agent_kwargs() -> dict:
    from hermes_cli.runtime_provider import resolve_runtime_provider, format_runtime_provider_error
    from hermes_cli.config import load_config
    
    config = load_config()
    model_cfg = config.get("model", {})
    
    # Use config provider/base_url if HERMES_INFERENCE_PROVIDER not set
    env_provider = os.getenv("HERMES_INFERENCE_PROVIDER")
    if env_provider:
        requested = env_provider
        explicit_base_url = None
    else:
        requested = model_cfg.get("provider", "auto")
        explicit_base_url = model_cfg.get("base_url")
    
    try:
        runtime = resolve_runtime_provider(
            requested=requested,
            explicit_base_url=explicit_base_url,
        )
    except Exception as exc:
        raise RuntimeError(format_runtime_provider_error(exc)) from exc
    
    return {
        "api_key": runtime.get("api_key"),
        "base_url": runtime.get("base_url"),
        "provider": runtime.get("provider"),
        "api_mode": runtime.get("api_mode"),
        "command": runtime.get("command"),
        "args": list(runtime.get("args") or []),
        "credential_pool": runtime.get("credential_pool"),
    }

This ensures the gateway respects model.provider config before falling back to auto-detection.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existsarea/configConfig system, migrations, profilescomp/cliCLI entry point, hermes_cli/, setup wizardcomp/gatewayGateway runner, session dispatch, deliveryprovider/openrouterOpenRouter aggregatortype/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