Initial skills documentation — 25 categories, all SKILL.md + references + scripts
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
# 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 `<base_url>/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
|
||||
```
|
||||
Reference in New Issue
Block a user