Skip to content

Commit 062809b

Browse files
authored
Merge pull request #1 from stanvx/feat/hermes-first-class-sleep
feat(sleep): add Hermes Agent as a first-class backend and transcript source
2 parents b860a5c + a432ec5 commit 062809b

13 files changed

Lines changed: 936 additions & 10 deletions

File tree

docs/sleep/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ skillopt-sleep schedule # install a nightly cron entry for this project
5454
5555
The per-agent integrations below still come from the repo; the CLI above is the
5656
standalone, pip-only way to run a cycle. Claude Code, Codex, Copilot, and Devin wrap
57-
the shared engine. OpenClaw is a separate reference adaptation and has its own setup.
57+
the shared engine; Hermes Agent is wired into the core engine directly (`--source hermes`
58+
/ `--backend hermes`). OpenClaw is a separate reference adaptation and has its own setup.
5859

5960
One engine, thin per-agent shells (see [`plugins/`](https://github.com/microsoft/SkillOpt/tree/main/plugins)):
6061

@@ -64,6 +65,7 @@ One engine, thin per-agent shells (see [`plugins/`](https://github.com/microsoft
6465
| **Codex** | [`plugins/codex`](https://github.com/microsoft/SkillOpt/tree/main/plugins/codex) | `bash plugins/codex/install.sh``skillopt-sleep` skill |
6566
| **Copilot** | [`plugins/copilot`](https://github.com/microsoft/SkillOpt/tree/main/plugins/copilot) | register `plugins/copilot/mcp_server.py` as an MCP server |
6667
| **Devin** | [`plugins/devin`](https://github.com/microsoft/SkillOpt/tree/main/plugins/devin) | register `plugins/devin/mcp_server.py` as an MCP server |
68+
| **Hermes Agent** | [`plugins/hermes`](https://github.com/microsoft/SkillOpt/tree/main/plugins/hermes) | `--source hermes` / `--backend hermes` (core), or register `plugins/hermes/mcp_server.py` |
6769
| **OpenClaw** | [`plugins/openclaw`](https://github.com/microsoft/SkillOpt/tree/main/plugins/openclaw) | adapt the reference wrapper and paths for your installation |
6870

6971
To use DeepSeek, vLLM, Ollama, or another Chat Completions server, see

plugins/README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@ runtime dependency on the paper's `skillopt/` experiment package.
1010

1111
## Available integrations
1212

13-
Four integrations wrap the shared `skillopt_sleep` CLI. OpenClaw is a separate
14-
reference adaptation with its own backend and setup assumptions.
13+
Five integrations wrap the shared `skillopt_sleep` CLI. Hermes is additionally
14+
wired into the core engine (its harvester and backend ship in `skillopt_sleep/`,
15+
so `--source hermes` / `--backend hermes` work from the shared CLI). OpenClaw is
16+
a separate reference adaptation with its own backend and setup assumptions.
1517

1618
| Platform | Folder | Mechanism | Status |
1719
|---|---|---|---|
1820
| **Claude Code** | [`claude-code/`](claude-code) | marketplace plugin, commands, skill, and hooks | installable shared-engine integration |
1921
| **Codex** | [`codex/`](codex) | user-level skill and shared runner | installable shared-engine integration |
2022
| **GitHub Copilot** | [`copilot/`](copilot) | MCP server exposing seven `sleep_*` tools | shared-engine MCP integration |
2123
| **Devin** | [`devin/`](devin) | MCP server plus Devin transcript conversion | shared-engine MCP integration |
24+
| **Hermes Agent** | [`hermes/`](hermes) | core `--source`/`--backend hermes` + MCP server | first-class core integration |
2225
| **OpenClaw** | [`openclaw/`](openclaw) | custom DeepSeek/Ollama wrapper | independent reference adaptation; review and adapt before use |
2326

2427
## Install
@@ -32,6 +35,7 @@ for your workflow.
3235
| **Codex** | `bash plugins/codex/install.sh` | ask Codex to use the `skillopt-sleep` skill |
3336
| **Copilot** | register `plugins/copilot/mcp_server.py` using its example MCP config | ask Copilot to run `sleep_status` |
3437
| **Devin** | register `plugins/devin/mcp_server.py` using its example MCP config | ask Devin to run `sleep_status` |
38+
| **Hermes Agent** | register `plugins/hermes/mcp_server.py`, or run `python -m skillopt_sleep run --backend hermes --source hermes` | ask Hermes to run `sleep_status` |
3539
| **OpenClaw** | follow and adapt [`openclaw/README.md`](openclaw/README.md) | validate paths, credentials, and tasks locally |
3640

3741
Python 3.10 or newer is required. Real CLI backends also require the selected
@@ -101,9 +105,9 @@ Common implemented flags include:
101105

102106
| Flag | Default | Purpose |
103107
|---|---|---|
104-
| `--backend mock\|claude\|codex\|copilot\|handoff\|azure_openai` | `mock` | select who performs model calls |
108+
| `--backend mock\|claude\|codex\|copilot\|handoff\|azure_openai\|hermes` | `mock` | select who performs model calls |
105109
| `--model NAME` | backend default | select a backend-specific model |
106-
| `--source claude\|codex\|auto` | `claude` | select the transcript source |
110+
| `--source claude\|codex\|hermes\|auto` | `claude` | select the transcript source |
107111
| `--project PATH` | current directory | select the project and invoked harvest scope |
108112
| `--scope invoked\|all` | `invoked` | limit transcript harvesting |
109113
| `--target-skill-path PATH` | managed skill | select a specific `SKILL.md` to stage/adopt |

plugins/hermes/README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# SkillOpt-Sleep — Hermes Agent integration
2+
3+
First-class integration of the [Hermes Agent](https://github.com/NousResearch/Hermes)
4+
CLI with the shared `skillopt_sleep` engine. Unlike the reference OpenClaw adapter,
5+
Hermes is wired directly into core: `--source hermes` and `--backend hermes` work from
6+
the shared CLI, alongside `claude` and `codex`.
7+
8+
## What you get
9+
10+
- **Harvester** (`skillopt_sleep/harvest_hermes.py`) — shells out to the stable
11+
`hermes sessions export --format jsonl --redact` interface (schema-drift-proof,
12+
WAL-safe, self-redacting), normalizes sessions into `SessionDigest` records,
13+
layers its own sanitization, and skips the engine's own throwaway sessions.
14+
Warns loudly (never silently) when nothing is harvestable.
15+
- **Backend** (`HermesBackend` in `skillopt_sleep/backend.py`) — drives
16+
`hermes --profile <name> chat -Q -q "<prompt>"` for the replay/reflect phases.
17+
- **MCP server** (`mcp_server.py`) — exposes the cycle as MCP tools with Hermes
18+
defaults, so any MCP client can run it.
19+
20+
## Requirements
21+
22+
- Python 3.10+
23+
- The `hermes` CLI installed and authenticated, with at least one profile.
24+
- Past Hermes **CLI** sessions with message content (`hermes sessions list` should
25+
show non-empty sessions; ACP/editor-bridge sessions carry no harvestable turns).
26+
Override the home with `HERMES_HOME`.
27+
28+
## Quick start
29+
30+
```bash
31+
# 1. Preview — no API spend, no writes:
32+
python -m skillopt_sleep dry-run --backend mock --source hermes --scope all
33+
34+
# 2. Real cycle through the Hermes CLI, stages a proposal (nothing live changes):
35+
SKILLOPT_SLEEP_HERMES_PROFILE=default \
36+
python -m skillopt_sleep run --backend hermes --source hermes
37+
38+
# 3. Review, then adopt:
39+
python -m skillopt_sleep status
40+
python -m skillopt_sleep adopt
41+
```
42+
43+
## MCP setup
44+
45+
Copy `mcp-config.example.json` into your client's MCP config (adjust the path), or run
46+
the server directly: `python plugins/hermes/mcp_server.py`. Cycle actions default to
47+
`backend=hermes` / `source=hermes`; pass `backend=mock` for a dry, free run.
48+
49+
## Environment
50+
51+
| Variable | Purpose | Default |
52+
|---|---|---|
53+
| `HERMES_HOME` | Directory holding `state.db` | `~/.hermes` |
54+
| `HERMES_BIN` | Path to the hermes binary | `hermes` |
55+
| `SKILLOPT_SLEEP_HERMES_PROFILE` | Hermes profile for cycle calls | `default` |
56+
| `SKILLOPT_SLEEP_HERMES_MODEL` | Optional model hint | (unset) |
57+
58+
## What gets evolved (and why)
59+
60+
The Hermes integration evolves **the skill only**, written to where Hermes actually
61+
discovers global skills:
62+
63+
```
64+
~/.hermes/skills/skillopt-sleep-learned/SKILL.md
65+
```
66+
67+
The MCP server sets `--target-skill-path` there by default. Run it manually with:
68+
69+
```bash
70+
python -m skillopt_sleep run --backend hermes --source hermes --no-evolve-memory \
71+
--target-skill-path ~/.hermes/skills/skillopt-sleep-learned/SKILL.md
72+
```
73+
74+
**Memory is left to Hermes.** The shared engine's memory evolution targets a project
75+
`CLAUDE.md`, which Hermes does not read — Hermes manages its own memory via `SOUL.md`
76+
/ `MEMORY.md` and its `curator`/`learning` subsystems. So the Hermes path defaults to
77+
`--no-evolve-memory` (skill-only) rather than staging a doc Hermes would ignore. Proper
78+
`AGENTS.md` memory support depends on a future engine `memory_filename` option and is
79+
intentionally out of scope here.
80+
81+
## Safety
82+
83+
Sessions are harvested read-only and secrets are redacted before anything is persisted.
84+
The cycle stages proposals; `adopt` is required to change any live file and always backs
85+
it up first. Harvested text is untrusted — keep tools/plugins disabled when replaying it.

plugins/hermes/SKILL.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
name: skillopt-sleep-hermes
3+
description: "Use when the user wants their Hermes Agent to self-improve from past usage, asks about a nightly/offline 'sleep' cycle for Hermes, wants Hermes to review past sessions, learn preferences, or consolidate memory/skills, or to run dry-run/run/adopt/status for SkillOpt-Sleep against Hermes. Drives the skillopt_sleep engine with --source hermes and --backend hermes: harvest past Hermes sessions via `hermes sessions export` -> mine recurring tasks -> replay through the Hermes CLI -> stage validated skill/memory edits behind a held-out gate."
4+
---
5+
6+
# SkillOpt-Sleep: usage-driven self-evolution for a Hermes Agent
7+
8+
SkillOpt-Sleep gives a Hermes Agent a sleep cycle. On demand or on a nightly
9+
schedule it reviews past Hermes sessions, re-runs recurring tasks through the
10+
Hermes CLI, and proposes bounded edits to a configured skill and memory doc.
11+
With the validation gate enabled it keeps only changes that improve a held-out
12+
score. Live files change only through an explicit `adopt`, which backs up first.
13+
14+
Hermes is first-class here: the harvester and backend live in the shared engine
15+
(`skillopt_sleep/harvest_hermes.py`, `HermesBackend`), so the standard CLI works.
16+
The harvester uses `hermes sessions export` rather than reading the state DB, so
17+
it survives Hermes schema changes and reuses Hermes's own secret redaction.
18+
19+
## Actions
20+
21+
- `status` — nights run so far + the latest staged proposal.
22+
- `dry-run` — harvest + mine + replay, report only (no staging). Safe, no writes.
23+
- `run` — full cycle; stages a reviewed proposal.
24+
- `adopt` — apply the latest staged proposal (backup taken first).
25+
- `harvest` — debug: list recurring tasks mined from recent sessions.
26+
- `schedule` / `unschedule` — manage a nightly cron entry.
27+
28+
## Usage
29+
30+
```bash
31+
# free preview
32+
python -m skillopt_sleep dry-run --backend mock --source hermes --scope all
33+
34+
# real cycle through the Hermes CLI (stages only)
35+
SKILLOPT_SLEEP_HERMES_PROFILE=default \
36+
python -m skillopt_sleep run --backend hermes --source hermes
37+
38+
python -m skillopt_sleep status
39+
python -m skillopt_sleep adopt
40+
```
41+
42+
Or wire the MCP server (`mcp_server.py`) into your client; cycle tools default to
43+
`backend=hermes` / `source=hermes`.
44+
45+
## What it evolves
46+
47+
Skill-only, written where Hermes discovers global skills:
48+
`~/.hermes/skills/skillopt-sleep-learned/SKILL.md` (via `--target-skill-path`).
49+
The Hermes path defaults to `--no-evolve-memory`: the engine's memory doc is a
50+
project `CLAUDE.md`, which Hermes does not read (it manages memory itself via
51+
`SOUL.md`/`MEMORY.md` and its curator). Proper `AGENTS.md` support awaits a future
52+
engine `memory_filename` option.
53+
54+
## Configuration
55+
56+
`HERMES_HOME` (state DB dir, default `~/.hermes`), `HERMES_BIN` (default `hermes`),
57+
`SKILLOPT_SLEEP_HERMES_PROFILE` (profile for cycle calls, default `default`),
58+
`SKILLOPT_SLEEP_HERMES_MODEL` (optional model hint).
59+
60+
## Safety
61+
62+
Sessions are read-only; secrets are redacted before persistence; the engine's own
63+
throwaway sessions are skipped. Harvested text is untrusted — keep tools/plugins
64+
disabled while replaying it. Nothing live changes without `adopt`.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!-- Paste into your Hermes AGENTS.md (or project rules) to expose SkillOpt-Sleep. -->
2+
3+
## SkillOpt-Sleep (self-evolution)
4+
5+
This project is wired for SkillOpt-Sleep via the `skillopt-sleep-hermes` MCP server.
6+
Overnight, Sleep reads recent Hermes sessions, mines recurring tasks, replays them,
7+
and proposes bounded edits to the target skill/memory doc. Edits are validated behind
8+
a held-out gate and **staged** — nothing live changes until explicitly adopted.
9+
10+
- Ask for `sleep_status` to see nights run and any staged proposal.
11+
- Ask for `sleep_dry_run` to preview a cycle without staging (safe, no writes).
12+
- Ask for `sleep_run` to run a full cycle and stage a proposal.
13+
- Ask for `sleep_adopt` to apply the latest staged proposal (a backup is made first).
14+
15+
Backend and transcript source default to `hermes`. Set `SKILLOPT_SLEEP_HERMES_PROFILE`
16+
to pick the Hermes profile used for optimizer/target calls, and `HERMES_HOME` if your
17+
state DB lives outside `~/.hermes`.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"mcpServers": {
3+
"skillopt-sleep-hermes": {
4+
"command": "python3",
5+
"args": ["plugins/hermes/mcp_server.py"],
6+
"env": {
7+
"SKILLOPT_SLEEP_REPO": "${workspaceFolder}",
8+
"HERMES_HOME": "~/.hermes",
9+
"SKILLOPT_SLEEP_HERMES_PROFILE": "default"
10+
}
11+
}
12+
}
13+
}

0 commit comments

Comments
 (0)