# Hermes Configuration Discipline Do not modify Hermes config.yaml by adding keys you guessed or assumed existed. Always verify before applying. ## The Rule **You must verify every config key exists in official Hermes documentation before adding it to config.yaml.** Hermes config keys are not arbitrary YAML — they are read by specific code paths in the Hermes runtime. A made-up key is silently ignored, not validated, and leaves you thinking a feature was configured when it wasn't. ## Verification Sources (in priority order) 1. **The `hermes config` CLI** — `hermes config set KEY VAL` validates the key path before applying. If `hermes config set` accepts it, it's a real key. 2. **The official docs** — https://hermes-agent.nousresearch.com/docs/user-guide/configuration 3. **The `hermes-agent` skill** — loaded with `skill_view(name='hermes-agent')`, it documents known config sections. 4. **The source code** — `hermes_cli/config.py` contains DEFAULT_CONFIG which enumerates every recognized top-level key. 5. **The internal help** — `hermes config --help`, `hermes config check`, `hermes config show` ## What NOT to do - **Do not assume patterns from other tools carry over.** Just because some other tool uses `fallback_providers` doesn't mean Hermes reads them. - **Do not write a key + value into config.yaml that you haven't seen in the docs, the skill, or the source.** Writing and testing is not the right order — verify first, then write. - **Do not patch config.yaml by hand with arbitrary YAML when `hermes config set` exists.** The CLI is the safe path. Use it. ## What config changes look like for Hermes If the user wants automatic fallback to a local model, verify the installed Hermes schema first. Current Hermes uses `model.fallbacks` for the main agent and `delegation.fallback` for child agents. Do not substitute guessed names such as `fallback_providers`, `fallback_chain`, or `fallback_order`. Example shape (verify against the installed version before applying): ```yaml model: fallbacks: '[{"model":"llama3.2:3b","provider":"ollama-local"}]' delegation: fallback: '[{"model":"llama3.2:3b","provider":"ollama-local"}]' providers: ollama-local: base_url: http://localhost:11434/v1 ``` ### Verify a custom OpenAI-compatible provider A provider is active only if it is represented in current `config.yaml` under `providers` or the active `model` block. A stale `auth.json` record containing only a label, URL, status, or secret fingerprint is metadata -- it does not prove the credential still exists or that Hermes can use it. 1. Parse `config.yaml`; inspect `model`, `providers`, `delegation`, and `auxiliary` without printing secrets. 2. Check `.env` for the expected named variable; report only presence and length. 3. Treat `auth.json` fingerprints as clues, not usable credentials. 4. Call `/models` with the actual credential and verify the requested model ID appears. 5. Send a minimal chat completion using that exact model. 6. Only after both calls succeed report the provider and model as functional. ### Verify Ollama as a fallback 1. Confirm the binary, service, and listener. Keep it local-only unless remote access was explicitly requested. 2. Pull the exact configured model. 3. Verify both `/api/tags` and OpenAI-compatible `/v1/models` list it. 4. Send a deterministic `/v1/chat/completions` probe and verify returned content. 5. Confirm `model.fallbacks` and, when required, `delegation.fallback` reference the same provider/model. Installing a model is not complete until inference succeeds. A configured provider with an empty model list is not operational. ## Config change workflow ```text User request → check docs/skill/source for real key → if EXISTS → use `hermes config set` or edit via `hermes config edit` if NOT FOUND → tell user it doesn't exist, suggest alternatives ``` ## When the user corrects you If the user calls out a made-up config key: - Acknowledge immediately — don't deflect - Remove the invalid key from config.yaml via the proper CLI or a direct edit - Document the lesson ## Known missing features (as of 2026-07-05) | User wants | Hermes has | Workaround | |---|---|---| | Automatic provider failover | `fallback_providers` does NOT exist | Manual provider switch via CLI, or local ollama for maintenance tasks | | Multiple fallback providers | Not supported | N/A | | Provider priority list | Not supported | N/A | ## Web tools `use_gateway` pitfall Hermes has two config knobs for web tools: ```yaml web: backend: firecrawl # Which web backend to use use_gateway: false # true = route through Nous Portal gateway ``` **The trap:** When `web.use_gateway: true` (the default or a previously-set value), Hermes routes Firecrawl requests through **Nous Portal's gateway** — it ignores your `FIRECRAWL_API_KEY` from `.env` entirely. If you're not logged into Nous Portal (no OAuth session), `web_search` and `web_extract` fail with: > "Web tools are not configured. Set FIRECRAWL_API_KEY for cloud Firecrawl..." Even though the key IS set and valid. The fix is: ```bash hermes config set web.use_gateway false ``` Then a new session (`/reset`) picks up the change. **Note:** `/reset` itself does NOT fix this — the problem is the config value, not the session state. Multiple resets without changing the config value will all fail the same way. **Verification:** Test the key directly against Firecrawl's API before and after: ```bash source ~/.hermes/.env 2>/dev/null curl -s -X POST "https://api.firecrawl.dev/v1/search" \ -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"test","limit":1}' # Expected: HTTP 200, {"success": true, "data": [...]} ``` **Key learning:** `web.use_gateway: true` is NOT a fallback or override layer — it *replaces* the local key. If you're self-hosting the Firecrawl key in `.env`, this must be `false`. Setting it back to `true` after switching to Nous Portal OAuth would be correct for that auth mode. ### Debugging flow for "web tools not configured" ``` 1. Check .env: grep FIRECRAWL_API_KEY ~/.hermes/.env → If missing, add key. If present, proceed. 2. Check config: grep -A2 '^web:' ~/.hermes/config.yaml → If use_gateway: true, flip to false via: hermes config set web.use_gateway false → Then /reset or start new session. 3. Test key: direct curl to api.firecrawl.dev (see above) → 200 = key valid. Non-200 = key expired/wrong. 4. Verify tools: try web_search or web_extract ```