From b7bd177105986a0af5ec13c427e0e3837f8d05c8 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Tue, 5 May 2026 07:56:29 -0700 Subject: [PATCH] docs(AGENTS.md): add curator/cron/delegation/toolsets, fix plugin tree (#20226) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(AGENTS.md): add curator/cron/delegation/toolsets, fix plugin tree, frontmatter, auto-discovery caveat Closes #19101 and #19107 (@pty819). Verified 16 claims from those two issues against current main. 12 were real gaps; 2 were generated/hallucinated (#10 unverified --now flag is actually real and already cited in AGENTS.md; #11 stale PR refs #5587 and #4950 do not appear in AGENTS.md at all); 2 were low-prio nits (memory provider hierarchy, --now scope enumeration) deferred. Changes: - Project tree: add yuanbao to platforms comment; expand plugins/ subtree with real directory names (kanban, hermes-achievements, observability, image_gen) instead of vague ''. - Test-count blurb: 15k/700 Apr → 17k/900 May (verified: 17,375 test defs, 915 files). - Adding New Tools: clarify that auto-discovery wires up schemas but the tool only reaches an agent if its name is added to a toolset in toolsets.py. _HERMES_CORE_TOOLS is not dead code. - Adding Configuration: enumerate top-level config.yaml sections including auxiliary and curator; note auxiliary is per-task overrides for side-LLM work. - SKILL.md frontmatter: add author, license, related_skills. Note top-level tags/category are mirrored from metadata.hermes.*. - New section 'Toolsets' — enumerates the 30 current TOOLSETS keys (including yuanbao, kanban, moa, spotify, safe, debugging). - New section 'Delegation (delegate_task)' — sync semantics, batch mode, leaf vs orchestrator roles, config knobs, durability caveat. - New section 'Curator (skill lifecycle)' — core files, 11 CLI verbs, telemetry sidecar, invariants (pin/delete split after PR #20220, bundled/hub off-limits), curator.* config section. - New section 'Cron (scheduled jobs)' — 4 schedule formats, 7 CLI verbs, per-job fields, 3-min hard interrupt, catchup/grace windows, tick.lock, cron→session isolation. Skipped (invalid claims): - #19107 item 10: --now is real (hermes_cli/skills_hub.py:624/966/1013/1470) - #19107 item 11: no '#5587' or '#4950' or 'async_delegation' in AGENTS.md * docs(AGENTS.md): add Kanban section Adds a Kanban entry alongside Curator / Cron / Delegation so the major durable background systems are all represented. Covers the CLI verbs, the HERMES_KANBAN_TASK-gated worker toolset, the in-gateway dispatcher, plugin assets, and the board/tenant isolation model. Points at the full 742-line user docs for detail. --- AGENTS.md | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 195 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index f09258061f..b77a1d2699 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,12 +37,17 @@ hermes-agent/ │ ├── platforms/ # Adapter per platform (telegram, discord, slack, whatsapp, │ │ # homeassistant, signal, matrix, mattermost, email, sms, │ │ # dingtalk, wecom, weixin, feishu, qqbot, bluebubbles, -│ │ # webhook, api_server, ...). See ADDING_A_PLATFORM.md. +│ │ # yuanbao, webhook, api_server, ...). See ADDING_A_PLATFORM.md. │ └── builtin_hooks/ # Extension point for always-registered gateway hooks (none shipped) ├── plugins/ # Plugin system (see "Plugins" section below) │ ├── memory/ # Memory-provider plugins (honcho, mem0, supermemory, ...) │ ├── context_engine/ # Context-engine plugins -│ └── / # Dashboard, image-gen, disk-cleanup, examples, ... +│ ├── kanban/ # Multi-agent board dispatcher + worker plugin +│ ├── hermes-achievements/ # Gamified achievement tracking +│ ├── observability/ # Metrics / traces / logs plugin +│ ├── image_gen/ # Image-generation providers +│ └── / # disk-cleanup, example-dashboard, google_meet, platforms, +│ # spotify, strike-freedom-cockpit, ... ├── optional-skills/ # Heavier/niche skills shipped but NOT active by default ├── skills/ # Built-in skills bundled with the repo ├── ui-tui/ # Ink (React) terminal UI — `hermes --tui` @@ -53,7 +58,7 @@ hermes-agent/ ├── environments/ # RL training environments (Atropos) ├── scripts/ # run_tests.sh, release.py, auxiliary scripts ├── website/ # Docusaurus docs site -└── tests/ # Pytest suite (~15k tests across ~700 files as of Apr 2026) +└── tests/ # Pytest suite (~17k tests across ~900 files as of May 2026) ``` **User config:** `~/.hermes/config.yaml` (settings), `~/.hermes/.env` (API keys only). @@ -289,9 +294,9 @@ registry.register( ) ``` -**2. Add to `toolsets.py`** — either `_HERMES_CORE_TOOLS` (all platforms) or a new toolset. +**2. Add to `toolsets.py`** — either `_HERMES_CORE_TOOLS` (all platforms) or a new toolset. **This step is required:** auto-discovery imports the tool and registers its schema, but the tool is only *exposed to an agent* if its name appears in a toolset. `_HERMES_CORE_TOOLS` is not dead code — it's the default bundle every platform's base toolset inherits from. -Auto-discovery: any `tools/*.py` file with a top-level `registry.register()` call is imported automatically — no manual import list to maintain. +Auto-discovery: any `tools/*.py` file with a top-level `registry.register()` call is imported automatically — no manual import list to maintain. Wiring into a toolset is still a deliberate, manual step. The registry handles schema collection, dispatch, availability checking, and error wrapping. All handlers MUST return a JSON string. @@ -313,6 +318,22 @@ The registry handles schema collection, dispatch, availability checking, and err section is handled automatically by the deep-merge and does NOT require a version bump. +### Top-level `config.yaml` sections (non-exhaustive): + +`model`, `agent`, `terminal`, `compression`, `display`, `stt`, `tts`, +`memory`, `security`, `delegation`, `smart_model_routing`, `checkpoints`, +`auxiliary`, `curator`, `skills`, `gateway`, `logging`, `cron`, `profiles`, +`plugins`, `honcho`. + +`auxiliary` holds per-task overrides for side-LLM work (curator, vision, +embedding, title generation, session_search, etc.) — each task can pin +its own provider/model/base_url/max_tokens/reasoning_effort. See +`agent/auxiliary_client.py::_resolve_auto` for resolution order. + +`curator` holds the background skill-maintenance config — +`enabled`, `interval_hours`, `min_idle_hours`, `stale_after_days`, +`archive_after_days`, `backup` (nested). + ### .env variables (SECRETS ONLY — API keys, tokens, passwords): 1. Add to `OPTIONAL_ENV_VARS` in `hermes_cli/config.py` with metadata: ```python @@ -519,11 +540,176 @@ niche skills belong in `optional-skills/`. ### SKILL.md frontmatter -Standard fields: `name`, `description`, `version`, `platforms` -(OS-gating list: `[macos]`, `[linux, macos]`, ...), +Standard fields: `name`, `description`, `version`, `author`, `license`, +`platforms` (OS-gating list: `[macos]`, `[linux, macos]`, ...), `metadata.hermes.tags`, `metadata.hermes.category`, -`metadata.hermes.config` (config.yaml settings the skill needs — stored -under `skills.config.`, prompted during setup, injected at load time). +`metadata.hermes.related_skills`, `metadata.hermes.config` (config.yaml +settings the skill needs — stored under `skills.config.`, prompted +during setup, injected at load time). + +Top-level `tags:` and `category:` are also accepted and mirrored from +`metadata.hermes.*` by the loader. + +--- + +## Toolsets + +All toolsets are defined in `toolsets.py` as a single `TOOLSETS` dict. +Each platform's adapter picks a base toolset (e.g. Telegram uses +`"messaging"`); `_HERMES_CORE_TOOLS` is the default bundle most +platforms inherit from. + +Current toolset keys: `browser`, `clarify`, `code_execution`, `cronjob`, +`debugging`, `delegation`, `discord`, `discord_admin`, `feishu_doc`, +`feishu_drive`, `file`, `homeassistant`, `image_gen`, `kanban`, `memory`, +`messaging`, `moa`, `rl`, `safe`, `search`, `session_search`, `skills`, +`spotify`, `terminal`, `todo`, `tts`, `video`, `vision`, `web`, `yuanbao`. + +Enable/disable per platform via `hermes tools` (the curses UI) or the +`tools..enabled` / `tools..disabled` lists in +`config.yaml`. + +--- + +## Delegation (`delegate_task`) + +`tools/delegate_tool.py` spawns a subagent with an isolated +context + terminal session. Synchronous: the parent waits for the +child's summary before continuing its own loop — if the parent is +interrupted, the child is cancelled. + +Two shapes: + +- **Single:** pass `goal` (+ optional `context`, `toolsets`). +- **Batch (parallel):** pass `tasks: [...]` — each gets its own subagent + running concurrently. Concurrency is capped by + `delegation.max_concurrent_children` (default 3). + +Roles: + +- `role="leaf"` (default) — focused worker. Cannot call `delegate_task`, + `clarify`, `memory`, `send_message`, `execute_code`. +- `role="orchestrator"` — retains `delegate_task` so it can spawn its + own workers. Gated by `delegation.orchestrator_enabled` (default true) + and bounded by `delegation.max_spawn_depth` (default 2). + +Key config knobs (under `delegation:` in `config.yaml`): +`max_concurrent_children`, `max_spawn_depth`, `child_timeout_seconds`, +`orchestrator_enabled`, `subagent_auto_approve`, `inherit_mcp_toolsets`, +`max_iterations`. + +Synchronicity rule: delegate_task is **not** durable. For long-running +work that must outlive the current turn, use `cronjob` or +`terminal(background=True, notify_on_complete=True)` instead. + +--- + +## Curator (skill lifecycle) + +Background skill-maintenance system that tracks usage on agent-created +skills and auto-archives stale ones. Users never lose skills; archives +go to `~/.hermes/skills/.archive/` and are restorable. + +- **Core:** `agent/curator.py` (review loop, auto-transitions, LLM review + prompt) + `agent/curator_backup.py` (pre-run tar.gz snapshots). +- **CLI:** `hermes_cli/curator.py` wires `hermes curator ` where + verbs are: `status`, `run`, `pause`, `resume`, `pin`, `unpin`, + `archive`, `restore`, `prune`, `backup`, `rollback`. +- **Telemetry:** `tools/skill_usage.py` owns the sidecar + `~/.hermes/skills/.usage.json` — per-skill `use_count`, `view_count`, + `patch_count`, `last_activity_at`, `state` (active / stale / + archived), `pinned`. + +Invariants: +- Curator only touches skills with `created_by: "agent"` provenance — + bundled + hub-installed skills are off-limits. +- Never deletes; max destructive action is archive. +- Pinned skills are exempt from every auto-transition and from the + LLM review pass. +- `skill_manage(action="delete")` refuses pinned skills; patch/edit/ + write_file/remove_file go through so the agent can keep improving + pinned skills. + +Config section (`curator:` in `config.yaml`): +`enabled`, `interval_hours`, `min_idle_hours`, `stale_after_days`, +`archive_after_days`, `backup.*`. + +Full user-facing docs: `website/docs/user-guide/features/curator.md`. + +--- + +## Cron (scheduled jobs) + +`cron/jobs.py` (job store) + `cron/scheduler.py` (tick loop). Agents +schedule jobs via the `cronjob` tool; users via `hermes cron ` +(`list`, `add`, `edit`, `pause`, `resume`, `run`, `remove`) or the +`/cron` slash command. + +Supported schedule formats: +- Duration: `"30m"`, `"2h"`, `"1d"` +- "every" phrase: `"every 2h"`, `"every monday 9am"` +- 5-field cron expression: `"0 9 * * *"` +- ISO timestamp (one-shot): `"2026-06-01T09:00:00Z"` + +Per-job fields include `skills` (load specific skills), `model` / +`provider` overrides, `script` (pre-run data-collection script whose +stdout is injected into the prompt; `no_agent=True` turns the script +into the entire job), `context_from` (chain job A's last output into +job B's prompt), `workdir` (run in a specific directory with its +`AGENTS.md`/`CLAUDE.md` loaded), and multi-platform delivery. + +Hardening invariants: +- **3-minute hard interrupt** on cron sessions — runaway agent loops + cannot monopolize the scheduler. +- Catchup window: half the job's period, clamped to 120s–2h. +- Grace window: 120s for one-shot jobs whose fire time was missed. +- File lock at `~/.hermes/cron/.tick.lock` prevents duplicate ticks + across processes. +- Cron sessions pass `skip_memory=True` by default; memory providers + intentionally do not run during cron. + +Cron deliveries are **not** mirrored into the target gateway session — +they land in their own cron session with a header/footer frame so the +main conversation's message-role alternation stays intact. + +--- + +## Kanban (multi-agent work queue) + +Durable SQLite-backed board that lets multiple profiles / workers +collaborate on shared tasks. Users drive it via `hermes kanban `; +workers spawned by the dispatcher drive it via a dedicated `kanban_*` +toolset so their schema footprint is zero when they're not inside a +kanban task. + +- **CLI:** `hermes_cli/kanban.py` wires `hermes kanban` with verbs + `init`, `create`, `list` (alias `ls`), `show`, `assign`, `link`, + `unlink`, `comment`, `complete`, `block`, `unblock`, `archive`, + `tail`, plus less-commonly-used `watch`, `stats`, `runs`, `log`, + `assignees`, `heartbeat`, `notify-*`, `dispatch`, `daemon`, `gc`. +- **Worker toolset:** `tools/kanban_tools.py` exposes `kanban_show`, + `kanban_complete`, `kanban_block`, `kanban_heartbeat`, `kanban_comment`, + `kanban_create`, `kanban_link` — gated by `HERMES_KANBAN_TASK` so + the schema only appears for processes actually running as a worker. +- **Dispatcher:** long-lived loop that (default every 60s) reclaims + stale claims, promotes ready tasks, atomically claims, and spawns + assigned profiles. Runs **inside the gateway** by default via + `kanban.dispatch_in_gateway: true`. +- **Plugin assets:** `plugins/kanban/dashboard/` (web UI) + + `plugins/kanban/systemd/` (`hermes-kanban-dispatcher.service` for + standalone dispatcher deployment). + +Isolation model: +- **Board** is the hard boundary — workers are spawned with + `HERMES_KANBAN_BOARD` pinned in their env so they can't see other + boards. +- **Tenant** is a soft namespace *within* a board — one specialist + fleet can serve multiple businesses with workspace-path + memory-key + isolation. +- After ~5 consecutive spawn failures on the same task the dispatcher + auto-blocks it to prevent spin loops. + +Full user-facing docs: `website/docs/user-guide/features/kanban.md`. ---