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
- Configure Hermes with a non-OpenRouter provider:
model:
base_url: https://api.minimax.io/anthropic
default: MiniMax-M2.7
provider: minimax
- Ensure
OPENROUTER_API_KEY is set in ~/.hermes/.env (from a previous config or fresh key)
- Start the gateway:
hermes gateway (or use CLI: hermes chat)
- Send a message via Discord/Telegram (or chat in CLI)
- Expected: Requests go to
api.minimax.io using MiniMax-M2.7
- 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.
Problem
When running Hermes via the gateway (Discord/Telegram) or CLI, the agent ignores the explicitly configured
model.providerandmodel.base_urlinconfig.yamland routes all requests through OpenRouter ifOPENROUTER_API_KEYis 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:This passes only the env var — not the config's
model.provider. WhenHERMES_INFERENCE_PROVIDERis unset,resolve_runtime_provider()defaults to"auto", which eventually falls through to_resolve_openrouter_runtime()atruntime_provider.py:727-733.The
_resolve_openrouter_runtime()function only respectsmodel.base_urlwhenmodel.provideris"auto"or"custom":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 checksCLI_CONFIG["model"].get("provider")but still passesrequested="auto"toresolve_runtime_provider()when no env var is set, triggering the same fallback path.Reproduction
OPENROUTER_API_KEYis set in~/.hermes/.env(from a previous config or fresh key)hermes gateway(or use CLI:hermes chat)api.minimax.iousing MiniMax-M2.7openrouter.ai— model may be auto-selected (e.g., GLM-5), and OpenRouter credits are consumedImpact
OPENROUTER_API_KEYin their environmentRelated Issues
provider: autoorprovider: custom. Specific providers (minimax, anthropic, etc.) still fall through to OpenRouter.Proposed Fix
gateway/run.py:_resolve_runtime_agent_kwargs()and CLI initialization should readmodel.providerandmodel.base_urlfrom config and pass them as explicit overrides toresolve_runtime_provider():This ensures the gateway respects
model.providerconfig before falling back to auto-detection.