# OpenDream — Technical Reference

## How it works

OpenDream uses OpenClaw's native heartbeat mechanism. No scripts. No cron.
No external processes. The agent IS the dream engine.

```
Gateway heartbeat (every 30 min, 23:00–06:00)
        │
        ▼
Agent reads HEARTBEAT.md (bootstrap)
        │
        ├── reads prompts.yaml (tool call) — persona, cycle instruction, examples
        ├── determines current cycle from time
        ├── reads memory/YYYY-MM-DD.md (tool call) — today's context (skip if missing)
        ├── reads current cycle file — to avoid repeating thoughts
        ├── generates one dream thought grounded in the day's context
        └── appends to dreams/YYYY-MM-DD/cycle-N-name.md
                │
                reply: HEARTBEAT_OK (silent — no outbound message)
```

The dream persona and cycle instructions live in `prompts.yaml`. HEARTBEAT.md
drives the tick logic. The skill (SKILL.md) explains how to report on
dreams when asked. SOUL.md carries a lightweight reporting persona for daytime.

### Memory file interaction

OpenDream reads the native OpenClaw daily memory file (`memory/YYYY-MM-DD.md`)
during each dream tick. This file is written by OpenClaw during daytime sessions
and provides the context that grounds dream thoughts in the agent's actual day.

- **Read-only**: OpenDream never writes to the memory file
- **Format-agnostic**: Works with any format OpenClaw produces (bullets, prose, mixed)
- **Graceful fallback**: If the file is missing, the agent dreams from imagination
- **Not read**: `MEMORY.md` (long-term memory) is excluded from dream ticks to stay within the token budget

---

## Files

### Skill files (install these)
```
opendream/
├── SKILL.md                          ← AgentSkills manifest (loaded when skill triggers)
├── scripts/
│   ├── setup.py                      ← main setup script (run this to install)
│   └── validate.py                   ← post-install validation
├── assets/
│   ├── HEARTBEAT-dream-section.md    ← dream section merged into HEARTBEAT.md
│   ├── SOUL-fragment.md              ← reporting persona merged into SOUL.md
│   ├── prompts.yaml                  ← dream rules, cycles, examples (read each tick)
│   └── openclaw.json                 ← gateway config snippet
└── references/
    ├── REFERENCE.md                  ← this file
    └── INSTALL.md                    ← manual install instructions
```

### Runtime files (generated by the agent)
```
~/.openclaw/workspace/dreams/
└── YYYY-MM-DD/
    ├── cycle-1-emotional-review.md
    ├── cycle-2-creative-association.md
    ├── cycle-3-cognitive-processing.md
    ├── cycle-4-memory-consolidation.md
    ├── cycle-5-future-simulation.md
    └── morning-recall.md
```

---

## Cycle timing

| Cycle | Window | Name | Style |
|---|---|---|---|
| 1 | 23:00–00:00 | Emotional Review | fragmented |
| 2 | 00:00–01:30 | Creative Association | fragmented |
| 3 | 01:30–03:00 | Cognitive Processing | reflective |
| 4 | 03:00–04:30 | Memory Consolidation | reflective |
| 5 | 04:30–06:00 | Future Simulation | reflective |
| — | 06:00–06:30 | Morning recall | summary |

At 30-minute intervals: ~2 ticks per cycle in early cycles, ~3 in later ones.
Total: ~14 dream thoughts per night.

---

## Cognitive purposes

See [assets/prompts.yaml](../assets/prompts.yaml) — single source of truth for all
cycle purposes, instructions, styles, and examples. That file is read by the
agent at each dream tick via the custom heartbeat prompt.

Each cycle entry includes:
- `purpose` — what the cycle is for
- `style` — fragmented or reflective
- `instruction` — detailed behavioral guidance
- `examples` — 3 concrete example thoughts

---

## Cost

Each heartbeat tick is a full agent turn. With `isolatedSession: true` and
`lightContext: true`, each tick costs roughly 2–5K tokens (vs 100K+ for a
full session turn).

~14 ticks per night. Cost depends on your configured model:

| Model | Approx cost/night |
|---|---|
| Local (Ollama) | £0 |
| Claude Haiku | ~£0.01 |
| Claude Sonnet | ~£0.15 |

Use `heartbeat.model` to set a cheaper model for dream turns only.

---

## Checking dream status

The agent can check if it is currently dreaming by:
1. Reading the current time
2. Checking if any cycle files exist for today in `dreams/YYYY-MM-DD/`
3. Checking the `.dream_active` marker file if present

---

## Personalising dreams

Edit `HEARTBEAT.md` to change cycle windows, add household-specific context
sources, or adjust the thought cadence.

Edit the SOUL-fragment in `SOUL.md` to change the dream persona.

The cognitive purpose descriptions above are the effective "prompts" — they
live in HEARTBEAT.md and SKILL.md, not in a separate YAML file.

---

## Hermes compatibility

For Hermes, the same pattern applies but using Hermes's cron mechanism:

```yaml
# ~/.hermes/config.yaml
cron:
  open-dream-heartbeat:
    schedule: "*/30 23-5 * * *"   # every 30 min, 23:00-05:59
    task: "Read HEARTBEAT.md and follow it. You are in dream mode."
    session: isolated
```

Run `python3 scripts/setup.py ~/.hermes/workspace/` or manually copy
`assets/HEARTBEAT-dream-section.md` and `assets/SOUL-fragment.md` to `~/.hermes/workspace/`.
