From fd8a7847d6c134584ed0ae4a28d3b012c2d2ad4f Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 15 Jul 2026 14:01:38 -0500 Subject: [PATCH] =?UTF-8?q?tools-update-cron:=20sync=202026-07-15=20?= =?UTF-8?q?=E2=80=94=2023=20skill(s)=20updated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ask-claude/SKILL.md | 3 +- ask-dev/SKILL.md | 9 +- ask-hermes/SKILL.md | 5 +- creative-ideation/SKILL.md | 213 ++++++++------ deep-research/SKILL.md | 61 +++- dynamic-workflow/SKILL.md | 209 ++++++++++++++ equipment-knowledge-base/SKILL.md | 171 +++++++++++ gitea/SKILL.md | 19 +- hermes-config-bulk-update/SKILL.md | 14 +- hermes-cron-management/SKILL.md | 200 +++++++++++++ hermes-profile-management/SKILL.md | 56 +++- local-ai-media-generation/SKILL.md | 90 ++++++ maps/SKILL.md | 195 +++++++++++++ nordvpn/SKILL.md | 99 +++++++ notion/SKILL.md | 448 +++++++++++++++++++++++++++++ ocr-and-documents/SKILL.md | 172 +++++++++++ open-webui-administration/SKILL.md | 196 +++++++++++++ searxng-smart-search/SKILL.md | 41 ++- simplify-code/SKILL.md | 212 ++++++++++++++ skill-quality-review/SKILL.md | 154 ++++++++++ spike/SKILL.md | 197 +++++++++++++ test-driven-development/SKILL.md | 362 +++++++++++++++++++++++ youtube-content/SKILL.md | 77 +++++ 23 files changed, 3072 insertions(+), 131 deletions(-) create mode 100644 dynamic-workflow/SKILL.md create mode 100644 equipment-knowledge-base/SKILL.md create mode 100644 hermes-cron-management/SKILL.md create mode 100644 local-ai-media-generation/SKILL.md create mode 100644 maps/SKILL.md create mode 100644 nordvpn/SKILL.md create mode 100644 notion/SKILL.md create mode 100644 ocr-and-documents/SKILL.md create mode 100644 open-webui-administration/SKILL.md create mode 100644 simplify-code/SKILL.md create mode 100644 skill-quality-review/SKILL.md create mode 100644 spike/SKILL.md create mode 100644 test-driven-development/SKILL.md create mode 100644 youtube-content/SKILL.md diff --git a/ask-claude/SKILL.md b/ask-claude/SKILL.md index 799bbce..43144a0 100644 --- a/ask-claude/SKILL.md +++ b/ask-claude/SKILL.md @@ -1,7 +1,7 @@ --- name: ask-claude description: "Consult Claude Opus 4.8 on 10.0.0.28 via SSH print mode with session resumption. Multi-turn back-and-forth without tmux or polling." -version: 2.6.1 +version: 2.7.0 author: Hermes Agent license: MIT platforms: [linux] @@ -372,6 +372,7 @@ Sonnet is 3-5x faster and cheaper. Use for: factual lookups, simple analysis, qu ## Pitfalls - **CRITICAL: Pasted inline beats file paths every time.** Claude runs on 10.0.0.28 and has no access to `/home/n8n/workspace/`, `~/workspace/`, or any other local path. "Read the plan at /home/n8n/workspace/.../_plan.md" wastes a turn: Claude searches the wrong filesystem, returns "file not found," and you paid $0.20-$0.35 for nothing. **Always paste the artifact inline** between clear markers like `==== PLAN BEGINS ==== ... ==== PLAN ENDS ====`. The "Claude's Limitations" section above already says this — but the failure mode is costly enough to deserve its own pitfall. File paths in questions should be reserved for files Claude can actually see on its own host (`~/claude/hermes_support/...`). +- **Large-artifact exception (>~20KB):** For very large plans/reports, pasting inline bloats the question file and the SSH invocation. Instead, `scp` the artifact to the remote host (`scp plan.md n8n@10.0.0.28:/tmp/plan.md`) and tell Claude to read it at that remote path (`/tmp/plan.md`) with its file tools. Claude CAN read files on its own host (10.0.0.28) — the "no local file access" rule only applies to paths on YOUR host. This worked cleanly for a 49.6KB plan validation (ask-claude session a1de5e36, 2026-07-07). Still paste the QUESTION/prompt inline; only the artifact goes via scp. - **ask.sh can fail silently while direct `claude -p` works.** The wrapper may return `{"is_error": true, "error": "no Claude output (timeout or CLI failure)"}` even when Claude is healthy. When this happens, fall back to the direct invocation: `ssh n8n@10.0.0.28 'cd ~/claude/hermes_support && timeout 280 /home/n8n/.local/bin/claude -p "$(cat /tmp/ask-claude-q.txt)" --output-format json --model claude-opus-4-8 --max-turns 30 || true'`. The wrapper is preferred (it handles usage API + merge.py), but the direct path is the reliable fallback. If the direct path also fails, Claude is genuinely down. - **CRITICAL: Never inline questions in SSH commands.** Shell metacharacters (`"`, `$`, `(`, backticks) will break. Always write to a temp file via `mktemp` first, then `claude -p "$(cat $QFILE)"`. - **Always use `--output-format json`** — without it, you get plain text and can't extract session_id for follow-ups. diff --git a/ask-dev/SKILL.md b/ask-dev/SKILL.md index 132e0b8..71aa351 100644 --- a/ask-dev/SKILL.md +++ b/ask-dev/SKILL.md @@ -1,7 +1,7 @@ --- name: ask-dev description: Persistent peer Hermes agent for delegated work on the dev profile. `ask dev ` delegates a task with full context via headless one-shot commands. Session persists across all turns in one Hermes session via --resume. -version: 1.1.0 +version: 1.3.0 author: Hermes Agent license: MIT platforms: [linux] @@ -204,14 +204,17 @@ When the user says "ask dev to fix X, then YOU validate," follow this exact sequ 1. **Profile flag required.** Use `-p dev` — the sticky default may be general, which would spawn a clone of this agent, not a peer. Always pin the profile explicitly. 2. **--yolo is required.** The peer runs headless (one-shot, no TTY). Without `--yolo`, dangerous-command approval prompts fail closed (60s timeout → deny) and the peer can't complete tasks that trigger them. `--yolo` bypasses all approval prompts for the peer session only. The hardline blocklist (rm -rf /, fork bombs, mkfs on root, dd to block devices) still applies — no flag overrides that. This does NOT change the dev profile's config; it only affects the peer session. -2. **Do NOT use interactive REPL mode.** Running `hermes -p dev` without `chat -q` (interactive REPL) was tried and failed — the TUI produces unreadable ANSI redraw noise when driven via `terminal(pty=true)`. The output is garbled and responses cannot be extracted. Always use headless `chat -q "..." -Q` instead. +3. **Do NOT use interactive REPL mode.** Running `hermes -p dev` without `chat -q` (interactive REPL) was tried and failed — the TUI produces unreadable ANSI redraw noise when driven via `terminal(pty=true)`. The output is garbled and responses cannot be extracted. Always use headless `chat -q "..." -Q` instead. 3. **Peer is headless.** Operator sees my relay, not the peer's chat. Full text in `hermes sessions list` if needed. 4. **Peer self-reports are not verified fact.** Spot-check file writes, test passes before confirming to operator. 5. **Peer's workspace is its own.** Files written to the peer's workspace are NOT in this agent's workspace. Give ABSOLUTE paths (e.g. `/home/n8n/workspace/dev/`) if the peer should write to our workspace. 6. **Blast radius.** Peer has ALL tools (terminal, web, MCP) — can rm, exfil, burn tokens. Bound with prompt-level constraints. State the blast radius to operator for sensitive tasks. 7. **Turn budget is hard-capped.** `--max-turns 20` enforces it. If the peer hits 20 before finishing, it returns what it has — operator decides whether to continue. -8. **Don't silently paraphrase.** Relay the peer's actual response. If long, chunk it. Call out unverified claims. +8. **Long implementations hit the 600s foreground wall-clock limit.** A peer dispatch with `--max-turns 50` doing 30+ minutes of work (real implementation, multiple smoke tests with research-profile dispatches inside) can exceed the foreground command's 600-second timeout even when well within the turn budget. The peer may be terminated mid-task with no output, leaving the dispatch in an indeterminate state. **Mitigation:** for any peer dispatch expected to take more than ~5 minutes of wall-clock time, use the terminal tool's `background=true` + `notify_on_complete=true` mode instead of foreground. The peer runs to completion, you get notified on exit, and you spot-check the result. Real example (July 2026): dispatching a 9-task skill build (`better-search` implementation) to `ask-dev` with `--max-turns 50` hit the 600s foreground timeout during Task 5 (smoke test 2). Re-dispatching in background mode completed all 9 tasks. **Rule of thumb:** if the work involves 3+ smoke tests that each spawn their own research-profile dispatches, use background mode from the start. +9. **Don't silently paraphrase.** Relay the peer's actual response. If long, chunk it. Call out unverified claims. 10. **Peers can overstate findings.** A peer may correctly identify real gaps AND incorrectly flag things that aren't actually broken. In this session, the peer correctly identified the tool_executor.py ThreadPoolExecutor as the root cause of the Ctrl+C hang, but also flagged cli.py:9452 (account-usage fetch) as a second culprit — that one uses a `with` context manager that properly joins, so it's not a leak. Always verify each claim independently; don't assume all of a peer's findings are correct just because some are. +11. **Skill-build peers must restore any directory mutations before exit.** When a peer is implementing a skill that includes a write-failure smoke test (e.g., rename `results/` to `results.bak/` to test that `mkdir -p` recreates it), the peer must restore the rename before exit. Real failure (July 2026 better-search build): the dev peer left `results.bak/` on exit with all smoke-test result files inside it. The next session inherited dirty state, and manual recovery was required to move 8 files back to `results/`. **Mitigation:** when composing an implementation prompt that includes a write-failure test, add an explicit "before exit: restore any renamed/moved files" step. When the peer reports "IN PROGRESS" on the last task, the calling agent should assume directory state may be dirty and verify before trusting the report. +12. **Skill-build peers may report "Files Created" with stale file locations.** If the peer's smoke tests renamed a directory, the peer's "files created" summary may list paths that no longer match the actual filesystem (e.g., "result file at /home/n8n/workspace/research/results/..." when the file is actually in `results.bak/`). **Spot-check the peer's filesystem claims directly** with `ls -la` and `stat`, not just by reading the peer's summary. The peer's "Files Created" list is informational; the real filesystem is the source of truth. ## Verification Checklist diff --git a/ask-hermes/SKILL.md b/ask-hermes/SKILL.md index a5285fb..6c357ca 100644 --- a/ask-hermes/SKILL.md +++ b/ask-hermes/SKILL.md @@ -1,7 +1,7 @@ --- name: ask-hermes description: Persistent peer Hermes agent for delegated work. `ask hermes ` delegates a task with full context via headless one-shot commands. Session persists across all turns in one Hermes session via --resume. -version: 4.2.0 +version: 4.3.0 author: Hermes Agent license: MIT platforms: [linux] @@ -215,7 +215,8 @@ When the user says "ask hermes to fix X, then YOU validate," follow this exact s 5. **Peer's workspace is its own.** Files written to the peer's workspace are NOT in this agent's workspace. Give ABSOLUTE paths (e.g. `/home/n8n/workspace/dev/`) if the peer should write to our workspace. 6. **Blast radius.** Peer has ALL tools (terminal, web, MCP) — can rm, exfil, burn tokens. Bound with prompt-level constraints. State the blast radius to operator for sensitive tasks. 7. **Turn budget is hard-capped.** `--max-turns 20` enforces it. If the peer hits 20 before finishing, it returns what it has — operator decides whether to continue. -8. **Don't silently paraphrase.** Relay the peer's actual response. If long, chunk it. Call out unverified claims. +8. **Long implementations hit the 600s foreground wall-clock limit.** A peer dispatch with `--max-turns 50` doing 30+ minutes of work (real implementation, multiple smoke tests with research-profile dispatches inside) can exceed the foreground command's 600-second timeout even when well within the turn budget. The peer may be terminated mid-task with no output, leaving the dispatch in an indeterminate state. **Mitigation:** for any peer dispatch expected to take more than ~5 minutes of wall-clock time, use the terminal tool's `background=true` + `notify_on_complete=true` mode instead of foreground. The peer runs to completion, you get notified on exit, and you spot-check the result. Real example (July 2026): dispatching a 9-task skill build (`better-search` implementation) to `ask-dev` with `--max-turns 50` hit the 600s foreground timeout during Task 5 (smoke test 2). Re-dispatching in background mode completed all 9 tasks. **Rule of thumb:** if the work involves 3+ smoke tests that each spawn their own research-profile dispatches, use background mode from the start. +9. **Don't silently paraphrase.** Relay the peer's actual response. If long, chunk it. Call out unverified claims. 10. **Peers can overstate findings.** A peer may correctly identify real gaps AND incorrectly flag things that aren't actually broken. In this session, the peer correctly identified the tool_executor.py ThreadPoolExecutor as the root cause of the Ctrl+C hang, but also flagged cli.py:9452 (account-usage fetch) as a second culprit — that one uses a `with` context manager that properly joins, so it's not a leak. Always verify each claim independently; don't assume all of a peer's findings are correct just because some are. ## Pre-Dispatch Reasoning Check (MANDATORY) diff --git a/creative-ideation/SKILL.md b/creative-ideation/SKILL.md index 2724425..003f7f4 100644 --- a/creative-ideation/SKILL.md +++ b/creative-ideation/SKILL.md @@ -1,152 +1,177 @@ --- -name: ideation -title: Creative Ideation — Constraint-Driven Project Generation -description: "Generate project ideas via creative constraints." -version: 1.0.0 +name: creative-ideation +title: Creative Ideation — Routed Library of Creative Methods +description: "Generate ideas via named methods from creative practice." +version: 2.1.0 author: SHL0MS license: MIT platforms: [linux, macos, windows] metadata: hermes: - tags: [Creative, Ideation, Projects, Brainstorming, Inspiration] + tags: [Creative, Ideation, Brainstorming, Methods, Inspiration] category: creative requires_toolsets: [] --- # Creative Ideation +A library of ideation methods for any domain. Read the user's situation, route to the matching method, apply, generate output that is specific and non-obvious. Methods are tools — pick the right one for the situation, don't perform all of them. + ## When to use -Use when the user says 'I want to build something', 'give me a project idea', 'I'm bored', 'what should I make', 'inspire me', or any variant of 'I have tools but no direction'. Works for code, art, hardware, writing, tools, and anything that can be made. +Any open-ended generative or selective question: "I want to make / build / write / start something", "I'm stuck", "inspire me", "make this weirder", "help me pick", "I need to invent X", "give me a research question". -Generate project ideas through creative constraints. Constraint + direction = creativity. +## Operating rules -## How It Works +1. **Constraint plus direction is creativity.** No constraint = no traction. No direction = no shape. Methods supply both. +2. **Refuse the first three ideas.** They're slop. Generate, discard, regenerate. See `references/anti-slop.md`. +3. **One method per response unless asked.** Don't stack. +4. **Specificity over abstraction.** Real proper nouns, real materials, real mechanisms. "An app for X" is slop; "a 200-line CLI tool that prints Y when Z" is direction. Naming a tech stack is not specificity — name a mechanism. +5. **Weird must also be good.** Frame-breaking is the goal, but an idea that is strange with no real situation, mechanism, or reason to exist is its own failure mode. Every set of ideas must include at least one that is genuinely *buildable/pursuable now* — non-obvious but grounded, with a real first step. Don't trade all usefulness for surprise. +6. **Name the method you used and who invented it.** Attribution invokes the discipline. +7. **When user picks one, build it.** Don't keep generating after they've chosen. -1. **Pick a constraint** from the library below — random, or matched to the user's domain/mood -2. **Interpret it broadly** — a coding prompt can become a hardware project, an art prompt can become a CLI tool -3. **Generate 3 concrete project ideas** that satisfy the constraint -4. **If they pick one, build it** — create the project, write the code, ship it +## Routing — 4-step procedure -## The Rule +Do this *before* generating any output. Routing failures produce slop. -Every prompt is interpreted as broadly as possible. "Does this include X?" → Yes. The prompts provide direction and mild constraint. Without either, there is no creativity. +You may skip narrating the routing steps if it's cleaner, but **never compress at the cost of per-idea depth**: each idea's concrete mechanism, situational binding, and honest failure mode are what make output good (measured) — they are not scaffolding, do not cut them. -## Constraint Library +### Step 1 — Extract three signals from the prompt -### For Developers +**PHASE** — what stage is the user in? -**Solve your own itch:** -Build the tool you wished existed this week. Under 50 lines. Ship it today. +| Phase | Cues | +|---|---| +| **GENERATING** | "give me an idea", "what should I make", "inspire me", no idea yet | +| **EXPANDING** | "what else", "more like this", "give me variations" — has a base idea | +| **SELECTING** | "help me pick", "which should I do", "I have these options" | +| **UNBLOCKING** | "I'm stuck", "blocked", "going in circles", "stale" — has material | +| **SUBVERTING** | "make it weirder", "less obvious", "this is too safe" | +| **REFINING** | "this is fine but missing something", "feels rough" | +| **SYNTHESIZING** | "I have a pile of notes / interviews / observations" | -**Automate the annoying thing:** -What's the most tedious part of your workflow? Script it away. Two hours to fix a problem that costs you five minutes a day. +**DOMAIN** — what is the user making/doing? -**The CLI tool that should exist:** -Think of a command you've wished you could type. `git undo-that-thing-i-just-did`. `docker why-is-this-broken`. `npm explain-yourself`. Now build it. +| Domain | Cues | +|---|---| +| **TEXT** | fiction, essay, poem, lyric, script, copy | +| **OBJECT** | visual art, music, sound, performance, installation, sculpture | +| **ARTIFACT** | software, hardware, mechanism, device | +| **SYSTEM** | org, civic, institution, ecology, community | +| **SELF** | life decision, career, personal practice | +| **RESEARCH** | paper, thesis, scholarly question | +| **PRODUCT** | business, market, service | -**Nothing new except glue:** -Make something entirely from existing APIs, libraries, and datasets. The only original contribution is how you connect them. +**SPECIFICITY** — how much constraint is in the prompt? -**Frankenstein week:** -Take something that does X and make it do Y. A git repo that plays music. A Dockerfile that generates poetry. A cron job that sends compliments. +| Level | Cues | +|---|---| +| **NONE** | "I'm bored", "inspire me" — no domain, no project | +| **DOMAIN** | "I want to write something" — knows the field, no project | +| **PROJECT** | "I'm working on this specific X" | +| **PROBLEM** | "I have this specific friction within X" | -**Subtract:** -How much can you remove from a codebase before it breaks? Strip a tool to its minimum viable function. Delete until only the essence remains. +### Step 2 — Apply overrides (highest priority, fire first) -**High concept, low effort:** -A deep idea, lazily executed. The concept should be brilliant. The implementation should take an afternoon. If it takes longer, you're overthinking it. +Override rules beat the routing table: -### For Makers & Artists +- **Mood signal** — user says "weird", "strange", "surprising", "less obvious", "more interesting" → `references/methods/lateral-provocations.md` or `references/methods/pataphysics.md`, regardless of domain. +- **User names a method** — use it. +- **User asks for a method recommendation** ("which method") → surface 2–3 candidates with one-line each, ask which to apply. Don't silently default. +- **High-slop terrain** — "AI ideas", "startup ideas", "habit tracker", "productivity / wellness / fitness / food / travel app" → force `references/methods/lateral-provocations.md` or `references/methods/pataphysics.md` over the obvious method. Refuse the first **5** ideas, not 3. -**Blatantly copy something:** -Pick something you admire — a tool, an artwork, an interface. Recreate it from scratch. The learning is in the gap between your version and theirs. +### Step 3 — Route by phase first, then domain -**One million of something:** -One million is both a lot and not that much. One million pixels is a 1MB photo. One million API calls is a Tuesday. One million of anything becomes interesting at scale. +**By phase (applies regardless of domain):** -**Make something that dies:** -A website that loses a feature every day. A chatbot that forgets. A countdown to nothing. An exercise in rot, killing, or letting go. +| Phase | Default route | +|---|---| +| GENERATING + SPECIFICITY=NONE | `references/full-prompt-library.md` **General** section (constraint dispatch) | +| GENERATING + DOMAIN known | route by domain (next table) | +| EXPANDING | `references/methods/scamper.md` | +| SELECTING | `references/methods/premortem-and-inversion.md` (or `references/methods/compression-progress.md` for upside) | +| UNBLOCKING | `references/methods/oblique-strategies.md` | +| SUBVERTING | `references/methods/lateral-provocations.md` (fallback `references/methods/pataphysics.md`) | +| REFINING (text) | `references/methods/defamiliarization.md` | +| REFINING (other) | `references/methods/creative-discipline.md` (Tharp's spine) | +| SYNTHESIZING | `references/methods/affinity-diagrams.md` | +| Volume needed fast | `references/methods/volume-generation.md` | -**Do a lot of math:** -Generative geometry, shader golf, mathematical art, computational origami. Time to re-learn what an arcsin is. +**By domain (when GENERATING with DOMAIN known):** -### For Anyone +| Domain | Default route | +|---|---| +| TEXT — formal / poetry | `references/methods/oulipo.md` | +| TEXT — narrative | `references/methods/story-skeletons.md` | +| TEXT — has source material to remix | `references/methods/chance-and-remix.md` | +| OBJECT (music, visual, performance) | `references/methods/oblique-strategies.md` | +| OBJECT — physical maker / wants a starting constraint | `references/full-prompt-library.md` **Physical / object** section | +| ARTIFACT — wants a starting constraint | `references/full-prompt-library.md` **Software / artifact** section | +| ARTIFACT — engineering invention with parameter conflict | `references/methods/triz-principles.md` | +| ARTIFACT — software architecture | `references/methods/pattern-languages.md` | +| ARTIFACT — has natural-system analog | `references/methods/biomimicry.md` | +| ARTIFACT — accumulated assumptions to question | `references/methods/first-principles.md` | +| SYSTEM (civic, org, institutional) | `references/methods/leverage-points.md` | +| SYSTEM — collective / participatory | `references/full-prompt-library.md` **Social / collective** section | +| SELF (life, career, what-to-study) | `references/methods/derive-and-mapping.md` | +| RESEARCH — picking a question | `references/methods/compression-progress.md` | +| RESEARCH — attacking a known problem | `references/methods/polya.md` | +| PRODUCT (business, service) | `references/methods/jobs-to-be-done.md` | +| Need to break a frame / find analogy | `references/methods/analogy-and-blending.md` | -**Text is the universal interface:** -Build something where text is the only interface. No buttons, no graphics, just words in and words out. Text can go in and out of almost anything. +### Step 4 — Handle ambiguity and contradiction -**Start at the punchline:** -Think of something that would be a funny sentence. Work backwards to make it real. "I taught my thermostat to gaslight me" → now build it. +- **Multiple paths plausible** → pick the one closest to the user's actual phrasing. Don't pick the most interesting method to seem sophisticated. +- **Genuinely ambiguous** → ask ONE clarifying question, don't silently guess. Examples: *"Are you generating ideas or picking between ones you have?"* / *"Is this for fiction, essay, or something else?"* +- **Signals contradict** (e.g., "weird startup ideas" → product domain + weird mood) → **stack two methods explicitly**. State what you're doing: *"Using `jobs-to-be-done` for the product framing + `lateral-provocations` to break the obvious shape."* +- **No match** → constraint dispatch (`references/full-prompt-library.md`) is the safe fallback. +- **Same question asked again** → switch methods. Variation in method = variation in idea distribution. -**Hostile UI:** -Make something intentionally painful to use. A password field that requires 47 conditions. A form where every label lies. A CLI that judges your commands. +### Anti-default check (run before generating) -**Take two:** -Remember an old project. Do it again from scratch. No looking at the original. See what changed about how you think. +- About to write "Here are 5 ideas:" or a bare numbered list? → STOP. Pick a method first. +- About to default to generic LLM-mode brainstorming? → STOP. Pick a path above. +- Output looks like what an unrouted LLM would produce? → routing failed, redo. -See `references/full-prompt-library.md` for 30+ additional constraints across communication, scale, philosophy, transformation, and more. +The default LLM mode is exactly what this skill exists to displace. If you generate without routing, you've defeated the skill. -## Matching Constraints to Users +For deeper edge cases (mood signals, stacking, anti-patterns) see `references/heuristics.md`. -| User says | Pick from | -|-----------|-----------| -| "I want to build something" (no direction) | Random — any constraint | -| "I'm learning [language]" | Blatantly copy something, Automate the annoying thing | -| "I want something weird" | Hostile UI, Frankenstein week, Start at the punchline | -| "I want something useful" | Solve your own itch, The CLI that should exist, Automate the annoying thing | -| "I want something beautiful" | Do a lot of math, One million of something | -| "I'm burned out" | High concept low effort, Make something that dies | -| "Weekend project" | Nothing new except glue, Start at the punchline | -| "I want a challenge" | One million of something, Subtract, Take two | +## Output format -## Output Format +For the constraint-dispatch default path: ``` -## Constraint: [Name] +## Constraint: [Name] — from [Source] > [The constraint, one sentence] ### Ideas 1. **[One-line pitch]** - [2-3 sentences: what you'd build and why it's interesting] - ⏱ [weekend / week / month] • 🔧 [stack] + [2-3 sentences — what specifically is made, why it's interesting] + ⏱ [weekend/week/month] • 🔧 [stack/medium/materials] -2. **[One-line pitch]** - [2-3 sentences] - ⏱ ... • 🔧 ... - -3. **[One-line pitch]** - [2-3 sentences] - ⏱ ... • 🔧 ... +2. ... +3. ... ``` -## Example +For other methods, use the format the method specifies (TRIZ produces a contradiction analysis; OuLiPo produces constrained text; Oblique Strategies produces a single applied card → next move). Don't force every method into the constraint template. -``` -## Constraint: The CLI tool that should exist -> Think of a command you've wished you could type. Now build it. +**Every idea set, regardless of method:** +- Name the method used. On slop terrain, name the obvious ideas you refused. +- Give each idea its concrete mechanism and its honest failure mode / tradeoff / who-it's-for. This depth is what makes ideas land — measured, not decorative. +- Mark at least one idea as the **grounded** one — buildable/pursuable now, non-obvious but with a real first step. The others can run further toward the strange; this one has to be genuinely doable. Don't let the whole set be weird-but-impractical. -### Ideas +## File map -1. **`git whatsup` — show what happened while you were away** - Compares your last active commit to HEAD and summarizes what changed, - who committed, and what PRs merged. Like a morning standup from your repo. - ⏱ weekend • 🔧 Python, GitPython, click - -2. **`explain 503` — HTTP status codes for humans** - Pipe any status code or error message and get a plain-English explanation - with common causes and fixes. Pulls from a curated database, not an LLM. - ⏱ weekend • 🔧 Rust or Go, static dataset - -3. **`deps why ` — why is this in my dependency tree** - Traces a transitive dependency back to the direct dependency that pulled - it in. Answers "why do I have 47 copies of lodash" in one command. - ⏱ weekend • 🔧 Node.js, npm/yarn lockfile parsing -``` - -After the user picks one, start building — create the project, write the code, iterate. +- `references/full-prompt-library.md` — constraint library, sectioned by domain (General, Software, Physical, Social, Lists). Default path for SPECIFICITY=NONE. +- `references/method-catalog.md` — one-line summary + when-to-use per method +- `references/heuristics.md` — extended decision tree for edge cases +- `references/anti-slop.md` — anti-slop rules; apply to every output +- `references/exercises.md` — time-boxed exercises (5min / 30min / 1hr / day / week) +- `references/methods/` — 22 named methods, one file each, load only the one you're using ## Attribution -Constraint approach inspired by [wttdotm.com/prompts.html](https://wttdotm.com/prompts.html). Adapted and expanded for software development and general-purpose ideation. +Constraint-dispatch core adapted from [wttdotm.com/prompts.html](https://wttdotm.com/prompts.html). Methods drawn from primary sources cited in each method file. diff --git a/deep-research/SKILL.md b/deep-research/SKILL.md index b4dd16b..311cd05 100644 --- a/deep-research/SKILL.md +++ b/deep-research/SKILL.md @@ -1,14 +1,14 @@ --- name: deep-research description: Dispatch exhaustive deep web research to the research profile. Triggered by "deep research", "ask web", or "research this". The research profile runs with the deep-web-research skill loaded — six-move flow, external ledger, mechanical saturation, disconfirmation, condensation from disk. -version: 2.3.0 +version: 2.4.0 author: Hermes Agent license: MIT platforms: [linux] metadata: hermes: - tags: [research, deep-research, delegation, web-search, scraping] - related_skills: [ask-hermes, ask-claude, ask-dev, deep-web-research, writing-plans] + tags: [research, deep-research, delegation, web-search, scraping, research-ladder] + related_skills: [ask-hermes, ask-claude, ask-dev, deep-web-research, writing-plans, better-search, searxng-smart-search] --- # deep-research — Exhaustive Web Research Delegation @@ -17,7 +17,7 @@ metadata: Dispatches a research question to the research profile, which runs with the `deep-web-research` skill loaded. The research agent does exhaustive, trail-following research — any tool, any trail, no rush — then condenses everything into a tight, concrete, evidence-backed answer. This agent just relays the result. -See `references/design-rationale.md` for the v2.0 architecture decisions and Claude validation findings. +See `references/design-rationale.md` for the v2.0 architecture decisions and Claude validation findings. See `references/research-ladder-and-two-skill-pattern.md` for the three-tier research ladder (`searxng-smart-search` / `better-search` / `deep-research`), the two-skill contract pattern (dispatcher + methodology), and the "don't overcomplicate" rule that emerged from the operator's plan-build sessions. See `references/inventory-before-dispatch.md` for the SSH probe script and workflow for inventorying a target box before dispatching environment-specific research. **Trigger phrases:** "deep research", "ask web", "research this", "deep dive on", "exhaustive research on" @@ -35,6 +35,13 @@ If the operator's question is ambiguous enough that the research agent would was - Do NOT ask when the research agent can sensibly find out (e.g., "What year did X happen?" — the research will find it). - Do NOT ask to delay dispatching. Asking is a cost, not a hedge. +**Scope dimensions to confirm before dispatch (high-value, often-missed):** +Beyond the question's subject, confirm any dimension that changes the *output shape* of the plan/research. Missing one forces a kill + re-dispatch mid-run, wasting the first session's turns. Known dimensions: +- **Hardware/environment target** — when the deliverable maps tools to specific hardware (e.g., "build a local pipeline on our hardware"), confirm *which* hardware before dispatch. Do not assume the full fleet from memory; the operator may be scoping to a single box. This is the #1 missed dimension. +- **Cloud vs. local vs. hybrid** — when a workflow could be replicated with cloud APIs, local self-hosted, or a mix, confirm which before dispatch. +- **Build-on-existing vs. fresh** — when the target environment already has partial tooling installed, confirm whether to reuse it or design from scratch. +These are NOT generic clarifying questions — they are scope axes specific to plan-building research. Ask at most one `clarify` round covering whichever of these are genuinely unresolved before dispatching. + **Multi-turn narrowing:** If after 1–2 rounds of clarifying questions the scope is still unclear, abandon the dispatch and ask the operator to rewrite the question with the scope made explicit. Do not loop. ## Command @@ -46,6 +53,7 @@ hermes -p research -s deep-web-research chat -q "" -Q --max-turns 600 - Output line 1: `session_id: ` — capture this - The research agent writes the condensed answer to `~/workspace/research/results/-.md` - Hold the session_id for follow-up questions +- **Session_id capture pitfall (background dispatch):** When run as a background process, the output begins with a TUI banner (OS/hostname/IP block) + an initial reasoning block BEFORE the session_id line appears. Piping through `| head -20` can truncate the output before the session_id is reached. Use a larger head (`| head -50`) or, better, `grep -oE 'session_id: [a-f0-9-]+'` on the full log to extract it reliably. If the session_id is lost, `session_search` on the research profile may NOT find `-Q` quiet-mode sessions — in that case, do NOT re-dispatch Stage 3 of the validate-fix pipeline; apply validated corrections directly to the plan file yourself (you have the full plan text + validation report). This is equally correct and avoids a redundant 600-turn run. **Subsequent asks (resume the session):** ``` @@ -64,17 +72,20 @@ hermes -p research -s deep-web-research chat --resume -q "-.md`. Do NOT inline the answer — the file is the source of truth. +**This rule is operator-standing and applies to all research delegation skills** (`deep-research`, `better-search`, and any future research-delegation skill). Even "checking once after a delay" violates the rule. The operator reads the result file when they want to. + The session_id is captured from output line 1 and held in conversation context for follow-up questions and result retrieval. No state file needed. ## What the Research Agent Does @@ -119,7 +130,19 @@ The research agent must determine the best tools for each research type — not - User wants current, verified, cross-referenced information - Phone number lookup, person research, topic investigation, fact verification -## When NOT to Use +## When NOT to Use (research ladder — pick the right tier) + +The research ladder has three tiers. Pick the cheapest one that fits the question: + +| Tier | Skill | Loops | Use when | +|---|---|---|---| +| Light | `searxng-smart-search` (inline MCP) | 1 | Single factual lookup, single search suffices | +| Medium | `better-search` | 1–3 | "Look into X", "do a better search", 2–3 targeted searches with AI evaluation | +| Heavy | `deep-research` (this skill) | Many (200+) | "Map the X landscape", OSINT, exhaustive coverage, contradiction-hunting | + +**Routing decision belongs to the operator, not the dispatcher.** If the question is "what is the capital of France?", use `searxng-smart-search` directly. If it's "look into the latest X", use `better-search`. Only escalate to `deep-research` when the operator explicitly wants exhaustive multi-source work. + +**Do NOT use `deep-research` for:** - Simple factual question (capital of France, current time) - Question I can answer from a single search @@ -151,16 +174,24 @@ The research agent self-reports are not verified fact. If it claims a file write 6. **Don't do the research yourself.** If the user triggers deep research, dispatch it. Don't run a few searches and call it done. This is the #1 failure mode: the agent runs 2-3 `mcp_searxng_searxng_web_search` calls, gets empty results, and gives up. That's not deep research — that's a casual lookup. If you catch yourself typing `mcp_searxng_searxng_web_search` for a deep research request, STOP. You're doing it wrong. Dispatch to the research profile. 7. **The methodology skill lives on the research profile.** `deep-web-research` is at `~/.hermes/profiles/research/skills/research/deep-web-research/SKILL.md`. It does NOT exist on the general profile. Don't search for it here — it won't be found. The general profile only has this delegation skill. 8. **Dispatcher/methodology coordination is a two-skill contract.** This skill (the dispatcher) caps clarifying questions at 5 default / 10 max and aborts the dispatch if the question is under-specified. The `deep-web-research` methodology skill (on the research profile) handles the same problem differently because it's headless — it can't ask the operator, so it aborts with a structured under-specification report naming the plausible interpretations. When updating one, update the other to match. Drift between the two causes the dispatcher to think the question is dispatchable while the methodology aborts it, or vice versa — both waste turns. +9. **Confirm hardware/environment scope before dispatching a hardware-mapped plan.** If the deliverable maps tools to specific hardware, confirm *which hardware* before dispatch — do not assume the full fleet from memory. The operator may be scoping to a single box (e.g., "I'll provide one LXC"). A 600-turn research artifact built against the wrong hardware scope has its architecture, parallelization, and GPU-scheduling sections wrong and must be killed and re-dispatched. Cheaper to ask one `clarify` round than to re-run 600 turns. (Learned 2026-07-07: dispatched a microdrama-pipeline plan against the full fleet; operator corrected to a single LXC; had to kill and re-dispatch.) +10. **Inventory the target box before dispatching environment-specific research.** When the plan must build on an existing install, SSH in and inventory the real state (GPU, RAM, disk, running services, installed models/nodes/packages) *before* dispatching, and pass the exact inventory into the research prompt. This lets the research agent research only the genuinely missing pieces instead of guessing or re-researching what's already installed. See `references/inventory-before-dispatch.md` for the probe script. -## Pre-Dispatch Reasoning Check (MANDATORY) +## Pre-Dispatch Reasoning Check (do NOT mutate the research profile's config) -Before EVERY deep research dispatch, set the research profile's reasoning_effort to `max`. This is a hard gate — do not dispatch without it. +**Do NOT call `hermes -p research config set agent.reasoning_effort max` before dispatching.** That is a persistent side-effect — it writes to the research profile's `config.yaml` and the change survives the dispatch, affecting every subsequent research-profile session (interactive use, cron jobs, other research delegations). -``` -hermes -p research config set agent.reasoning_effort max +**Correct approach:** The research profile's `agent.reasoning_effort` is already set to a thorough value by the operator (operator's standing rule: thoroughness > speed; thoroughness > tokens). Read it before dispatching to confirm it's at a high value, but do NOT write to it: + +```bash +# Read-only check — confirm reasoning_effort is set +grep -E "default:|reasoning_effort:" ~/.hermes/profiles/research/config.yaml | head -5 +# If it's NOT at max for the model, warn the operator — don't silently fix it ``` -`max` is the highest effort setting universally supported by all models. No model-specific table needed. If the model changes to one that supports `xhigh`, the user will set it in config — the pre-dispatch check just ensures it's at `max` minimum. +If the operator wants a different reasoning effort for this specific dispatch, they set it themselves; the dispatcher does not mutate other profiles' configs on every invocation. The "max" value the operator wants is achieved by the operator setting it once in `config.yaml`; the dispatcher reads and confirms, never writes. + +This rule also applies to all research-dispatching skills (`better-search`, future research delegation skills). The dispatcher is not authorized to mutate the target profile's config. ## Research → Validate → Fix Pipeline diff --git a/dynamic-workflow/SKILL.md b/dynamic-workflow/SKILL.md new file mode 100644 index 0000000..2844c00 --- /dev/null +++ b/dynamic-workflow/SKILL.md @@ -0,0 +1,209 @@ +--- +name: dynamic-workflow +description: Orchestrate large fan-out work as a plan-in-code "workflow" so the agent's context holds only the final verified answer, not the exhaust of hundreds of intermediate steps. Use for codebase-wide sweeps, large migrations, multi-angle research, and any task too big for one context window where the split strategy is known enough to script. Includes the adversarial-convergence verification recipe (independent attempts + refuters, keep only surviving claims). +version: 1.0.0 +author: Hermes Agent + Teknium +license: MIT +metadata: + hermes: + tags: [orchestration, fan-out, subagents, delegation, verification, migration, audit, research] + category: autonomous-ai-agents + related_skills: [] +when_to_use: + - A task is too big for one context window AND you can describe the split (per-file, per-endpoint, per-source, per-record) + - You want orchestration codified as a re-runnable script, not improvised turn-by-turn + - Quality matters more than token economy: you want independent attempts cross-checked / refuted before you trust the answer + - Codebase-wide bug/security sweep, 100+ file migration, multi-angle research with sources cross-checked +when_not_to_use: + - Small bounded task (<~10 units) — just call the tool directly or do it inline + - Tight serial dependency (B needs A's output) — orchestration overhead is wasted + - You need it to survive the user sending a new message — see "The synchronous trap" below; use cron/kanban instead +--- + +# Dynamic Workflow — plan-in-code fan-out with verification + +This is Hermes's answer to Claude Code's "dynamic workflows" (run hundreds of +parallel subagents in one session). The mechanic worth copying is NOT "more +subagents" — it is **moving the plan, the loop, and the intermediate results +OUT of the context window and INTO a script.** Normally the agent IS the +orchestrator: every intermediate result piles into context, which is exactly +what caps you at a handful of agents. A workflow keeps only the *final verified +answer* in context; the script holds everything else. + +> This skill is self-contained, but it builds on standard fan-out hygiene — +> chunk inputs to ~50-70KB per child, route structured output to files (not the +> `summary` field, which truncates under load), use delimiter-separated lines +> over JSON wrappers, and remember that a "stalled" child often completed its +> write anyway (check the filesystem before retrying). If your install has a +> `delegate-task-output-patterns` skill, load it for the detailed thresholds; +> the rules above are the load-bearing subset. + +## The two orchestration-script layers (pick the right one — they are NOT interchangeable) + +Hermes has no JS runtime. The "orchestration script" is one of two layers, and +the split is enforced by a real capability boundary, not a style preference: + +| | Layer A: `execute_code` (Python script) | Layer B: `delegate_task` batch | +|---|---|---| +| Use for | DETERMINISTIC fan-out — fetch N URLs, parse N files, run N shell commands, template N outputs | LLM-JUDGMENT fan-out — classify, review, decide, write, refute, audit per item | +| The script holds | the loop + branching + intermediate vars (real Python) | n/a — you call it once with a `tasks=[...]` array; each task is its own isolated agent | +| Tools available inside | `web_search, web_extract, read_file, write_file, search_files, terminal, patch` ONLY (the `SANDBOX_ALLOWED_TOOLS` set) | configured child toolsets, subject to delegate restrictions (leaf children are stripped of `delegate_task`, `clarify`, `memory`, `send_message`, `execute_code` — see `DELEGATE_BLOCKED_TOOLS`) | +| Can it call `delegate_task`? | **NO.** `delegate_task` is NOT in `SANDBOX_ALLOWED_TOOLS`. Do not write a script that imports it — it will fail. | itself, if `role='orchestrator'` and `max_spawn_depth>=2` | +| Concurrency | you control it in Python (`ThreadPoolExecutor`, batches) | `delegation.max_concurrent_children` (default 3; raise in config.yaml) | +| Cost shape | cheap — most steps are tool calls, no per-item LLM unless you call `web_search`/aux | one model call tree PER child task — multiplies linearly, can be very expensive | + +**Rule of thumb:** do the deterministic part in Layer A first (inline, in a +script), then fan out ONLY the irreducibly-LLM step via Layer B. This is +Pattern 1 from `delegate-task-output-patterns`, applied at workflow scale. +Mixing them: a Layer-A script can write a manifest file, and you (the parent) +then read that manifest and issue a single Layer-B `delegate_task` batch. + +## The synchronous trap (READ THIS — it is the #1 way a "workflow" disappoints) + +`delegate_task` runs **synchronously inside the parent turn**. If the user sends +a new message, hits /stop, or /new, every in-flight child is **cancelled and its +work discarded** (status `interrupted`). It does NOT run in the background, and +it does NOT survive the turn. There is no cache-resume of a half-finished fan-out. + +So a "workflow" in Hermes is one of: + +1. **Foreground workflow (default):** Layer A and/or one Layer-B batch, completed + within a single turn. Good for minutes-long fan-out (dozens of units). The + user waits. This is what you build 90% of the time. +2. **Durable workflow (hours/days, survives interruption):** use the **kanban + swarm** (the SQLite-backed multi-agent kernel that ships with Hermes — + `hermes_cli/kanban_swarm.py` + the kanban plugin; if your install has a + `kanban-multiagent` skill, load it for the workflow). It + writes a task graph (root → parallel workers → verifier → synthesizer) into + the SQLite kanban kernel with a JSON blackboard. State persists across turns + and restarts. This is the ONLY path that matches Claude Code's "runs into + hours and days, resumes where it left off." Reach for it when the foreground + path would time out or when the user must be able to walk away. + +Never promise "background, resumable, hundreds of agents over days" from a plain +`delegate_task` call. For a durable multi-agent workflow *graph*, the kanban +swarm is the right fit. For simpler durable/out-of-turn cases there are lighter +options too: a `cronjob` one-shot or scheduled job, or a managed +`terminal(background=True, notify_on_complete=True)` process — both survive the +turn without standing up a full task graph. + +## Workflow recipe (foreground) + +1. **Decompose into independent units.** What is the unit — a file? an endpoint? + a source? a record? Each unit must be answerable WITHOUT the others' output + (else it's serial, not fan-out — see when_not_to_use). +2. **Deterministic pre-pass (Layer A).** In one `execute_code` script, gather the + manifest: list the files, extract the candidate sites, fetch the raw sources, + compute anything regex/parse can compute. Write a manifest to a **unique + per-run** directory — `/tmp/wf__/manifest.jsonl` (one unit per + line), never a bare `/tmp/wf_/` that a prior interrupted run could have + left stale outputs in. This is the "plan in code." Print the unit count and + the run dir, and stop. +3. **Size the fan-out** against `delegate-task-output-patterns`: chunk so each + child handles ~8-12 mechanical file edits OR ~2000-3000 lines of reading OR + ~50-70KB of corpus. Look at the LARGEST unit, not the average. One + `delegate_task(tasks=[...])` call is bounded by + `delegation.max_concurrent_children` (default 3) — it does NOT queue hundreds + of tasks internally. For larger fan-out, issue bounded waves yourself (loop: + one batch, collect, next batch) or have the user raise the config + intentionally. +4. **LLM-judgment fan-out (Layer B).** Issue ONE `delegate_task` with a `tasks=[]` + array, one task per chunk. Each task: reads its slice from the manifest, + emits delimiter-separated lines to `/tmp/wf__/out_.csv`, prints a + status word, stops. Do NOT depend on the `summary` field for content. +5. **Synthesize on the parent.** Read the out_*.csv files yourself — verify the + file count and freshness (each was written this run) so a stale or missing + output from an interrupted child isn't silently read as success — then merge + and present. The cross-cutting "whole picture" step stays on the parent — only + the per-unit work fanned out. + +## The novel mechanic worth building: adversarial convergence + +This is the part Hermes did NOT already have and the real reason to bother. +Claude Code's quality claim ("independent agents try to refute each other's +findings; only surviving claims surface; iterate until they converge") maps +cleanly onto `delegate_task` batch mode: + +### Recipe: N independent attempts + M refuters + +For a finding-quality task (security audit, "is this code path actually +vulnerable?", "does this migration preserve behavior?", a high-stakes plan): + +1. **Independent attempts (round 1).** Fan out the SAME question to N children + (N=2-4) with DIFFERENT framings/angles in each `context`, so they don't + collapse to the same reasoning. Each writes its claims to + `/tmp/wf_/attempt_.md` as a list of discrete, individually-checkable + claims (one claim per line — atomicity is what makes refutation possible). +2. **Collect + dedupe (parent or Layer A).** Merge all claims into a single + numbered list. Identical claims from independent attempts = higher prior; + note the agreement count per claim. +3. **Refutation round (round 2).** Fan out a refuter batch: each refuter gets the + claim list and is told "your job is to BREAK these claims — for each, find the + counter-evidence (the auth check that DOES exist, the test that DOES cover it, + the edge case the claim ignores). Output `claim_idx|survives|counter_evidence`." + Give refuters the codebase/sources, not the original attempts' reasoning. +4. **Keep only survivors.** A claim surfaces to the user only if it survived + refutation (no refuter produced valid counter-evidence). Filtered claims are + dropped, with a one-line note of why if the user asked for completeness. +5. **Converge (optional).** If round 2 surfaced NEW claims (refuters often find + adjacent issues), feed them back through one more refutation round. Stop when + a round produces no new surviving claims — that's convergence. Cap at 3 rounds + to bound cost. + +This gives you the "more trustworthy than a single pass" property without a +runtime — it's just two `delegate_task` batches and a merge, structured so +disagreement is visible and unsupported claims die before they reach the user. + +### Why atomic claims matter +A refuter cannot break "the auth layer has problems." It CAN break "endpoint +`POST /api/users/:id/role` in src/routes/users.ts:142 has no role check." Force +attempts to emit specific, located, individually-falsifiable claims or the +refutation round is theater. + +## Cost discipline (this is the thing that bites) + +A workflow can consume dramatically more tokens than a normal turn — that is +inherent, not a bug. Two real multipliers: + +- **Each Layer-B child is a full agent tree.** 20 children ≈ 20× the model calls. + `delegation.max_concurrent_children` only bounds *concurrency*, not *total*. +- **Hermes aux/subagent model defaults to main-model-first.** Children inherit + the parent's (often expensive reasoning) model. `delegate_task` does NOT expose + a per-task `model` or `profile` field — its per-task keys are + `{goal, context, toolsets, role}`. To run the fan-out cheaper you either route + delegation globally via `delegation` config (model/provider applied to all + children), or — for genuinely model/profile-scoped work — use cron, the kanban + swarm, or a separate Hermes process. The cleanest lever for mechanical fan-out + is still Layer A: do the deterministic part in a script with no per-item LLM at + all. + +Always: start on a SCOPED slice (one directory, 20 records, 10 endpoints), prove +the recipe end-to-end, report the token cost, THEN offer to run it at full scale. +Never silently fan out hundreds of children — surface the cost first and let the +user say go. + +## Pitfalls + +- **Writing `delegate_task` inside an `execute_code` script.** It's not in + `SANDBOX_ALLOWED_TOOLS`; the import/stub won't exist. Layer A is deterministic + tools only. Fan out LLM judgment from the parent turn, not from inside a script. +- **Promising background/resumable from `delegate_task`.** It's synchronous and + turn-scoped. Durable = kanban swarm. +- **Trusting `summary` fields for content.** Route structured output to files + (Pattern 2 in delegate-task-output-patterns). +- **Non-atomic claims in the verify recipe.** Unfalsifiable claims survive + refutation by default and pollute the output. Force located, specific claims. +- **Same framing in all "independent" attempts.** They collapse to one answer and + the cross-check is worthless. Vary the angle in each child's context. +- **Fanning out a serial task.** If unit B needs unit A's output, parallelism + produces wrong/empty results. Re-check independence before fanning out. + +## Verification before you call it done + +- Did the deterministic pre-pass actually run, and does the manifest line-count + match the expected unit count? (`wc -l /tmp/wf_/manifest.jsonl`) +- Did every fan-out child write its output file? (`ls /tmp/wf_/out_*.csv`) — + remember stalled children often completed anyway (Pattern 6). +- For the verify recipe: can you point to the refuter counter-evidence for every + DROPPED claim, and confirm every SURFACED claim went through refutation? +- Did you report token cost on the scoped run before offering full scale? diff --git a/equipment-knowledge-base/SKILL.md b/equipment-knowledge-base/SKILL.md new file mode 100644 index 0000000..71fdbc3 --- /dev/null +++ b/equipment-knowledge-base/SKILL.md @@ -0,0 +1,171 @@ +--- +name: equipment-knowledge-base +description: "Build and maintain a Qdrant knowledge base for vehicles, tools, and equipment — OEM part numbers, maintenance schedules, specs, and cross-references. Free materials only, no shopping links." +version: 1.0.0 +category: productivity +tags: [equipment, vehicles, parts, maintenance, qdrant, knowledge-base] +related_skills: [local-vector-memory, qdrant-collection-management, searxng-smart-search] +--- + +# Equipment Knowledge Base + +Build a searchable Qdrant knowledge base for vehicles, tools, and equipment — OEM part numbers, maintenance schedules, fluid specs, cross-references, and dimensions. Designed for queries like "what's the oil filter for my Ranger" or "what oil weight does my tractor take." + +## When to Use + +- User wants to store manuals, part numbers, and specs for their vehicles/equipment +- User says "I want a collection for my equipment" or "store part numbers for my [vehicle]" +- User wants to query across vehicles ("what oil do all my gas engines use?") + +## User Preferences (HARD — do not violate) + +- **Free materials only.** Never suggest or purchase paid service manuals without explicit user approval. +- **No shopping links.** The user explicitly said: "I don't need to store shopping links. I just need to make sure part numbers are accurate and correct." Do NOT embed Walmart, Amazon, or other purchase links. Part numbers and cross-references only. +- **Accuracy over breadth.** Part numbers must be sourced from OEM documentation (owner's manual, official parts fiche). Forum cross-references are secondary — flag them as such. +- **Keep pricing details.** When purchase agreements, invoices, or registration emails are found, record the price, serial number, dealer, and date in the part-numbers doc under a `## Purchase Information` section. Include trade-in values and tax breakdowns when available. + +## Collection Schema + +Single collection: `equipment` (1024-dim, Cosine, Qdrant at 10.0.0.22:6333). + +Every point payload should carry: + +```json +{ + "text": "The searchable content chunk", + "vehicle": "2023-polaris-ranger-sp-570", + "vehicle_label": "2023 Polaris Ranger SP 570 Midsize", + "vehicle_type": "utv | atv | dirt-bike | zero-turn | tractor | excavator", + "category": "oem-part-numbers | maintenance-schedule | specifications | cross-reference | forum-knowledge", + "part_number": "2540086", + "part_type": "oil-filter | air-filter | spark-plug | belt | tire | battery | fluid | etc", + "source_type": "oem-manual | forum | parts-fiche", + "source_url": "https://publications.polaris.com/...", + "retrieved": "2026-07-12" +} +``` + +## Vehicle Registry + +Maintain a registry in the workspace AGENTS.md. Each vehicle gets a key, label, and type. Example: + +| Key | Label | Type | +|-----|-------|------| +| `2023-polaris-ranger-sp-570` | 2023 Polaris Ranger SP 570 Midsize | utv | + +## Workflow (per vehicle) + +### 1. Research OEM Part Numbers +- Primary source: manufacturer's owner's manual (free PDF or online portal) +- Search SearXNG for: `[year] [make] [model] owner's manual part numbers` +- Pull the specifications page and maintenance section via `web_url_read` +- Extract: spark plug type/gap, oil type, fluid types and capacities, tire sizes/pressures +- **IMPORTANT: Owner's manuals typically do NOT list filter/belt part numbers.** Polaris and John Deere owner's manuals list specs but not consumable part numbers. Those are in the separate parts catalog. For filters and belts, cross-reference from: + - Manufacturer's "quick parts guide" or "replacement parts guide" PDF (e.g., Deere's `z515e-with-48-54-60-inch-deck.pdf`) + - Brand-specific forums (prcforum.com for Polaris, etc.) + - Aftermarket kit listings that confirm fitment across years + - **Always flag cross-referenced numbers** — do not present them as OEM-verified + +### 2. Cross-Reference (Secondary) +- Search forums (prcforum.com for Polaris, etc.) for cross-reference threads +- Extract aftermarket equivalents (WIX, NAPA, Mobil 1, K&N, etc.) +- Flag as "forum-sourced" — not OEM-verified + +### 3. Maintenance Schedule +- Pull the full maintenance schedule from the owner's manual +- Include intervals, fluid capacities, torque specs +- Note severe-use caveats (50% interval reduction) + +### 4. Write Structured Markdown +- One doc for part numbers + specs +- One doc for maintenance schedule +- Store in `~/workspace/equipment/` as `-part-numbers.md` and `-maintenance.md` +- Include source URL and retrieval date + +### 5. Ingest into Qdrant (IMMEDIATELY after writing) +- Use `mcp_better_qdrant_add_documents` for BOTH markdown files in the same turn +- Target collection: `equipment` +- Embedding service: `ollama` +- **Do NOT wait for the user to say "go" or "ingest."** After writing the .md files, immediately call add_documents for both. The user explicitly said "automatically add all to collections." + +### 6. Verify Queryability +Run 1-2 test queries (not 3 — keep it fast): +- "what is the oil filter part number for [vehicle]" +- "[vehicle] tire pressure" or "[vehicle] oil capacity" + +Scores 0.5+ are good. Below 0.4 means chunking or query mismatch. + +### 7. Search Email for Purchase Documents +Before building docs for a new vehicle, search the user's email for purchase agreements, invoices, and registration notices. These contain serial numbers, pricing, dealer info, and exact model configurations that owner's manuals don't. + +- Use `himalaya envelope list` with `from ` and `from ` queries +- Search across ALL folders — purchase docs may be in INBOX, RECEIPTS, or custom folders +- Download PDF attachments with `himalaya attachment download` and extract with pymupdf (or tesseract fallback for scanned docs) +- Record findings in the part-numbers doc under `## Purchase Information` +- Key fields: dealer name, date, serial number/VIN, price, trade-in, tax, warranty terms +- If no purchase docs found, note it explicitly — don't fabricate + +## Querying the KB (Answering User Questions) + +When the user asks a question about their equipment (e.g., "what tools for an oil change," "what's the interval for X"): + +1. **Query Qdrant first.** Search the `equipment` collection for what the KB already has — part numbers, maintenance schedules, fluid specs. +2. **Identify the gap.** The KB has specs and schedules but typically does NOT have step-by-step procedures, tools lists, or torque sequences. Those live in the owner's manual or Polaris help center articles. +3. **Web search to fill the gap.** Search SearXNG for the specific procedure (e.g., `"[year] [model] oil change procedure tools"`). Polaris help center articles (KA-XXXXX) often have the full tools list and steps. +4. **Combine and present.** Merge Qdrant data (part numbers, fluids, capacities) with web-sourced procedure details (tools, steps, torque specs). Cite both sources. + +### When the user asks for a product on a specific retailer (Walmart, Amazon, etc.) + +- **Search the retailer directly** — use `site:walmart.com` or `site:amazon.com` in the SearXNG query. General web searches return forum threads and third-party sites; retailer-specific searches surface actual product listings. +- **Verify fitment before recommending.** Cross-check the product's listed compatibility against the vehicle's known specs (model year, trim level, chassis type). Many listings claim broad compatibility that is wrong (e.g., "fits Ranger 570" but only fits Full Size, not SP 570 midsize). +- **Walmart product pages are Cloudflare-blocked for `web_url_read`** — you'll get a "Robot or human?" captcha page. Use the SearXNG search snippet for price, specs, and part number. The snippet is usually sufficient. +- **For oil change kits:** confirm the quart count matches the vehicle. The 570 takes 2 qts (kit #2890056 or #2202166). The XP 1000 takes 2.5 qts (kit #2879323). Recommending the wrong kit means the user gets the wrong oil quantity. + +## Pitfalls + +- **Cloudflare blocks on parts sites.** polaris.com, partzilla.com, rockymountainatvmc.com all use aggressive Cloudflare bot detection. The browser tool (Browserbase) has its own IP separate from the host VPN — it may be blocked even when the host VPN is fresh. Use SearXNG `web_url_read` for Polaris's publications portal (publications.polaris.com) which is NOT Cloudflare-protected. For parts fiche sites, fall back to SearXNG search snippets if direct access is blocked. +- **Polaris help center (polaris.com/en-us/off-road/owner-resources/help-center/) is Cloudflare-blocked.** `web_url_read` on KA-XXXXX articles returns 403. However, SearXNG search snippets for these articles often contain the full procedure text (tools list, steps, torque values). Use the search snippet as the primary source when the article itself is blocked — the snippet is usually complete enough to answer the question. +- **SearXNG is in a separate LXC (10.0.0.8:8888), not behind the host VPN.** It has its own IP. If SearXNG returns empty results, the issue is with SearXNG's engines, not the host VPN. The `web_search` tool and `web_extract` go through the host VPN — if SearXNG works but these don't, the host VPN IP is likely flagged. +- **NordVPN reconnect for fresh IP.** The host runs NordVPN 5.2.0. If sites block the host IP, reconnect: `nordvpn disconnect && nordvpn connect us `. Agent is authorized to reconnect without asking. Any other NordVPN settings changes require user permission. Current settings: NordLynx, kill switch on, firewall on, post-quantum on, allowlisted ports 53 + 11434, subnet 34.36.133.0/24. +- **Don't confuse owner's manual with service manual.** The free owner's manual has specs, fluid capacities, and maintenance schedules. The paid service manual has repair procedures, torque specs for every bolt, wiring diagrams. The user only wants free materials — owner's manual is sufficient for the KB. +- **Owner's manuals often don't list filter/belt part numbers.** Polaris manuals list spark plug type, oil type, and fluid capacities but NOT oil filter, air filter, or drive belt part numbers. Those are in the separate Polaris parts catalog (paid or dealer-only). Cross-reference from forums and aftermarket kit listings, but FLAG these as cross-referenced, not OEM-verified. Example: "Oil Filter (OEM): 2540086 (cross-referenced — same filter used across Polaris 570/1000 models)". +- **Part number supersessions.** OEMs sometimes supersede part numbers (e.g., air filter 2521372 → 7082037). Note both, with the current number first. +- **Forum cross-references may be for different years.** A 2014 Ranger 570 cross-reference thread may not apply to a 2023 SP 570. Verify compatibility before embedding. +- **Spark plugs vary by engine serial number.** Some manufacturers (John Deere) don't list a single plug number in the quick parts guide — it depends on the specific engine. Note this caveat and tell the user to check the engine blower housing for the serial number. +- **CAT parts are serial-number specific.** Caterpillar parts catalogs require the machine serial number prefix (e.g., BDH for 301.5). Fuel and hydraulic filter part numbers vary by serial number. Always tell the user to confirm with a CAT dealer using their serial number. The engine oil filter (150-4140 for C1.1/3003) is one of the few parts that crosses multiple models. +- **Some engines have no replaceable oil filter.** Small Honda engines (CRF50F, CRF70F, XR50R, XR70R) use a centrifugal oil screen that must be cleaned during oil changes — there is no cartridge or spin-on filter to replace. Note this explicitly so the user doesn't go looking for a part that doesn't exist. +- **Oil change intervals can vary by model number within the same year.** The 2024 Polaris Sportsman 570 has some model numbers (A24SEE57B1, etc.) that use a 100-hour oil change interval while others use 200-hour. Check the owner's manual for model-number-specific notes and flag this for the user. +- **Deck/belt size variants on mowers.** Zero-turn mowers often have multiple deck sizes (48"/54"/60"). Confirm which deck the user has before recording blade and belt part numbers. The parts guide may list all variants — only record the one that matches. +- **Don't fabricate part numbers.** If a number can't be confirmed from an official or well-established source, say so explicitly. The user values accuracy over completeness. +- **marker-pdf is unreliable on Python 3.13.** `pip install marker-pdf` installs but `marker_single` fails with cascading missing deps (pdftext → ftfy → surya). When you need OCR on scanned PDFs and marker-pdf is broken, use the tesseract fallback: pymupdf → PNG export → pytesseract. See `references/tesseract-fallback.md` for the recipe. +- **PDFs from Deere.com are text-based.** The John Deere replacement parts guides and filter overviews on deere.com are text-layer PDFs — pymupdf extracts them directly, no OCR needed. Only scanned dealer invoices/agreements need OCR. +- **`web_url_read` returns raw PDF binary for PDF URLs.** When fetching PDFs from deere.com or similar, `web_url_read` returns the raw PDF bytes, not extracted text. Download with `curl -sL -o /tmp/file.pdf ""` then extract with pymupdf instead. +- **`web_url_read` section extraction fails on XML content.** publications.polaris.com serves owner's manuals as XML, not markdown. The `section` parameter silently returns "not found" because the heading structure doesn't match. Workaround: fetch without a `section` filter and parse the raw content, or rely on SearXNG search snippets which often contain the full procedure text. +- **Base model SP 570 headlight bulbs are a trap.** The OEM part #4010253 cross-references to 881/886 PG13 bulbs, but these do NOT physically fit the base model connector. H13/9008 dual-beam bulbs also don't fit (base model is single-beam, 2-prong). The only guaranteed path: (1) pull the existing bulb and read the stamped number, or (2) buy the OEM LED assembly kit #2889877. Do NOT recommend a bulb type without the user confirming the stamped number on their existing bulb. See `references/ranger-sp570-headlight-bulbs.md` for the full failure history. + +## Workspace + +- Path: `~/workspace/equipment/` +- AGENTS.md: scopes the collection, declares vehicle registry, lists out-of-scope collections +- Source markdown files live here before ingestion + +## Related Skills + +- `local-vector-memory` — Qdrant stack setup, embedder config, MCP tools +- `qdrant-collection-management` — collection CRUD, schema, registry +- `searxng-smart-search` — search defaults for parts/manual research +- `himalaya` — email CLI for searching purchase documents and invoices + +## References + +- `references/email-purchase-search.md` — pattern for searching Gmail for purchase agreements, invoices, and registration notices via Himalaya CLI +- `references/ranger-sp570-example.md` — example part-numbers doc +- `references/tesseract-fallback.md` — OCR recipe when marker-pdf is broken +- `references/polaris-cross-model-reference.md` — Polaris part number cross-model compatibility +- `references/nordvpn-reference.md` — NordVPN reconnect procedure +- `references/ranger-sp570-oil-change.md` — Ranger SP 570 oil change: tools, supplies, drain plug specs, torque, intervals +- `references/ranger-sp570-accessory-wiring.md` — Ranger SP 570 ACC wire location, pulse bar vs terminal block, fuse, wiring guidance +- `references/ranger-sp570-aftermarket-exhaust.md` — Aftermarket exhaust options for SP 570 midsize (very limited — Big Gun only potential fit) +- `references/ranger-sp570-headlight-bulbs.md` — Headlight bulb replacement: what doesn't fit (H13, 881/886, Sixty61), confirmed bulb type (9006/HB4), OEM LED upgrade kit #2889877, forum consensus +- `references/ranger-sp570-front-gearcase-fluid.md` — Front gearcase (Demand Drive) fluid change: capacity, tools, torque, Walmart link, interval +- `references/ranger-sp570-under-hood-power-setup.md` — Under-hood accessory power distribution: fuse block, wiring, complete Walmart shopping list, installation strategy diff --git a/gitea/SKILL.md b/gitea/SKILL.md index 14b7678..a81069a 100644 --- a/gitea/SKILL.md +++ b/gitea/SKILL.md @@ -1,7 +1,7 @@ --- name: gitea description: "Push Hermes skill updates to the local Gitea instance at 10.0.0.61:3000. Clone, copy, commit, push workflow." -version: 1.2.0 +version: 1.3.0 author: Hermes Agent license: MIT platforms: [linux] @@ -24,7 +24,7 @@ Push skill updates to the local Gitea instance at `http://10.0.0.61:3000`. | Auth URL | `http://TOKEN@10.0.0.61:3000/SpeedyFoxAi/hermes-skills.git` | | Token | `2c6cacb89b8124a98a52206fdbee51cefcd46844` | | Local clone | `/tmp/hermes-skills` | -| Skill source | `~/.hermes/profiles/general/skills/` | +| Skill source | `~/.hermes/profiles//skills/` (any profile — general, research, dev, etc.) | ## Versioning @@ -80,9 +80,24 @@ git commit -m "Add v1.0.0" git push origin main ``` +## Pre-Push Token Validation (MANDATORY — before every push) + +Tokens expire, get rotated, or are revoked. Always validate the token BEFORE attempting a push: + +```bash +# Test token validity — 200 = valid, 401 = stale/rotated +curl -s -o /dev/null -w "%{http_code}" \ + -H "Authorization: token " \ + http://10.0.0.61:3000/api/v1/user +``` + +If 401, stop and ask the user for a new token. Do NOT attempt the push — it will fail and the error messages are misleading ("could not read Password", "terminal prompts disabled", "Authentication failed"). + ## Pitfalls - **Token in URL is required for push.** The repo is public-read but write-protected. Always set the remote URL with the token before pushing: `git remote set-url origin http://TOKEN@10.0.0.61:3000/SpeedyFoxAi/hermes-skills.git` +- **Token-in-URL may fail with "could not read Password".** Some git configurations ignore the password in the URL and still prompt. If `git push http://TOKEN@host/repo.git` fails, try `git -c credential.helper= -c credential.helper='!f() { echo "username=token"; echo "password=TOKEN"; }; f' push origin main`. If that also fails, the token itself is likely stale — validate it first with the curl check above. +- **Hardcoded token in this skill is a convenience, not a guarantee.** The token `2c6cacb89b8124a98a52206fdbee51cef46844` was valid at skill creation time but may have been rotated since. Always run the pre-push curl validation before relying on it. - **Git identity must be set.** The clone in `/tmp` won't have user.email/user.name configured. Set them before committing: `git config user.email "n8n@hermes-main.local" && git config user.name "Hermes Agent"` - **Skill directory names in the repo are flat** — e.g. `ask-claude/SKILL.md`, not `autonomous-ai-agents/ask-claude/SKILL.md`. The category hierarchy exists in `~/.hermes/profiles/general/skills/` but the Gitea repo uses flat skill names. - **Clone is disposable.** `/tmp/hermes-skills` is a working copy. Don't store anything there you need to keep. Re-clone if the directory is missing or stale. diff --git a/hermes-config-bulk-update/SKILL.md b/hermes-config-bulk-update/SKILL.md index d0e4bec..2e2b743 100644 --- a/hermes-config-bulk-update/SKILL.md +++ b/hermes-config-bulk-update/SKILL.md @@ -1,7 +1,7 @@ --- name: hermes-config-bulk-update description: "Bulk-update all Hermes config files (base + profiles) in one pass using execute_code." -version: 1.0.0 +version: 1.0.1 author: Hermes Agent --- @@ -39,8 +39,12 @@ for p in configs: - `references/nous-research-api.md` — Nous Research model name mapping (Ollama `:cloud` → Nous `provider/model`), config structure examples, auth status, and testing instructions. - `references/dgx-vllm-server.md` — DGX vLLM server (10.0.0.6) connection details, current model, smoke tests, container info. -- `references/model-temperature-configuration.md` — Main inference temperature is NOT user-configurable in v0.17.0 (`_fixed_temperature_for_model` only handles Kimi/Arcee; PR #34219 unmerged). Lists per-subsystem temps that DO work (compression, vision, MoA), Ollama `:cloud` model behavior (honors `options.temperature` but Hermes never sends it), and ranked workarounds (Modelfile bake, cherry-pick PR, proxy). +- `references/model-temperature-configuration.md` — Main inference temperature IS configurable via `custom_providers[].extra_body.temperature` (confirmed v0.18.0). Full code-path trace from `_custom_provider_extra_body_for_agent` through OpenAI SDK merge to Ollama cloud passthrough. Per-model specifics (MiniMax M3 [0,2], DeepSeek, GLM), three-temperature-location alignment requirement, and `_fixed_temperature_for_model` behavior (Kimi OMIT_TEMPERATURE, Arcee 0.5, everything else None). +- `references/temperature-validation-test-suite.md` — Reusable 4-question test suite for validating temperature changes are effective. Run at two temps, compare Q1-Q4 outputs. Includes expected results, validation criteria, and model-specific notes. - `references/profile-config-deep-clean.md` — Single-profile config.yaml deep-clean + max optimization workflow: remove unused sections, max all limits, set full permissions, configure auxiliary models to local Ollama, test infrastructure endpoints, fill empty values, categorize intentional empties. +- `references/config-schema-classification.md` — Complete Hermes config.yaml key classification reference (v33): REQUIRED/RECOMMENDED/OPTIONAL/DEPRECATED/OBSOLETE for every key, gateway-only sections, invalid enum values found in real configs, stale defaults, bogus keys, minimal config templates by profile type, and batch cleaning script pattern. Built from deep research against DEFAULT_CONFIG source code + official docs. +- `references/post-cleanup-verification.md` — After any bulk config change, `hermes config check` passing is NOT sufficient. Smoke-test every profile with a real chat query. Covers the sequential test pattern, what failures it catches (unreachable endpoints, model not found, auth failures), and the pitfall of parallel backgrounding causing event loop conflicts. +- `references/multi-agent-config-validation-loop.md` — Proven 4-phase workflow for cleaning configs across many profiles: deep research → per-profile dev/Claude validation loop → smoke test → fix failures. Used successfully to clean 22 profiles (41% line reduction). Covers the ask-dev/ask-claude dispatch pattern, standard validation questions, and pitfalls. - `references/searxng-search-requirement.md` — Hard rule: ALWAYS use `mcp_searxng_searxng_web_search` for web searches, never the built-in `web_search` tool. User-corrected behavior. - `references/performance-tuning.md` — Comprehensive Hermes config performance/quality review: critical fixes (web.extract_backend), streaming, tool output limits, session pruning, checkpoints, browser engine, smart model routing, delegation depth, prompt caching, watch items, and bulk-patch YAML paths with verification commands. - `references/local-ollama-profile-model-selection.md` — When setting a profile model to an Ollama-hosted model, query the live local catalog, pick only from available models, and verify/correct the profile's `base_url` so it points at local Ollama rather than an inherited remote vLLM endpoint. @@ -298,6 +302,9 @@ docker exec hermes-webui ls -d /workspace/{default,ai,automation,coding,comfy,dg ## Pitfalls +- **`hermes config check` passing does NOT mean the profile works.** It validates YAML structure and key recognition only — it does not test that the model endpoint is reachable, the model exists, or auth works. After any bulk config change, smoke-test every profile with a real chat query: `hermes -p chat -q "respond with exactly: OK " -Q --max-turns 3 --yolo`. See `references/post-cleanup-verification.md` for the full pattern and what failures it catches. The CLI's YAML serializer interprets `off` as a boolean. The resulting `mode: false` is not a recognized approvals mode (valid values: `manual | smart | off` — all strings). The agent will fall back to default behavior (manual approval, which hangs in headless/cron contexts). **Fix:** use `execute_code` with `yaml.safe_load`/`yaml.dump` to write the string value directly, or edit config.yaml manually. Do NOT use `hermes config set` for this key. +- **`approvals.cron_mode` is a SEPARATE gate from `approvals.mode`.** Even with `mode: off`, `cron_mode: deny` blocks dangerous commands in cron context. The agent must find another path rather than executing the command. For cron jobs that need full tool access, set BOTH: `approvals.mode: off` AND `approvals.cron_mode: approve`. These are independent gates — setting one does not affect the other. +- **The `default` profile uses base `~/.hermes/`, NOT `~/.hermes/profiles/default/`.** `hermes -p default` targets the base config directory. `hermes profile list` shows it, but `ls ~/.hermes/profiles/default/` fails because the directory doesn't exist. When iterating profiles for bulk operations, include `default` by targeting `~/.hermes/config.yaml` and `~/.hermes/skills/` — not by looking for a `profiles/default/` directory. Count profiles as: base config + N profile dirs. - **`provider: custom` for ALL self-hosted endpoints (vLLM, Ollama, llama.cpp, etc.).** The correct provider ID is `custom`, NOT `openai`. The `openai` provider ID is reserved for the official OpenAI API with `OPENAI_API_KEY` / `openai-api`. Using `provider: openai` with a self-hosted base_url may appear to work in some cases but is incorrect per Hermes docs and will cause routing/auth issues. The docs canonical form: ```yaml model: @@ -370,8 +377,9 @@ External APIs like Nous Research are configured as `custom_providers` entries + ``` If you accidentally modify one, revert by reloading the snapshot and setting the field back, or restore from `~/.hermes/backups/pre-update-*.zip`. Snapshots are NOT git-tracked, so there's no `git checkout` fallback. - **"Unknown toolsets: moa, rl" warning at startup means stale toolset entries in config.** The `moa` and `rl` toolsets are off-by-default and their tool modules don't exist. Removing them from the `toolsets:` list silences the warning. This does NOT disable the `/moa` slash command — MoA is a core feature, not a toolset. Use line filtering (not YAML parse/dump) for safe removal — see `references/toolset-cleanup.md`. -- **Model temperature is NOT user-configurable for the main inference path (v0.17.0).** Do NOT tell the user they can set `model.temperature` — that key does not exist in the config schema (confirmed via DEFAULT_CONFIG introspection). `_fixed_temperature_for_model()` (`agent/auxiliary_client.py:287-306`) only returns OMIT_TEMPERATURE for Kimi/Moonshot and 0.5 for Arcee Trinity; everything else gets no temperature field → provider default. PR #34219 would add `model.temperature` but is open/unmerged. Per-subsystem temps DO work: `compression.summarization.temperature` (default 0.3), `auxiliary.vision.temperature` (0.1), MoA preset temps. For Ollama `:cloud` models, the backend honors `options.temperature` but Hermes never sends it — the fastest fix is a Modelfile (`FROM :cloud` + `PARAMETER temperature `, `ollama create`). See `references/model-temperature-configuration.md` for the full stack analysis and ranked workarounds. +- **Model temperature IS configurable via `custom_providers[].extra_body.temperature` (confirmed v0.18.0).** Do NOT tell the user they can set `model.temperature` — that key does not exist in the config schema. The working mechanism is `extra_body.temperature` nested under the Ollama `custom_providers` entry. This merges into the OpenAI SDK's `extra_body` kwarg, which becomes a top-level `temperature` field in the JSON request body. Ollama's cloud proxy forwards it verbatim to the cloud provider. Confirmed working for MiniMax M3 (range [0,2]), DeepSeek, GLM, and other `:cloud` models. Three temperature locations must be aligned for consistency: `custom_providers[].extra_body.temperature` (main model), `moa.presets..reference_temperature`, and `moa.presets..aggregator_temperature`. See `references/model-temperature-configuration.md` for the full stack analysis, confirmed code paths, and per-model specifics. - **NEVER assume model selection for cron jobs.** When creating agent-driven cron jobs, always ask the user which model/provider to use. Do not default to the session model or pick one yourself. Script-only cron jobs (`no_agent=true`) don't need a model. This applies to any cron job that uses an LLM — the model must be explicitly chosen by the user and pinned via the `model` parameter on `cronjob(action='create')` or `cronjob(action='update')`. +- **Removing `cron:`, `gateway:`, or `streaming:` sections from a profile breaks its cron scheduler.** Even if a gateway process is running for that profile, the scheduler won't initialize without these config sections. During config cleanup, CLI-only profiles that still have cron jobs defined in `jobs.json` must retain these sections. The `cron:` section with `chronos.portal_url` is sufficient — the gateway and streaming sections can be minimal. See `hermes-cron-management` skill for the full cron lifecycle. - **`discover_models` on a `custom_providers` entry controls the `/model` picker source.** When `true` (or absent with an api_key set), the picker calls `/v1/models` and uses the live response. When `false`, the picker is locked to the static `models:` dict under that entry. The picker logic lives in `hermes_cli/model_switch.py` (`should_probe` block) and the live fetch caches to `/provider_models_cache.json` (deleted on `--refresh`). Implication: if a user says "the /model picker only shows N models for provider X", the fix is almost always flipping `discover_models: false` → `true` on that custom_provider entry across all configs — not adding more entries to the static `models:` list. Always do a live `curl` against `/v1/models` first to confirm the endpoint actually returns more than the static list claims, before writing to 9 files. - **When an agent stops early ("stopped after N iterations"), check `agent.max_turns` in the ACTIVE PROFILE first, not the server.** vLLM has no built-in iteration limit — it serves requests until the client stops. nuntius-mcp has its own `max_iterations` but is a separate system. The #1 culprit is the profile's `agent.max_turns` overriding the base config's higher value. If the stopped-at number is exactly 60, 50, or 20, it matches a Hermes default and confirms the limit is Hermes-side. See `references/iteration-turn-limits.md` for the full multi-layer checklist. - **Reasoning models on vLLM need `extra_body` to disable thinking.** Models like `qwen3.6-35b-a3b-uncensored` on vLLM put output in the `reasoning` field with `content: null` by default. The `/chat/completions` endpoint returns HTTP 200 but the message content is empty. Fix: add `extra_body: {chat_template_kwargs: {enable_thinking: false}}` to the model entry in `custom_providers`. Verify with a direct curl before writing to all configs — test both with and without the flag to confirm the endpoint accepts it. diff --git a/hermes-cron-management/SKILL.md b/hermes-cron-management/SKILL.md new file mode 100644 index 0000000..3b5a7d6 --- /dev/null +++ b/hermes-cron-management/SKILL.md @@ -0,0 +1,200 @@ +--- +name: hermes-cron-management +description: Diagnose, consolidate, and fix Hermes cron jobs across profiles. Covers the gateway dependency, stuck-job detection, cross-profile migration, and direct jobs.json editing when the cronjob tool can't reach other profiles. +version: 1.1.0 +author: Hermes Agent +platforms: [linux] +--- + +# Hermes Cron Management + +Diagnose and fix Hermes cron jobs — especially when jobs are stuck because their profile has no running gateway. + +## When to Use + +- Cron jobs have `next_run_at` timestamps in the past +- Jobs were created in a profile that no longer has a gateway running +- Consolidating scattered cron jobs into a single profile with a reliable gateway +- Validating that all cron jobs across all profiles are progressing properly + +## Core Rule: Gateway Dependency + +**Hermes cron jobs only execute when a gateway process is running for that profile.** A job defined in `~/.hermes/profiles//cron/jobs.json` will never fire unless a gateway process is active for ``. The `hermes.service` systemd unit or a `hermes gateway run --profile ` process must be running. + +This is the #1 cause of stuck cron jobs. Before debugging anything else, check: is a gateway running for this profile? + +## Diagnosis Workflow + +### 1. List all profiles and their cron jobs + +```bash +for p in $(ls ~/.hermes/profiles/); do + f="$HOME/.hermes/profiles/$p/cron/jobs.json" + [ -f "$f" ] && echo "=== $p ===" && python3 -c " +import json +with open('$f') as fh: + data = json.load(fh) +for j in data.get('jobs', []): + print(f' {j[\"id\"][:12]} {j[\"name\"]} enabled={j[\"enabled\"]} state={j[\"state\"]} next={j.get(\"next_run_at\",\"?\")} last_status={j.get(\"last_status\",\"?\")}') +" +done +``` + +### 2. Check which profiles have running gateways + +```bash +ps aux | grep 'hermes.*gateway run' | grep -v grep +``` + +### 3. Cross-reference + +Any profile with cron jobs but NO gateway process → those jobs are stuck. Their `next_run_at` will be frozen in the past. + +## Fix: Consolidate into a Profile with a Running Gateway +The reliable fix: move orphaned jobs into a profile that has a running gateway. + +### Step 1: Verify the target profile + +```bash +# Confirm gateway is running +ps aux | grep 'hermes.*gateway.*general' | grep -v grep + +# Confirm cron scheduler is active in gateway logs +grep 'cron\|tick' ~/.hermes/profiles/general/logs/gateway.log | tail -5 + +# Confirm required models are available +curl -s localhost:11434/api/tags | python3 -c "import sys,json; [print(m['name']) for m in json.load(sys.stdin).get('models',[])]" +``` + +### Step 2: Verify dependencies exist in target profile + +Before migrating, confirm the target profile has: +- Required skills (check `~/.hermes/profiles//skills/`) +- Required scripts (check `~/.hermes/profiles//scripts/`) +- Workdir paths exist on disk + +### Step 3: Create the job in the target profile + +Use `cronjob(action='create', ...)` from within the target profile's session. Match the original job's schedule, model, provider, skills, toolsets, workdir, and deliver settings. + +**For no_agent script jobs:** The `cronjob` tool requires scripts to be in `~/.hermes/scripts/` relative to the profile. Copy the script from the source profile first: + +```bash +cp ~/.hermes/profiles//scripts/