Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/sleep/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ skillopt-sleep schedule # install a nightly cron entry for this project

The per-agent integrations below still come from the repo; the CLI above is the
standalone, pip-only way to run a cycle. Claude Code, Codex, Copilot, and Devin wrap
the shared engine. OpenClaw is a separate reference adaptation and has its own setup.
the shared engine; Hermes Agent is wired into the core engine directly (`--source hermes`
/ `--backend hermes`). OpenClaw is a separate reference adaptation and has its own setup.

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

Expand All @@ -64,6 +65,7 @@ One engine, thin per-agent shells (see [`plugins/`](https://github.com/microsoft
| **Codex** | [`plugins/codex`](https://github.com/microsoft/SkillOpt/tree/main/plugins/codex) | `bash plugins/codex/install.sh` → `skillopt-sleep` skill |
| **Copilot** | [`plugins/copilot`](https://github.com/microsoft/SkillOpt/tree/main/plugins/copilot) | register `plugins/copilot/mcp_server.py` as an MCP server |
| **Devin** | [`plugins/devin`](https://github.com/microsoft/SkillOpt/tree/main/plugins/devin) | register `plugins/devin/mcp_server.py` as an MCP server |
| **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` |
| **OpenClaw** | [`plugins/openclaw`](https://github.com/microsoft/SkillOpt/tree/main/plugins/openclaw) | adapt the reference wrapper and paths for your installation |

To use DeepSeek, vLLM, Ollama, or another Chat Completions server, see
Expand Down
12 changes: 8 additions & 4 deletions plugins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ runtime dependency on the paper's `skillopt/` experiment package.

## Available integrations

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

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

## Install
Expand All @@ -32,6 +35,7 @@ for your workflow.
| **Codex** | `bash plugins/codex/install.sh` | ask Codex to use the `skillopt-sleep` skill |
| **Copilot** | register `plugins/copilot/mcp_server.py` using its example MCP config | ask Copilot to run `sleep_status` |
| **Devin** | register `plugins/devin/mcp_server.py` using its example MCP config | ask Devin to run `sleep_status` |
| **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` |
| **OpenClaw** | follow and adapt [`openclaw/README.md`](openclaw/README.md) | validate paths, credentials, and tasks locally |

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

| Flag | Default | Purpose |
|---|---|---|
| `--backend mock\|claude\|codex\|copilot\|handoff\|azure_openai` | `mock` | select who performs model calls |
| `--backend mock\|claude\|codex\|copilot\|handoff\|azure_openai\|hermes` | `mock` | select who performs model calls |
| `--model NAME` | backend default | select a backend-specific model |
| `--source claude\|codex\|auto` | `claude` | select the transcript source |
| `--source claude\|codex\|hermes\|auto` | `claude` | select the transcript source |
| `--project PATH` | current directory | select the project and invoked harvest scope |
| `--scope invoked\|all` | `invoked` | limit transcript harvesting |
| `--target-skill-path PATH` | managed skill | select a specific `SKILL.md` to stage/adopt |
Expand Down
85 changes: 85 additions & 0 deletions plugins/hermes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# SkillOpt-Sleep — Hermes Agent integration

First-class integration of the [Hermes Agent](https://github.com/NousResearch/Hermes)
CLI with the shared `skillopt_sleep` engine. Unlike the reference OpenClaw adapter,
Hermes is wired directly into core: `--source hermes` and `--backend hermes` work from
the shared CLI, alongside `claude` and `codex`.

## What you get

- **Harvester** (`skillopt_sleep/harvest_hermes.py`) — shells out to the stable
`hermes sessions export --format jsonl --redact` interface (schema-drift-proof,
WAL-safe, self-redacting), normalizes sessions into `SessionDigest` records,
layers its own sanitization, and skips the engine's own throwaway sessions.
Warns loudly (never silently) when nothing is harvestable.
- **Backend** (`HermesBackend` in `skillopt_sleep/backend.py`) — drives
`hermes --profile <name> chat -Q -q "<prompt>"` for the replay/reflect phases.
- **MCP server** (`mcp_server.py`) — exposes the cycle as MCP tools with Hermes
defaults, so any MCP client can run it.

## Requirements

- Python 3.10+
- The `hermes` CLI installed and authenticated, with at least one profile.
- Past Hermes **CLI** sessions with message content (`hermes sessions list` should
show non-empty sessions; ACP/editor-bridge sessions carry no harvestable turns).
Override the home with `HERMES_HOME`.

## Quick start

```bash
# 1. Preview — no API spend, no writes:
python -m skillopt_sleep dry-run --backend mock --source hermes --scope all

# 2. Real cycle through the Hermes CLI, stages a proposal (nothing live changes):
SKILLOPT_SLEEP_HERMES_PROFILE=default \
python -m skillopt_sleep run --backend hermes --source hermes

# 3. Review, then adopt:
python -m skillopt_sleep status
python -m skillopt_sleep adopt
```

## MCP setup

Copy `mcp-config.example.json` into your client's MCP config (adjust the path), or run
the server directly: `python plugins/hermes/mcp_server.py`. Cycle actions default to
`backend=hermes` / `source=hermes`; pass `backend=mock` for a dry, free run.

## Environment

| Variable | Purpose | Default |
|---|---|---|
| `HERMES_HOME` | Directory holding `state.db` | `~/.hermes` |
| `HERMES_BIN` | Path to the hermes binary | `hermes` |
| `SKILLOPT_SLEEP_HERMES_PROFILE` | Hermes profile for cycle calls | `default` |
| `SKILLOPT_SLEEP_HERMES_MODEL` | Optional model hint | (unset) |

## What gets evolved (and why)

The Hermes integration evolves **the skill only**, written to where Hermes actually
discovers global skills:

```
~/.hermes/skills/skillopt-sleep-learned/SKILL.md
```

The MCP server sets `--target-skill-path` there by default. Run it manually with:

```bash
python -m skillopt_sleep run --backend hermes --source hermes --no-evolve-memory \
--target-skill-path ~/.hermes/skills/skillopt-sleep-learned/SKILL.md
```

**Memory is left to Hermes.** The shared engine's memory evolution targets a project
`CLAUDE.md`, which Hermes does not read — Hermes manages its own memory via `SOUL.md`
/ `MEMORY.md` and its `curator`/`learning` subsystems. So the Hermes path defaults to
`--no-evolve-memory` (skill-only) rather than staging a doc Hermes would ignore. Proper
`AGENTS.md` memory support depends on a future engine `memory_filename` option and is
intentionally out of scope here.

## Safety

Sessions are harvested read-only and secrets are redacted before anything is persisted.
The cycle stages proposals; `adopt` is required to change any live file and always backs
it up first. Harvested text is untrusted — keep tools/plugins disabled when replaying it.
64 changes: 64 additions & 0 deletions plugins/hermes/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
name: skillopt-sleep-hermes
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."
---

# SkillOpt-Sleep: usage-driven self-evolution for a Hermes Agent

SkillOpt-Sleep gives a Hermes Agent a sleep cycle. On demand or on a nightly
schedule it reviews past Hermes sessions, re-runs recurring tasks through the
Hermes CLI, and proposes bounded edits to a configured skill and memory doc.
With the validation gate enabled it keeps only changes that improve a held-out
score. Live files change only through an explicit `adopt`, which backs up first.

Hermes is first-class here: the harvester and backend live in the shared engine
(`skillopt_sleep/harvest_hermes.py`, `HermesBackend`), so the standard CLI works.
The harvester uses `hermes sessions export` rather than reading the state DB, so
it survives Hermes schema changes and reuses Hermes's own secret redaction.

## Actions

- `status` — nights run so far + the latest staged proposal.
- `dry-run` — harvest + mine + replay, report only (no staging). Safe, no writes.
- `run` — full cycle; stages a reviewed proposal.
- `adopt` — apply the latest staged proposal (backup taken first).
- `harvest` — debug: list recurring tasks mined from recent sessions.
- `schedule` / `unschedule` — manage a nightly cron entry.

## Usage

```bash
# free preview
python -m skillopt_sleep dry-run --backend mock --source hermes --scope all

# real cycle through the Hermes CLI (stages only)
SKILLOPT_SLEEP_HERMES_PROFILE=default \
python -m skillopt_sleep run --backend hermes --source hermes

python -m skillopt_sleep status
python -m skillopt_sleep adopt
```

Or wire the MCP server (`mcp_server.py`) into your client; cycle tools default to
`backend=hermes` / `source=hermes`.

## What it evolves

Skill-only, written where Hermes discovers global skills:
`~/.hermes/skills/skillopt-sleep-learned/SKILL.md` (via `--target-skill-path`).
The Hermes path defaults to `--no-evolve-memory`: the engine's memory doc is a
project `CLAUDE.md`, which Hermes does not read (it manages memory itself via
`SOUL.md`/`MEMORY.md` and its curator). Proper `AGENTS.md` support awaits a future
engine `memory_filename` option.

## Configuration

`HERMES_HOME` (state DB dir, default `~/.hermes`), `HERMES_BIN` (default `hermes`),
`SKILLOPT_SLEEP_HERMES_PROFILE` (profile for cycle calls, default `default`),
`SKILLOPT_SLEEP_HERMES_MODEL` (optional model hint).

## Safety

Sessions are read-only; secrets are redacted before persistence; the engine's own
throwaway sessions are skipped. Harvested text is untrusted — keep tools/plugins
disabled while replaying it. Nothing live changes without `adopt`.
17 changes: 17 additions & 0 deletions plugins/hermes/hermes-rules.snippet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!-- Paste into your Hermes AGENTS.md (or project rules) to expose SkillOpt-Sleep. -->

## SkillOpt-Sleep (self-evolution)

This project is wired for SkillOpt-Sleep via the `skillopt-sleep-hermes` MCP server.
Overnight, Sleep reads recent Hermes sessions, mines recurring tasks, replays them,
and proposes bounded edits to the target skill/memory doc. Edits are validated behind
a held-out gate and **staged** — nothing live changes until explicitly adopted.

- Ask for `sleep_status` to see nights run and any staged proposal.
- Ask for `sleep_dry_run` to preview a cycle without staging (safe, no writes).
- Ask for `sleep_run` to run a full cycle and stage a proposal.
- Ask for `sleep_adopt` to apply the latest staged proposal (a backup is made first).

Backend and transcript source default to `hermes`. Set `SKILLOPT_SLEEP_HERMES_PROFILE`
to pick the Hermes profile used for optimizer/target calls, and `HERMES_HOME` if your
state DB lives outside `~/.hermes`.
13 changes: 13 additions & 0 deletions plugins/hermes/mcp-config.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"mcpServers": {
"skillopt-sleep-hermes": {
"command": "python3",
"args": ["plugins/hermes/mcp_server.py"],
"env": {
"SKILLOPT_SLEEP_REPO": "${workspaceFolder}",
"HERMES_HOME": "~/.hermes",
"SKILLOPT_SLEEP_HERMES_PROFILE": "default"
}
}
}
}
Loading