mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-18 04:41:56 +00:00
docs: close in-tree memory plugins to new PRs and codify skill standards (#25302)
AGENTS.md and CONTRIBUTING.md both now state:
1. No new memory providers in the repo. The set under plugins/memory/
(honcho, mem0, supermemory, byterover, hindsight, holographic,
openviking, retaindb) is closed. New backends ship as standalone
plugin repos that users install into ~/.hermes/plugins/ via the
same MemoryProvider ABC, discovery path, and hermes memory setup
integration. PRs adding a new plugins/memory/<name>/ directory get
closed with a pointer to publish as their own repo.
2. Skill authoring standards (hardline) — applies to all new or
modernized skills (bundled, optional, contributed):
- description <= 60 chars, one sentence, ends with period, no
marketing words, no name repetition (verification snippet
included)
- tools referenced in SKILL.md prose must be native Hermes tools
or MCP servers the skill expects — no grep/cat/sed/find etc.
when search_files/read_file/patch already cover them
- platforms: gating audited against actual POSIX-only primitives
- author credits the human contributor first, not 'Hermes Agent'
- SKILL.md uses modern section order with line targets
- scripts/references/templates layout for non-trivial logic
- tests at tests/skills/test_<skill>_skill.py, stdlib + mock only
- .env.example edits isolated to a delimited block
CONTRIBUTING.md includes a good/bad description example and a
'don't say / say' table mapping shell utilities to native tools.
AGENTS.md points the agent at references/new-skill-pr-salvage.md
for the full salvage checklist.
This commit is contained in:
parent
66c70966cd
commit
ef98e3f9e6
2 changed files with 161 additions and 0 deletions
91
AGENTS.md
91
AGENTS.md
|
|
@ -513,6 +513,17 @@ generic plugin surface (new hook, new ctx method) — never hardcode
|
||||||
plugin-specific logic into core. PR #5295 removed 95 lines of hardcoded
|
plugin-specific logic into core. PR #5295 removed 95 lines of hardcoded
|
||||||
honcho argparse from `main.py` for exactly this reason.
|
honcho argparse from `main.py` for exactly this reason.
|
||||||
|
|
||||||
|
**No new in-tree memory providers (policy, May 2026):** the set of
|
||||||
|
built-in memory providers under `plugins/memory/` is closed. New memory
|
||||||
|
backends must ship as **standalone plugin repos** that users install
|
||||||
|
into `~/.hermes/plugins/` (or via pip entry points) — they implement
|
||||||
|
the same `MemoryProvider` ABC, register through the same discovery
|
||||||
|
path, and integrate via `hermes memory setup` / `post_setup()` without
|
||||||
|
landing in this tree. PRs that add a new directory under
|
||||||
|
`plugins/memory/` will be closed with a pointer to publish the
|
||||||
|
provider as its own repo. Existing in-tree providers stay; bug fixes
|
||||||
|
to them are welcome.
|
||||||
|
|
||||||
### Model-provider plugins (`plugins/model-providers/<name>/`)
|
### Model-provider plugins (`plugins/model-providers/<name>/`)
|
||||||
|
|
||||||
Every inference backend (openrouter, anthropic, gmi, deepseek, nvidia, …)
|
Every inference backend (openrouter, anthropic, gmi, deepseek, nvidia, …)
|
||||||
|
|
@ -580,6 +591,86 @@ during setup, injected at load time).
|
||||||
Top-level `tags:` and `category:` are also accepted and mirrored from
|
Top-level `tags:` and `category:` are also accepted and mirrored from
|
||||||
`metadata.hermes.*` by the loader.
|
`metadata.hermes.*` by the loader.
|
||||||
|
|
||||||
|
### Skill authoring standards (HARDLINE)
|
||||||
|
|
||||||
|
Every new or modernized skill — bundled, optional, or contributed —
|
||||||
|
must meet these standards before merge. Reviewers reject PRs that
|
||||||
|
violate them.
|
||||||
|
|
||||||
|
1. **`description` ≤ 60 characters, one sentence, ends with a period.**
|
||||||
|
Long descriptions bloat skill listings and dilute the model's
|
||||||
|
attention when many skills are loaded. State the capability, not
|
||||||
|
the implementation. No marketing words ("powerful",
|
||||||
|
"comprehensive", "seamless", "advanced"). Don't repeat the skill
|
||||||
|
name. Verify with:
|
||||||
|
```python
|
||||||
|
import re, pathlib
|
||||||
|
m = re.search(r'^description: (.*)$',
|
||||||
|
pathlib.Path('skills/<cat>/<name>/SKILL.md').read_text(),
|
||||||
|
re.MULTILINE)
|
||||||
|
assert len(m.group(1)) <= 60, len(m.group(1))
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Tools referenced in SKILL.md prose must be native Hermes tools or
|
||||||
|
MCP servers the skill explicitly expects.** When the skill needs a
|
||||||
|
capability, point at the proper tool by name in backticks
|
||||||
|
(`` `terminal` ``, `` `web_extract` ``, `` `read_file` ``,
|
||||||
|
`` `patch` ``, `` `search_files` ``, `` `vision_analyze` ``,
|
||||||
|
`` `browser_navigate` ``, `` `delegate_task` ``, etc.). Do NOT
|
||||||
|
name shell utilities the agent already has wrapped — `grep` →
|
||||||
|
`search_files`, `cat`/`head`/`tail` → `read_file`, `sed`/`awk` →
|
||||||
|
`patch`, `find`/`ls` → `search_files target='files'`. If the skill
|
||||||
|
depends on an MCP server, name the MCP server and document the
|
||||||
|
expected setup in `## Prerequisites`. Anything else (third-party
|
||||||
|
CLIs, shell pipelines, etc.) is fair game inside script files but
|
||||||
|
should not be the headline interaction surface in the prose.
|
||||||
|
|
||||||
|
3. **`platforms:` gating audited against actual script imports.**
|
||||||
|
Skills that use POSIX-only primitives (`fcntl`, `termios`,
|
||||||
|
`os.setsid`, `os.kill(pid, 0)` for liveness, `/proc`, `/tmp`
|
||||||
|
hardcoded, `signal.SIGKILL`, bash heredocs, `osascript`, `apt`,
|
||||||
|
`systemctl`) must declare their supported platforms. Default
|
||||||
|
posture: try to fix it cross-platform first — `tempfile.gettempdir`,
|
||||||
|
`pathlib.Path`, `psutil.pid_exists`, Python-level filtering instead
|
||||||
|
of `grep`. Gate to a narrower set only when the dependency is
|
||||||
|
genuinely platform-bound.
|
||||||
|
|
||||||
|
4. **`author` credits the human contributor first.** For external
|
||||||
|
contributions, the contributor's real name + GitHub handle goes
|
||||||
|
first; "Hermes Agent" is the secondary collaborator. If the
|
||||||
|
contributor's commit shows "Hermes Agent" as author (because they
|
||||||
|
used Hermes to draft the skill), replace it with their actual name
|
||||||
|
— credit the human, not the tool.
|
||||||
|
|
||||||
|
5. **SKILL.md body uses the modern section order.** `# <Skill> Skill`
|
||||||
|
title, 2-3 sentence intro stating what it does and doesn't do,
|
||||||
|
`## When to Use`, `## Prerequisites`, `## How to Run`,
|
||||||
|
`## Quick Reference`, `## Procedure`, `## Pitfalls`,
|
||||||
|
`## Verification`. Target ~200 lines for a complex skill,
|
||||||
|
~100 lines for a simple one. Cut redundant intro fluff, marketing
|
||||||
|
prose, and re-explanations of env vars already in
|
||||||
|
`## Prerequisites`.
|
||||||
|
|
||||||
|
6. **Scripts go in `scripts/`, references in `references/`,
|
||||||
|
templates in `templates/`.** Don't expect the model to inline-write
|
||||||
|
parsers, XML walkers, or non-trivial logic every call — ship a
|
||||||
|
helper script. Reference it from SKILL.md by path relative to the
|
||||||
|
skill directory.
|
||||||
|
|
||||||
|
7. **Tests live at `tests/skills/test_<skill>_skill.py`** and use only
|
||||||
|
stdlib + pytest + `unittest.mock`. No live network calls. Run via
|
||||||
|
`scripts/run_tests.sh tests/skills/test_<skill>_skill.py -q`.
|
||||||
|
|
||||||
|
8. **`.env.example` additions are isolated to a clearly delimited
|
||||||
|
block.** Don't touch the surrounding file — contributor-supplied
|
||||||
|
`.env.example` versions are usually stale and edits outside the
|
||||||
|
skill's own block must be dropped during salvage.
|
||||||
|
|
||||||
|
The full salvage / modernization checklist for external skill PRs
|
||||||
|
lives in the `hermes-agent-dev` skill at
|
||||||
|
`references/new-skill-pr-salvage.md` — load it before polishing
|
||||||
|
contributor skill PRs.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Toolsets
|
## Toolsets
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,24 @@ If your skill is specialized, community-contributed, or niche, it's better suite
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Memory Providers: Ship as a Standalone Plugin
|
||||||
|
|
||||||
|
**We are no longer accepting new memory providers into this repo.** The set of built-in providers under `plugins/memory/` (honcho, mem0, supermemory, byterover, hindsight, holographic, openviking, retaindb) is closed. If you want to add a new memory backend, publish it as a **standalone plugin repo** that users install into `~/.hermes/plugins/` (or via a pip entry point).
|
||||||
|
|
||||||
|
Standalone memory plugins:
|
||||||
|
|
||||||
|
- Implement the same `MemoryProvider` ABC (`agent/memory_provider.py`) — `sync_turn`, `prefetch`, `shutdown`, and optionally `post_setup(hermes_home, config)` for setup-wizard integration
|
||||||
|
- Use the same discovery system — `discover_memory_providers()` picks them up from user/project plugin directories and pip entry points
|
||||||
|
- Integrate with `hermes memory setup` via `post_setup()` — no need to touch core code
|
||||||
|
- Can register their own CLI subcommands via `register_cli(subparser)` in a `cli.py` file
|
||||||
|
- Get all the same lifecycle hooks and config plumbing as in-tree providers
|
||||||
|
|
||||||
|
PRs that add a new directory under `plugins/memory/` will be closed with a pointer to publish the provider as its own repo. Existing in-tree providers stay; bug fixes to them are welcome.
|
||||||
|
|
||||||
|
This isn't a quality bar — it's a coupling-and-maintenance decision. Memory providers are the most common plugin type and they shouldn't all live in this tree.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Development Setup
|
## Development Setup
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
@ -461,6 +479,58 @@ Gateway and messaging sessions never collect secrets in-band; they instruct the
|
||||||
|
|
||||||
See `skills/gifs/gif-search/` and `skills/email/himalaya/` for examples.
|
See `skills/gifs/gif-search/` and `skills/email/himalaya/` for examples.
|
||||||
|
|
||||||
|
### Skill authoring standards (HARDLINE)
|
||||||
|
|
||||||
|
Every new or modernized skill — bundled, optional, or contributed — must meet these standards before merge. Reviewers reject PRs that violate them.
|
||||||
|
|
||||||
|
1. **`description` ≤ 60 characters, one sentence, ends with a period.** Long descriptions bloat the skill listing UI and dilute the model's attention when many skills are loaded. State the capability, not the implementation. No marketing words ("powerful", "comprehensive", "seamless", "advanced"). Don't repeat the skill name. Verify with:
|
||||||
|
```python
|
||||||
|
import re, pathlib
|
||||||
|
m = re.search(r'^description: (.*)$',
|
||||||
|
pathlib.Path('skills/<cat>/<name>/SKILL.md').read_text(),
|
||||||
|
re.MULTILINE)
|
||||||
|
assert len(m.group(1)) <= 60, len(m.group(1))
|
||||||
|
```
|
||||||
|
|
||||||
|
Good: `Search arXiv papers by keyword, author, category, or ID.`
|
||||||
|
Bad: `A powerful and comprehensive skill that allows the agent to search arXiv for relevant academic papers using various criteria including keywords, authors, and categories.`
|
||||||
|
|
||||||
|
2. **Tools referenced in SKILL.md prose must be native Hermes tools or MCP servers the skill explicitly expects.** When the skill needs a capability, point at the proper tool by name in backticks: `` `terminal` ``, `` `web_extract` ``, `` `web_search` ``, `` `read_file` ``, `` `write_file` ``, `` `patch` ``, `` `search_files` ``, `` `vision_analyze` ``, `` `browser_navigate` ``, `` `delegate_task` ``, `` `image_generate` ``, `` `text_to_speech` ``, `` `cronjob` ``, `` `memory` ``, `` `skill_view` ``, `` `todo` ``, `` `execute_code` ``.
|
||||||
|
|
||||||
|
Do NOT name shell utilities the agent already has wrapped:
|
||||||
|
|
||||||
|
| Don't say | Say |
|
||||||
|
|---|---|
|
||||||
|
| `grep`, `rg` | `search_files` |
|
||||||
|
| `cat`, `head`, `tail` | `read_file` |
|
||||||
|
| `sed`, `awk` | `patch` |
|
||||||
|
| `find`, `ls` | `search_files` (with `target='files'`) |
|
||||||
|
| `curl` for content extraction | `web_extract` |
|
||||||
|
| `echo > file`, `cat <<EOF` | `write_file` |
|
||||||
|
|
||||||
|
If the skill depends on an MCP server, name the MCP server and document its setup in `## Prerequisites`. Third-party CLIs (e.g. `ffmpeg`, `gh`, a specific SDK) are fine to invoke from inside script files, but the prose should frame the interaction as "invoke through the `terminal` tool", not as a manual shell session.
|
||||||
|
|
||||||
|
3. **`platforms:` gating audited against actual script imports.** Skills that use POSIX-only primitives (`fcntl`, `termios`, `os.setsid`, `os.kill(pid, 0)` for liveness, `/proc`, hardcoded `/tmp` paths, `signal.SIGKILL`, bash heredocs, `osascript`, `apt`, `systemctl`) must declare their supported platforms via the `platforms:` frontmatter. Default posture is to fix it cross-platform first — `tempfile.gettempdir()`, `pathlib.Path`, `psutil.pid_exists()`, Python-level filtering instead of `grep`. Gate to a narrower set only when the dependency is genuinely platform-bound (e.g. `osascript` is macOS-only, `/proc` is Linux-only).
|
||||||
|
|
||||||
|
4. **`author` credits the human contributor first.** For external contributions, the contributor's real name + GitHub handle goes first (`Jane Doe (jane-doe)`); "Hermes Agent" is the secondary collaborator. If the contributor's commit shows "Hermes Agent" as author because they used Hermes to draft the skill, replace it with their actual name — credit the human, not the tool.
|
||||||
|
|
||||||
|
5. **SKILL.md body uses the modern section order.** `# <Skill> Skill` title, 2-3 sentence intro stating what it does and what it doesn't do, then:
|
||||||
|
- `## When to Use` — trigger conditions
|
||||||
|
- `## Prerequisites` — env vars, install steps, MCP setup, API key sourcing
|
||||||
|
- `## How to Run` — canonical invocation through the `terminal` tool
|
||||||
|
- `## Quick Reference` — flat command/API reference
|
||||||
|
- `## Procedure` — numbered steps with copy-paste commands
|
||||||
|
- `## Pitfalls` — known limits, rate limits, things that look broken but aren't
|
||||||
|
- `## Verification` — single command that proves the skill works
|
||||||
|
|
||||||
|
Target ~200 lines for a complex skill, ~100 lines for a simple one. Cut redundant intro fluff, marketing prose, and re-explanations of env vars already documented in `## Prerequisites`.
|
||||||
|
|
||||||
|
6. **Scripts go in `scripts/`, references in `references/`, templates in `templates/`.** Don't expect the model to inline-write parsers, XML walkers, or non-trivial logic every call — ship a helper script. Reference scripts from SKILL.md by path relative to the skill directory.
|
||||||
|
|
||||||
|
7. **Tests live at `tests/skills/test_<skill>_skill.py`** and use only stdlib + pytest + `unittest.mock`. No live network calls. Run via `scripts/run_tests.sh tests/skills/test_<skill>_skill.py -q`. Must pass under the hermetic CI env (no API keys leaking through). Use `monkeypatch` and `tmp_path` for any env-var or filesystem dependencies.
|
||||||
|
|
||||||
|
8. **`.env.example` additions are isolated to a clearly delimited block.** Don't touch the surrounding file — contributor-supplied `.env.example` versions are usually stale, and edits outside the skill's own block will be dropped during salvage. Comment all values with `#` (it's documentation, not live config).
|
||||||
|
|
||||||
### Skill guidelines
|
### Skill guidelines
|
||||||
|
|
||||||
- **No external dependencies unless absolutely necessary.** Prefer stdlib Python, curl, and existing Hermes tools (`web_extract`, `terminal`, `read_file`).
|
- **No external dependencies unless absolutely necessary.** Prefer stdlib Python, curl, and existing Hermes tools (`web_extract`, `terminal`, `read_file`).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue