WorldRouter

Skip to Content
AgentsHermes Agent

Hermes Agent

Hermes Agent  is a self-improving AI agent built by Nous Research. It reads provider configuration from a YAML file and supports any OpenAI-compatible endpoint as a custom provider — so you can point it at WorldRouter without forks, wrappers, or schema changes.

This guide walks through adding WorldRouter as a Hermes custom provider, selecting a WorldRouter model as the default, and verifying the connection.

Note:

Model selection. WorldRouter exposes multiple model families (Claude, GPT, Gemini, Grok, …). Hermes can call any of them through the same custom provider — pick the model ID you want from the Models page when you fill in model.default. Hermes-specific Claude compatibility caveats are noted at the end of this page.

Prerequisites

  • Hermes Agent installed. Follow the Hermes installation guide . Verify with hermes --version.
  • WorldRouter API key. Create one on the API Keys dashboard. Copy the value — it is only shown once.
  • WorldRouter base URL. Copy the Base URL value from the same dashboard page. It includes the /v1 suffix (for example, https://<your-worldrouter-host>/v1). Hermes expects the /v1 suffix because it speaks OpenAI chat-completions.
  • Available credits. Confirm balance on the Credits page.

Quick Start

1. Open your Hermes config file

Hermes reads its settings from:

  • macOS / Linux: ~/.hermes/config.yaml
  • Windows: %USERPROFILE%\.hermes\config.yaml

This is a plain YAML file on disk. Edit it with any text editor (VS Code, nano, vim, …). The same file is read by every Hermes surface — CLI, dashboard, and integrations.

  • If the file does not exist (first-time setup), run hermes setup (full wizard) — or just hermes model for the provider/model picker alone. Either command creates ~/.hermes/config.yaml with defaults; you can then add the WorldRouter block in step 2 by re-running hermes model (interactive path) or by editing the file directly.
  • If the file already exists, add the new custom_providers entry and update the top-level model block — do not replace the file wholesale, or you will lose other settings.

2. Add WorldRouter as a custom provider

Append a worldrouter entry to the custom_providers: list. If the file already has a custom_providers: list, add to it; otherwise create the list at the top level.

custom_providers: - name: worldrouter base_url: https://<your-worldrouter-host>/v1 key_env: WORLDROUTER_API_KEY api_mode: chat_completions models: claude-opus-4-6: {} claude-sonnet-4-6: {} claude-haiku-4-5: {} gpt-5.4: {} gemini-2.5-flash: {}

Field notes:

  • name is the label you reference elsewhere in the config (worldrouter). Pick anything that does not collide with another provider in the same file.
  • base_url must include the /v1 suffix. Copy the exact value from the API Keys dashboard.
  • key_env is the name of the environment variable Hermes should read for the API key — no $ prefix and no value (the value lives in your shell environment, see step 4). If you would rather paste the key directly into the file, replace key_env: WORLDROUTER_API_KEY with api_key: sk-worldrouter-... and skip step 4. The key_env form is preferred so the key does not live in plain text on disk.
  • api_mode: chat_completions tells Hermes to use the OpenAI chat-completions wire format. WorldRouter speaks this format natively.
  • models lists the model IDs you want available for selection — the ID is the YAML key, and the body ({}) is empty unless you want per-model overrides such as context_length. Each ID must match a model from the Models page exactly (IDs are case-sensitive). You do not have to list every WorldRouter model — only the ones you want Hermes to use.

For full schema details (per-model context_length, advanced fields), see the Hermes Custom Providers reference .

3. Set WorldRouter as the active provider

Update the top-level model: block so Hermes routes by default to WorldRouter:

model: default: claude-opus-4-6 provider: custom:worldrouter
  • provider uses the custom:<name> form for custom providers — the suffix (worldrouter) must match the name: you chose in step 2. Hermes also accepts the bare form provider: worldrouter as a silent alias; the custom:<name> form is preferred because it matches what hermes doctor and the hermes model picker display.
  • default must be one of the model IDs you listed under that provider’s models: map.

Switching providers later is the same edit — change provider: (and optionally default:) and restart your Hermes session.

4. Export your API key

If you used key_env: WORLDROUTER_API_KEY in step 2 (recommended), export the value in the shell that launches Hermes. Add this to ~/.zshrc, ~/.bashrc, or ~/.config/fish/config.fish:

export WORLDROUTER_API_KEY="sk-worldrouter-..."

Then reload the shell profile so the current terminal picks up the value:

# zsh source ~/.zshrc # bash source ~/.bashrc # fish source ~/.config/fish/config.fish

Alternative: Hermes also reads variables from ~/.hermes/.env. Add WORLDROUTER_API_KEY=sk-worldrouter-... there if you prefer per-tool env management over a shell profile.

If you pasted the key literally into config.yaml via api_key: instead, skip this step.

5. Verify

Send a one-shot prompt with Hermes’s -z flag (use this instead of a free-form positional argument — the bare hermes "<prompt>" form is not supported; the first positional must be a subcommand like chat):

hermes -z "Reply with 'ok' if you can see this."

Or run hermes chat for an interactive session and type the prompt there.

You have a working setup when both of the checks below hold:

  1. Hermes returns a normal answer. A reply such as ok — not an error, not a “model not found”, not a “401 unauthorized” — means the request reached WorldRouter and a model responded.
  2. The call shows up in WorldRouter usage. Open the Activity dashboard; the request and its token count should appear within a few seconds, and your credit balance on the Credits page should drop accordingly. This is the ground truth that the request actually went to WorldRouter rather than a fallback provider.

If you only see #1 but not #2, Hermes is talking to a different provider — most often because model.provider: is still pointing at an old entry, or because a fallback_providers: entry is being used first. Re-check step 3. You can also run hermes doctor for a diagnostic on the current provider/model resolution.

Interactive alternative — hermes model

If you prefer not to hand-edit YAML, Hermes ships an interactive picker that walks you through adding a custom provider:

hermes model

Choose Custom endpoint when prompted, then enter:

  • Base URL — your WorldRouter base URL including /v1.
  • API key — your WorldRouter key (sk-worldrouter-…).
  • Model name — any WorldRouter model ID from the Models page.

Hermes persists the values into ~/.hermes/config.yaml using the same custom_providers schema shown above. The hand-edited and interactive paths produce equivalent configs — use whichever you prefer.

How it works

Hermes treats every provider — built-in (anthropic, openrouter, …) or custom — as an interchangeable backend behind a single dispatch layer. When you select a custom provider, Hermes sends the chat-completions request to ${base_url}/chat/completions with the configured API key. WorldRouter’s OpenAI-compatible API accepts the request, forwards it to the underlying model family (Claude, GPT, Gemini, …), and bills usage against your WorldRouter credits.

The integration does not require any Hermes patches: WorldRouter is a vanilla OpenAI-compatible target as far as Hermes is concerned. Upgrading Hermes does not break the connection.

Model compatibility notes

  • Switching model families is a YAML edit. Change model.default: (or set it per call inside Hermes) to any model ID listed under your provider’s models: map. No provider re-selection is needed as long as the ID is in the list.
  • Claude models routing. WorldRouter currently serves Claude models through two distinct routes (pooled vs AWS-direct). Hermes integration paths that depend on AWS-direct Claude — for example, certain service_tier or Bedrock-specific behavior — are tracked in the WorldRouter model catalog; pick the Claude ID flagged as Hermes-compatible on the Models page if your Hermes workflow uses those paths.
  • Reasoning / service_tier fields. Hermes can pass extra request fields (reasoning_effort, service_tier, extra_body) through the chat-completions API. WorldRouter forwards these to the upstream model when the model family supports them; otherwise they are ignored.
  • Fallback providers. Hermes’s fallback_providers: block accepts any other custom provider you have configured (a local Ollama, another cloud, …). WorldRouter can be either the primary or a fallback — the schema is symmetric.

Troubleshooting

401 Unauthorized from ${base_url}/chat/completions. Your API key is missing or malformed. If you used key_env: WORLDROUTER_API_KEY, verify the env var is exported in the shell that launched Hermes (echo $WORLDROUTER_API_KEY). If you used api_key: literal, re-copy the value from the API Keys dashboard — make sure no whitespace was pasted.

404 Not Found or model not found. Either the base_url is missing the /v1 suffix (Hermes expects the full chat-completions root), or the model ID under models: does not match the canonical ID on the Models page. WorldRouter model IDs are case-sensitive; common mismatches include claude-opus-4 vs claude-opus-4-6.

Hermes still uses the previous provider after editing the file. Hermes loads config.yaml at session start; a session you opened before the edit will keep the old provider. Exit the current session and re-launch with hermes chat (or run hermes -z "<prompt>" for a fresh one-shot) so the new YAML is picked up. hermes doctor will report the resolved provider/model for the current session.

Credits not decreasing on the dashboard. The request did not actually hit WorldRouter — usually because model.provider: still points at a different provider, or base_url resolves to a non-WorldRouter host. Re-check both fields. The Activity dashboard shows whether requests are reaching WorldRouter.

Reference