Skip to content
dsh.fish
Bundle

dsh-skillopt

Microsoft SkillOpt-Sleep integration for DeepSeek Harness: give your dsh agent a nightly sleep cycle that harvests past sessions, replays recurring tasks, and consolidates validated skills behind a held-out gate.

Source
WODE25500
stars
3 stars
License
MIT
Updated
Updated 7 days ago

Readme

# SkillOpt-Sleep — DeepSeek Harness (dsh) integration

Give your **DeepSeek Harness** agent a nightly **sleep cycle**: it reviews past
sessions offline, replays your recurring tasks on your own API budget, and
consolidates what it learns into validated skills behind a held-out gate. Same
engine as the Claude Code / Codex / Cursor integrations
([skillopt_sleep](https://github.com/microsoft/SkillOpt)), wired into dsh's
plugin system as native tools plus a bundled skill.

DeepSeek Harness is the "everything is a plugin" agent framework
([deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness)).
Plugins are TypeScript modules exporting an `apply(ctx)` function that register
capabilities (tools, services, events, settings) on the Cordis context.

## Why a sleep cycle?

Skills improve when an agent re-examines its own sessions — not just when you
hand-tune a prompt. The sleep cycle turns your everyday usage into a nightly,
validation-gated skill-improvement loop: harvest what you actually did, replay
the recurring tasks on your own API budget, and keep only the changes that pass
a held-out gate. It's the same engine as the Claude Code / Codex / Cursor
integrations, wired into dsh as native tools plus a bundled skill.

## What this integration adds

| Component | Purpose |
|---|---|
| `src/index.js` | dsh plugin entry: registers 7 `skillopt_*` tools + Schemastery config |
| `cordis.patch.yml` | bundle patch layer — drop `dsh-skillopt` into any profile's bundles |
| `skills/skillopt-sleep/SKILL.md` | agent skill: when to use the tools, operating rules, data-boundary rules |
| `scripts/sleep.py` | bootstrap/self-check runner (same command shape the tools use) |
| `package.json` | npm package metadata (bundle manifest) |

## Tools

| Tool | skillopt_sleep action | Behavior |
|---|---|---|
| `skillopt_status` | `status` | state, engine availability, latest staged proposal & report |
| `skillopt_dry_run` | `dry-run` | full preview (harvest+mine+replay), stages nothing |
| `skillopt_run` | `run` | full cycle, stages a proposal (live files unchanged) |
| `skillopt_adopt` | `adopt` | apply latest staged proposal (with backup) — the live-change boundary |
| `skillopt_harvest` | `harvest` | read-only show/export of mined tasks |
| `skillopt_schedule` / `skillopt_unschedule` | `schedule` / `unschedule` | install/remove the nightly cron entry |

## Prerequisites

- DeepSeek Harness (dsh) installed
- Python 3.10+ with the SkillOpt-Sleep engine:

```bash
pip install skillopt          # or use this source checkout
```

## Install

### As a bundle in a profile

Add `dsh-skillopt` to the profile's bundles, or in the profile `cordis.patch.yml`:

```yaml
- insert:
    - id: skillopt
      name: './src/index.js'
      config:
        backend: mock          # or codex / claude / cursor / pi / opencode / handoff …
        project: /path/to/project
        preferences: 'Always use async/await'
```

### Local patch overlay (dev)

Run from a DeepSeek Harness **source checkout** (the official dev workflow,
`pnpm` resolves the workspace `dsh` bin):

```bash
pnpm dsh web --patch ./plugins/dsh/cordis.patch.yml
```

If `dsh` is installed **globally** (npm install -g), use it directly:

```bash
dsh web --patch ./plugins/dsh/cordis.patch.yml
```

Either way the patch inserts the `skillopt` plugin row into the profile; then
ask the agent: "Use skillopt_status to check the sleep cycle state."

## Config keys

| Key | Default | Purpose |
|---|---|---|
| `pythonCmd` | `python` | Python interpreter for the engine |
| `module` | — (bootstrap) | engine Python module override (`python -m <module>`) |
| `engineScript` | — (scripts/sleep.py) | engine bootstrap script override |
| `project` | — | default project directory |
| `scope` | — | harvest scope: `all` \| `invoked` |
| `backend` | — | `mock\|claude\|codex\|copilot\|cursor\|pi\|opencode\|handoff\|azure_openai` |
| `source` | — | `claude\|codex\|copilot\|cursor\|pi\|opencode\|auto` |
| `model` | — | backend model override |
| `maxTasks` / `maxSessions` | — | mine/harvest caps |
| `editBudget` | — | bounded edits per cycle |
| `preferences` | — | house rules for the reflection prior |
| `jsonOutput` | `false` | machine-readable JSON output |
| `autoAdopt` | `false` | OPERATOR-ONLY: auto-adopt a passed proposal without asking |
| `unscheduleAll` | `false` | OPERATOR-ONLY: allow `skillopt_unschedule` to remove every managed entry |
| `timeoutMs` | `600000` | per-call engine timeout in milliseconds |

Advanced engine keys (`gate_mode`, `gate_metric`, `gate_no_regression`,
`dream_rollouts`, `recall_k`, `evolve_memory`/`evolve_skill`) go in
`~/.skillopt-sleep/config.json` — the same file shared by all integrations.

## Data boundary

- Harvest is read-only; `mock`/`handoff` make no network calls.
- `run` stages proposals; `adopt` is the normal live-change boundary and backs up first.
- Real backends send truncated transcript excerpts and derived tasks to the
  selected provider. For sensitive sessions, export tasks first (`skillopt_harvest`
  with `output=`), redact, set `"reviewed": true`, then replay — real backends
  refuse unreviewed task files.
- Outbound prompts are not guaranteed secret-free; review source & provider policy.

## Validate (no API spend)

```bash
python -m skillopt_sleep.experiments.run_experiment --persona researcher --assert-improves
```

See the [SkillOpt-Sleep documentation](../../docs/sleep/README.md) for recorded
results, limitations, and the supported integration surface.

Install

dsh plugin --profile web add github:WODE25500/dsh-skillopt

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source