tools-update-cron: sync 2026-07-15 — 23 skill(s) updated

This commit is contained in:
Hermes Agent
2026-07-15 14:01:38 -05:00
parent 092bdf0517
commit fd8a7847d6
23 changed files with 3072 additions and 131 deletions

View File

@@ -1,7 +1,7 @@
---
name: hermes-profile-management
description: "Create, configure, and validate Hermes profiles with linked workspaces. Covers the full lifecycle: clone, model selection, cwd binding, AGENTS.md seeding, and two-round validation."
version: 1.1.0
version: 1.3.0
author: agent
license: MIT
platforms: [linux]
@@ -154,6 +154,12 @@ ls ~/workspace/<name> 2>&1 # Workspace gone (No such file or directo
## Pitfalls
- **User mentions a name → check local state BEFORE web search**: When the user says a name you don't recognize (e.g., "openz"), do NOT immediately search the web for it. Check local state first: `hermes profile list` (could be a profile), `hermes skills list` (could be a skill), memory/fact_store (could be a known entity), `session_search` (could be from a prior session). Only search the web if all local checks come up empty. The user will be frustrated if you treat their local resources as unknown internet things.
- **Check memory/fact_store for infrastructure state before assuming something isn't installed**: When the user asks you to set up or integrate a service (ComfyUI, Open WebUI, etc.), check memory and fact_store for existing infrastructure BEFORE writing a plan that assumes it needs to be installed from scratch. The user may have set it up in a prior session. If the user says "check memory," you've already made the mistake — stop, check, and revise the plan. This is the infrastructure variant of the name-resolution pitfall above.
- **Scope incrementally — start with the simplest working path, defer advanced features**: When the user says "first I just want X for now, more later," write the plan for X only. Explicitly list deferred features in a "Future Phases" section so the user sees you heard them, but do NOT include those phases in the current scope. The user wants a working deliverable fast, not a maximal architecture document. This applies to integration plans, feature rollouts, and any multi-phase work.
- **Backend API server profiles must declare their interface in AGENTS.md**: When a Hermes profile serves as a backend for a web UI (Open WebUI, custom frontend, etc.), its AGENTS.md MUST include a prominent "Your Main Interface is X" section at the top. This section must explicitly state: (a) the agent is a backend API server, not the UI, (b) users interact through the web interface, not directly, (c) UI features like image generation, TTS, STT, and vision are handled by the web UI — do NOT try to enable those Hermes toolsets, (d) the agent's tools (terminal, file, web, memory) are for backend tasks only. Without this section, the agent will try to enable `image_gen`, `tts`, `vision`, and `browser` toolsets to fulfill user requests, wasting resources and confusing the model. See `references/open-webui-backend-profile-pattern.md` for the canonical template.
- **AGENTS.md alone won't fix a running session — use agent.system_prompt too**: The agent loads AGENTS.md at session start. If the user is in a session that started before the AGENTS.md update, the agent will still exhibit the old behavior. Always pair AGENTS.md updates with `hermes -p <profile> config set agent.system_prompt "..."` to inject the directive into every session immediately. `agent.system_prompt` appends to the system prompt after the identity block and takes effect without a session restart. Apply to ALL backend profiles at once with a `for` loop. See `references/open-webui-backend-profile-pattern.md` for the full dual-delivery pattern.
- **model.base_url MUST match model.default (critical, silent failure)**: The #1 silent error in cloned configs. `model.default` names a model, `model.base_url` points at the endpoint that serves it. If the source profile's `base_url` was an Epyc vLLM endpoint (10.0.0.26:8000, serves only `qwen3.6-35b-a3b-uncensored`) and the new profile's `model.default` is `minimax-m3:cloud` (served by Ollama at localhost:11434), the primary model will silently fail to load. ALWAYS cross-check: if model.default is a `:cloud` Ollama-routed model, base_url must be `http://localhost:11434/v1`, NOT an Epyc/DGX endpoint. The fix: `config['model']['base_url'] = 'http://localhost:11434/v1'` for any Ollama-routed primary model.
- **context_length: 131072, not 262144**: DGX qwen3 DFlash has a native max context of 262,144 tokens, but you MUST configure `model.context_length: 131072`. The DGX vLLM runs `max_num_seqs: 3` with a shared ~457K token KV pool. Setting 262144 limits you to 1 concurrent stream; 131072 allows 3 streams. Epyc qwen3.6-35b uses 262144 (single stream, no KV pool sharing).
- **browser.allow_private_urls must match security.allow_private_urls**: If `security.allow_private_urls: true` but `browser.allow_private_urls: false`, the browser tool will silently block LAN URLs (10.0.0.x) even though security permits them. ALWAYS set both to the same value.
@@ -164,6 +170,8 @@ ls ~/workspace/<name> 2>&1 # Workspace gone (No such file or directo
- **Clone inherits config version**: May be behind the source. Run `hermes config migrate` to bring it current.
- **AGENTS.md still references source workspace**: Copied workspace files still have the old workspace path and purpose. Rewrite AGENTS.md for the new profile.
- **Profile alias**: `hermes profile create` auto-creates a wrapper at `~/.local/bin/<name>`. Use it as `vscode chat` or `hermes -p vscode`.
- **`~/.hermes/active_profile` is the sticky-default file**: `hermes profile use <name>` writes the profile name to `~/.hermes/active_profile`. When `hermes` runs without `-p`, it reads this file to determine which profile to load. If bare `hermes` loads the wrong profile, check this file first — it may have been set by a prior `hermes profile use` or manual edit. The file contains a single line with the profile name. Fix: `echo "general" > ~/.hermes/active_profile` or `hermes profile use general`.
- **Profile alias preferred over `-p` flag for dispatcher skills**: Some models (notably minimax-m3:cloud) hallucinate that `hermes -p` doesn't exist, even though it's a valid global flag. When writing dispatcher skills that delegate to another profile, use the profile alias (`research -s ...`) instead of `hermes -p research -s ...`. The alias is at `~/.local/bin/<name>` and works from any directory. This avoids the model second-guessing the command and falling back to doing the work itself.
- **Skills are cloned**: The new profile gets a copy of the source's skills directory. They diverge independently after creation.
- **Fallback model should be DGX qwen, not Ollama**: The standard fallback is `qwen` via DGX (http://10.0.0.6:8000/v1, api_key: dummy), NOT another Ollama model. DGX is the failover endpoint — if Ollama is down, the fallback must point at a different infrastructure, not the same one.
- **cronjob tool pause may not persist to jobs.json**: The `cronjob action='pause'` tool reports success and returns `enabled: false, state: paused` in its response, but the on-disk `cron/jobs.json` may still show `enabled: true, state: scheduled` on next read. The tool's in-memory state and the file can diverge. After pausing, ALWAYS verify by reading jobs.json directly, and if it didn't persist, write the pause directly: `j['enabled']=False; j['state']='paused'; j['paused_at']=<iso>; j['paused_reason']=<reason>` and dump back to the file. This is the only reliable way to pause a cloned cron job.
@@ -172,15 +180,55 @@ ls ~/workspace/<name> 2>&1 # Workspace gone (No such file or directo
- **The `patch` tool refuses writes to config.yaml**: You cannot use the `patch` tool on `~/.hermes/profiles/<name>/config.yaml` — it errors with "Agent cannot modify security-sensitive configuration." Use `hermes config set <key> <value>` instead, which writes safely and confirms the change. For the top-level `workspace:` key: `hermes config set workspace /workspace/<name>`. For `terminal.cwd`: `hermes config set terminal.cwd /home/n8n/workspace/<name>`. Both keys exist independently — `workspace:` controls which workspace's AGENTS.md gets auto-loaded, `terminal.cwd` controls the shell's starting directory. When binding a profile to its workspace, set BOTH.
- **`workspace:` key vs `terminal.cwd` are independent**: The top-level `workspace:` key (e.g. `/workspace/general`) controls which workspace root Hermes loads AGENTS.md / CLAUDE.md / .cursorrules from. The `terminal.cwd` key controls where shell commands start. They can diverge after a clone or partial setup — always verify both point at the intended workspace for the active profile.
- **Symptom: model lists files from home directory instead of workspace**: When `terminal.cwd: .` (the default), the session starts in whatever directory the process was launched from — typically `/home/n8n`. If the user says "list md files in your workspace" and the model returns files from the home folder (random scripts, memory files, etc.) instead of `~/workspace/<profile>/`, the cwd is unbound. Fix: `hermes config set terminal.cwd /home/n8n/workspace/<profile>`. This is the #1 cause of "model is looking at wrong files" confusion.
- **`~/.hermes/skills/` base directory is NOT a deployment target for skill copies.** The base `~/.hermes/skills/` exists but only holds cross-profile-only skills (e.g., `kanban-codex-lane`). The `autonomous-ai-agents` and `mcp` categories live in `~/.hermes/profiles/<p>/skills/<category>/`, NOT in the base. When writing a new skill, put a canonical source in your workspace (e.g., `~/workspace/general/<skill>-SKILL.md`) for tracking, then `cp` to each profile's category dir. Don't write to `~/.hermes/skills/<category>/<skill>/` thinking it will be picked up — the skill-discovery loader only scans per-profile skills dirs. Verified with `ls -la ~/.hermes/skills/autonomous-ai-agents/` → empty (no skills in that base dir). See `references/skill-distribution-patterns.md` for the full distribution model.
- **SOUL.md text duplicated via CLAUDE.md/AGENTS.md**: SOUL.md is loaded as identity (slot #1 in stable tier). CLAUDE.md/AGENTS.md are loaded as project context (separate code path in context tier). `skip_soul` only prevents SOUL.md from being loaded twice — it does NOT skip CLAUDE.md or AGENTS.md. If `~/workspace/CLAUDE.md` contains the same persona text as SOUL.md, the model sees it twice: once as "who I am" and once as "project instructions I should follow." Fix: keep CLAUDE.md/AGENTS.md for project-specific instructions (build commands, conventions, architecture), not persona text. Delete workspace-level CLAUDE.md if it only contains SOUL.md content.
- **agent.system_prompt config key**: `hermes config set agent.system_prompt "text"` appends text to the system prompt after the identity block. It augments, not replaces. Useful for injecting directives that must appear in every session without editing SOUL.md. Unlike SOUL.md, this is per-profile (set in each profile's config.yaml).
- **memory.write_approval config flag**: `hermes config set memory.write_approval true` gates ALL memory tool writes (add/replace/remove) to MEMORY.md and USER.md. When true, foreground writes prompt inline for approval; background-review writes are staged for `/memory pending` / `/memory approve` / `/memory reject`. Default is false (writes happen freely). This only gates the built-in `memory` tool — it does NOT affect Holographic/fact_store writes. Stronger than a SOUL.md directive since it's enforced at the tool level. **Per-profile, not global** — must be set in each profile's config.yaml. Use the `hermes-config-bulk-update` pattern to apply across all profiles in one pass.
- **`/memory pending` and `/memory approve` are chat slash commands, NOT CLI commands**: `hermes memory approve <id>` and `hermes memory pending` do not exist — the `hermes memory` CLI only has `setup`, `status`, `off`, `reset`. When `write_approval` is on, pending entries are reviewed with `/memory pending` (lists staged entries), `/memory approve <id>` (approves one), and `/memory reject <id>` (rejects one) — typed directly in the chat, not via the terminal. The `hermes memory status` command shows which provider is active but does NOT show pending entries.
- **Temperature is set in THREE places, not one**: A profile's temperature lives in three independent locations: (1) `moa.presets.<name>.reference_temperature` — the research sub-agent's reference stage, (2) `moa.presets.<name>.aggregator_temperature` — the research sub-agent's aggregation stage, (3) `custom_providers[].extra_body.temperature` — the main model's temperature passed via the Ollama provider's extra_body. All three must be set to the same value for consistent behavior. The main model temperature is NOT a top-level `model.temperature` key — it's embedded in the provider's `extra_body` block. To set all three: `sed` for the MOA temps (simple value replacement), and `patch` or `execute_code` to insert `extra_body: { temperature: 0.3 }` into the Ollama provider block (which may not exist yet). See `references/temperature-config.md` for the full pattern.
## Skills as Dispatcher + Methodology Contracts (Cross-Profile Distribution)
When designing a NEW skill that runs across profiles (i.e., a skill with more than one SKILL.md file), pick the distribution model upfront and document it in the plan. The two main patterns:
### Pattern A: Single skill, multi-profile copies (default)
- One SKILL.md, copied to every profile that needs it as a real file (not symlink).
- Use when: the skill is self-contained and each profile can run it independently with the same behavior.
- Example: `searxng-smart-search` lives at `~/.hermes/profiles/<p>/skills/mcp/searxng-smart-search/SKILL.md` on every profile that wants MCP search. The SKILL.md is identical in every copy.
### Pattern B: Dispatcher + Methodology contract (cross-profile delegation)
- **Two SKILL.md files** with a strict separation of concerns.
- **Dispatcher** (per-profile, lightweight): owns trigger detection, clarifying questions, dispatch command, session-id capture, delivery report. Installed on every profile that needs to fire the trigger. ~150 lines.
- **Methodology** (one specialized profile only): owns the actual heavy logic. Lives on the profile whose tools/model fit the work best. ~300+ lines, may be expensive to run.
- The dispatcher's command is identical regardless of which profile it's running on: `hermes -p <specialized-profile> -s <methodology-name> chat -q "<question>" ...`. The `-p` flag pins the target.
- Use when: the heavy work needs a specific profile's setup (e.g., a research profile with SearXNG MCP and a long-context model), but the trigger should be fireable from any profile (e.g., from dev, family_law, finance).
- Example: `better-search` (dispatcher, 16 profiles) + `better-search-research` (methodology, research profile only). The dispatcher catches `better search` triggers on any profile and always delegates to `research -s better-search-research ...` (using the `research` profile alias at `~/.local/bin/research` — avoids the `-p` flag that some models hallucinate doesn't exist).
- Reference implementation: `references/skill-distribution-patterns.md` — full design rationale, when to use which pattern, and a worked checklist for new-skill plan docs.
### Why two-skill contracts matter
1. **Single source of truth for the heavy logic.** Edit the methodology once → all 16 dispatchers pick up the change.
2. **Cheap dispatcher, expensive methodology.** The dispatcher is ~150 lines and runs in <1s to fire; only the methodology pays the long-context / multi-search cost.
3. **No skill duplication for the heavy part.** Replicating a 300-line methodology to 16 profiles = 4,800 lines of drift-prone duplication. The contract makes this a non-issue.
4. **Trigger coverage is per-profile, logic is per-specialized-profile.** Triggers can vary per profile (e.g., dev profile might add a dev-specific trigger) without touching the methodology.
### Decision: when to use which
- **Self-contained skill, same behavior everywhere** → Pattern A (single skill, real copies).
- **Skill that needs a specific profile's tools/model** → Pattern B (dispatcher + methodology).
- **Default to Pattern A.** Add the contract only when there's a concrete reason (the heavy logic needs a specific profile's setup, or the methodology is too large/expensive to replicate).
### Pitfalls for the dispatcher+methodology pattern
- **Real copies, not symlinks** for the dispatcher. Each profile gets its own dispatcher SKILL.md. The methodology also gets a real file, but on one profile only. (See `references/skill-distribution-patterns.md` for the verification protocol and the **same-category + same-scope precedent check** — the wrong-precedent trap is the most common error here.)
- **The dispatch command is identical across all dispatcher copies.** Hardcode `-p <specialized-profile> -s <methodology>` in every dispatcher's SKILL.md. The operator never types the profile flag.
- **`--max-turns` is a SAFETY NET, not the cap.** The methodology's loop cap is enforced by its own scaffolding (e.g., a `/tmp/<sid>.md` ledger that counts `## Refinement` blocks). `--max-turns` is just the ceiling the agent hits if it goes long. Set it high enough that real questions don't hit it (e.g., 50 for a 3-loop skill, 600 for an exhaustive one). Same logic as `deep-research` pitfall #4.
- **No `--resume` follow-up for cap-bounded methodologies.** If the methodology has a per-dispatch cap (e.g., better-search's 3-loop cap), `--resume` re-enters with fresh `--max-turns` and breaks the cap guarantee. Make every follow-up a fresh dispatch with a new sid, new ledger, and a new budget. Trade-off: the operator loses research context between dispatches — if iterative drilling matters, use a heavier skill (e.g., `deep-research`) that supports `--resume`.
- **Methodology skill must be loadable before dispatch.** The dispatcher should run a precondition check (`hermes -p <specialized-profile> skills list | grep <methodology>`) and abort cleanly with a "skill not installed" message if the methodology is missing. This prevents dispatching a generic unbounded session. (If you drop the precondition check, the runtime will still report `-s <name>: skill not found` clearly — either is fine, just don't silently fail.)
- **Trigger phrases must be explicit.** Avoid generic English verbs (`look into`, `find out`, `search again`) — they collide with normal agent tasks on dev/code profiles. Use phrases that include the skill's own name (`better search`, `do a better search`). Keep the list short (2-3 phrases); more phrases = more collision risk.
- **Cross-profile tests must bracket sparse AND dense profiles.** When verifying a dispatcher works on every profile, pick one profile that has many other cross-profile skills (dense, e.g. `general`) and one that has few (sparse, e.g. `people`). Testing only one end doesn't prove the principle. Run the same test from both ends.
## SOUL.md Symlink Propagation (One File, All Profiles)
Instead of maintaining independent SOUL.md copies per profile, use a single canonical file with symlinks. `load_soul_md()` does `get_hermes_home() / "SOUL.md"` — a simple file read, so symlinks are transparent.
@@ -340,7 +388,7 @@ These all regenerate or are stale:
- `interrupt_debug.log` — cloned debug log
- `checkpoints/store/` contents — cloned snapshots (especially if checkpoints disabled)
- `state-snapshots/` — cloned pre-update snapshots (can be 80MB+)
- `logs/agent.log*`, `logs/errors.log*`, `logs/gateway*.log*`, `logs/mcp-stderr.log`, `logs/hindsight-embed.log`, `logs/update.log`, `logs/curator/` — all cloned (can be 120MB+)
- `logs/agent.log*`, `logs/errors.log*`, `logs/gateway*.log*`, `logs/mcp-stderr.log`, `logs/hindsight-embed.log`, `logs/update.log`, `logs/curator/` — all cloned (can be 120MB+). **Pitfall:** `logs/curator/` is a directory, not a file — use `shutil.rmtree` or `rm -rf`, not `os.remove`. Same for `cache/` and `sessions/`.
- `models_dev_cache.json`, `ollama_cloud_models_cache.json`, `provider_models_cache.json`, `context_length_cache.yaml` — caches regenerate
- `cache/openrouter_model_metadata.json`, `cache/model_catalog.json` — caches regenerate
- `config.yaml.bak.*` — stale backups
@@ -395,6 +443,7 @@ Full validation script and cross-check code: `references/post-config-validation.
## Support Files
- `references/skill-distribution-patterns.md` — Cross-profile skill distribution patterns (Pattern A: real copies vs. Pattern B: dispatcher+methodology contract). Worked `better-search` example, decision checklist, real-copy-vs-symlink verification.
- `references/remote-acp-vscode.md` — Remote Hermes + VS Code ACP: SSH tunnel options, filesystem limitation, and workarounds
- `references/profile-setup-checklist.md` — Full 22-step checklist for profile setup (workspace, cron, config cleanup, permissions, max settings, fallback, junk cleanup, validation). Copy this into the new profile's workspace as a tracking doc.
- `references/post-config-validation.md` — Structured post-config validation pass: endpoint testing, model respond tests, base_url/model cross-check, hindsight bank audit, empty-value scan, decision points to surface to user.
@@ -409,3 +458,6 @@ Full validation script and cross-check code: `references/post-config-validation.
- `references/mcp-server-http-sharing.md` — Convert per-profile stdio MCP servers to a single shared HTTP instance with systemd persistence. Eliminates redundant npx processes and cold-start delays across profiles.
- `references/temperature-config.md` — Temperature is set in THREE places (MOA reference, MOA aggregator, Ollama provider extra_body). Full pattern for setting all three consistently.
- `references/telegram-bot-token-conflict.md` — Diagnose and fix Telegram bot token conflicts where messages route to the wrong profile because two gateways compete for the same token.
- `references/deepseek-reasoning-effort.md` — DeepSeek v4 `reasoning_effort` parameter: only two real tiers (`high` and `max`). `low`/`medium` silently map to `high`, `xhigh` maps to `max`. Don't bother with intermediate values — they don't save tokens.
- `references/open-webui-infrastructure.md` — Open WebUI deployment details for this environment: systemd service (not Docker), SQLite config table, ComfyUI wiring, Hermes API server connections, user accounts, and pitfalls.
- `references/open-webui-image-gen-debugging.md` — Open WebUI image generation debugging: the 3-way AND gate (model capability, backend flag, user permission), diagnostic curls, DB-level checks, fixes by gate, frontend cache clearing, and current environment state.