From a166fe8fc22cb5a0a6af11e298553a0558a6411b Mon Sep 17 00:00:00 2001 From: Xubin Ren Date: Sat, 4 Apr 2026 09:34:37 +0000 Subject: [PATCH] docs: clarify memory design and source-vs-release features --- README.md | 42 ++++++++++- docs/DREAM.md | 156 --------------------------------------- docs/MEMORY.md | 179 +++++++++++++++++++++++++++++++++++++++++++++ docs/PYTHON_SDK.md | 2 + 4 files changed, 220 insertions(+), 159 deletions(-) delete mode 100644 docs/DREAM.md create mode 100644 docs/MEMORY.md diff --git a/README.md b/README.md index 7816191af..b28e5d6e7 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,9 @@ - [Agent Social Network](#-agent-social-network) - [Configuration](#️-configuration) - [Multiple Instances](#-multiple-instances) +- [Memory](#-memory) - [CLI Reference](#-cli-reference) +- [In-Chat Commands](#-in-chat-commands) - [Python SDK](#-python-sdk) - [OpenAI-Compatible API](#-openai-compatible-api) - [Docker](#-docker) @@ -151,7 +153,12 @@ ## 📦 Install -**Install from source** (latest features, recommended for development) +> [!IMPORTANT] +> This README may describe features that are available first in the latest source code. +> If you want the newest features and experiments, install from source. +> If you want the most stable day-to-day experience, install from PyPI or with `uv`. + +**Install from source** (latest features, experimental changes may land here first; recommended for development) ```bash git clone https://github.com/HKUDS/nanobot.git @@ -159,13 +166,13 @@ cd nanobot pip install -e . ``` -**Install with [uv](https://github.com/astral-sh/uv)** (stable, fast) +**Install with [uv](https://github.com/astral-sh/uv)** (stable release, fast) ```bash uv tool install nanobot-ai ``` -**Install from PyPI** (stable) +**Install from PyPI** (stable release) ```bash pip install nanobot-ai @@ -1561,6 +1568,18 @@ nanobot gateway --config ~/.nanobot-telegram/config.json --workspace /tmp/nanobo - `--workspace` overrides the workspace defined in the config file - Cron jobs and runtime media/state are derived from the config directory +## 🧠 Memory + +nanobot uses a layered memory system designed to stay light in the moment and durable over +time. + +- `memory/history.jsonl` stores append-only summarized history +- `SOUL.md`, `USER.md`, and `memory/MEMORY.md` store long-term knowledge managed by Dream +- `Dream` runs on a schedule and can also be triggered manually +- memory changes can be inspected and restored with built-in commands + +If you want the full design, see [docs/MEMORY.md](docs/MEMORY.md). + ## 💻 CLI Reference | Command | Description | @@ -1583,6 +1602,23 @@ nanobot gateway --config ~/.nanobot-telegram/config.json --workspace /tmp/nanobo Interactive mode exits: `exit`, `quit`, `/exit`, `/quit`, `:q`, or `Ctrl+D`. +## 💬 In-Chat Commands + +These commands work inside chat channels and interactive agent sessions: + +| Command | Description | +|---------|-------------| +| `/new` | Start a new conversation | +| `/stop` | Stop the current task | +| `/restart` | Restart the bot | +| `/status` | Show bot status | +| `/dream` | Run Dream memory consolidation now | +| `/dream-log` | Show the latest Dream memory change | +| `/dream-log ` | Show a specific Dream memory change | +| `/dream-restore` | List recent Dream memory versions | +| `/dream-restore ` | Restore memory to the state before a specific change | +| `/help` | Show available in-chat commands | +
Heartbeat (Periodic Tasks) diff --git a/docs/DREAM.md b/docs/DREAM.md deleted file mode 100644 index 2e01e4f5d..000000000 --- a/docs/DREAM.md +++ /dev/null @@ -1,156 +0,0 @@ -# Dream: Two-Stage Memory Consolidation - -Dream is nanobot's memory management system. It automatically extracts key information from conversations and persists it as structured knowledge files. - -## Architecture - -``` -Consolidator (per-turn) Dream (cron-scheduled) GitStore (version control) -+----------------------------+ +----------------------------+ +---------------------------+ -| token over budget → LLM | | Phase 1: analyze history | | dulwich-backed .git repo | -| summarize evicted messages |──────▶| vs existing memory files | | auto_commit on Dream run | -| → history.jsonl | | Phase 2: AgentRunner | | /dream-log: view changes | -| (plain text, no tool_call) | | + read_file/edit_file | | /dream-restore: rollback | -+----------------------------+ | → surgical incremental | +---------------------------+ - | edit of memory files | - +----------------------------+ -``` - -### Consolidator - -Lightweight, triggered on-demand after each conversation turn. When a session's estimated prompt tokens exceed 50% of the context window, the Consolidator sends the oldest message slice to the LLM for summarization and appends the result to `history.jsonl`. - -Key properties: -- Uses plain-text LLM calls (no `tool_choice`), compatible with all providers -- Cuts messages at user-turn boundaries to avoid truncating multi-turn conversations -- Up to 5 consolidation rounds until the token budget drops below the safety threshold - -### Dream - -Heavyweight, triggered by a cron schedule (default: every 2 hours). Two-phase processing: - -| Phase | Description | LLM call | -|-------|-------------|----------| -| Phase 1 | Compare `history.jsonl` against existing memory files, output `[FILE] atomic fact` lines | Plain text, no tools | -| Phase 2 | Based on the analysis, use AgentRunner with `read_file` / `edit_file` for incremental edits | With filesystem tools | - -Key properties: -- Incremental edits — never rewrites entire files -- Cursor always advances to prevent re-processing -- Phase 2 failure does not block cursor advancement (prevents infinite loops) - -### GitStore - -Pure-Python git implementation backed by [dulwich](https://github.com/jelmer/dulwich), providing version control for memory files. - -- Auto-commits after each Dream run -- Auto-generated `.gitignore` that only tracks memory files -- Supports log viewing, diff comparison, and rollback - -## Data Files - -``` -workspace/ -├── SOUL.md # Bot personality and communication style (managed by Dream) -├── USER.md # User profile and preferences (managed by Dream) -└── memory/ - ├── MEMORY.md # Long-term facts and project context (managed by Dream) - ├── history.jsonl # Consolidator summary output (append-only) - ├── .cursor # Last message index processed by Consolidator - ├── .dream_cursor # Last history.jsonl cursor processed by Dream - └── .git/ # GitStore repository -``` - -### history.jsonl Format - -Each line is a JSON object: - -```json -{"cursor": 42, "timestamp": "2026-04-03 00:02", "content": "- User prefers dark mode\n- Decided to use PostgreSQL"} -``` - -Searching history: - -```bash -# Python (cross-platform) -python -c "import json; [print(json.loads(l).get('content','')) for l in open('memory/history.jsonl','r',encoding='utf-8') if l.strip() and 'keyword' in l.lower()][-20:]" - -# grep -grep -i "keyword" memory/history.jsonl -``` - -### Compaction - -When `history.jsonl` exceeds 1000 entries, it automatically drops entries that Dream has already processed (keeping only unprocessed entries). - -## Configuration - -Configure under `agents.defaults.dream` in `~/.nanobot/config.json`: - -```json -{ - "agents": { - "defaults": { - "dream": { - "cron": "0 */2 * * *", - "model": null, - "max_batch_size": 20, - "max_iterations": 10 - } - } - } -} -``` - -| Field | Type | Default | Description | -|-------|------|---------|-------------| -| `cron` | string | `0 */2 * * *` | Cron expression for Dream run interval | -| `model` | string\|null | null | Optional model override for Dream | -| `max_batch_size` | int | 20 | Max history entries processed per run | -| `max_iterations` | int | 10 | Max tool calls in Phase 2 | - -Dependency: `pip install dulwich` - -## Commands - -| Command | Description | -|---------|-------------| -| `/dream` | Manually trigger a Dream run | -| `/dream-log` | Show the latest Dream changes (git diff) | -| `/dream-log ` | Show changes from a specific commit | -| `/dream-restore` | List the 10 most recent Dream commits | -| `/dream-restore ` | Revert a specific commit (restore to its parent state) | - -## Troubleshooting - -### Dream produces no changes - -Check whether `history.jsonl` has entries and whether `.dream_cursor` has caught up: - -```bash -# Check recent history entries -tail -5 memory/history.jsonl - -# Check Dream cursor -cat memory/.dream_cursor - -# Compare: the last entry's cursor in history.jsonl should be > .dream_cursor -``` - -### Memory files contain inaccurate information - -1. Use `/dream-log` to inspect what Dream changed -2. Use `/dream-restore ` to roll back to a previous state -3. If the information is still wrong after rollback, manually edit the memory files — Dream will preserve your edits on the next run (it skips facts that already match) - -### Git-related issues - -```bash -# Check if GitStore is initialized -ls workspace/.git - -# If missing, restart the gateway to auto-initialize - -# View commit history manually (requires git) -cd workspace && git log --oneline -``` diff --git a/docs/MEMORY.md b/docs/MEMORY.md new file mode 100644 index 000000000..ee3b91da7 --- /dev/null +++ b/docs/MEMORY.md @@ -0,0 +1,179 @@ +# Memory in nanobot + +> **Note:** This design is currently an experiment in the latest source code version and is planned to officially ship in `v0.1.5`. + +nanobot's memory is built on a simple belief: memory should feel alive, but it should not feel chaotic. + +Good memory is not a pile of notes. It is a quiet system of attention. It notices what is worth keeping, lets go of what no longer needs the spotlight, and turns lived experience into something calm, durable, and useful. + +That is the shape of memory in nanobot. + +## The Design + +nanobot does not treat memory as one giant file. + +It separates memory into layers, because different kinds of remembering deserve different tools: + +- `session.messages` holds the living short-term conversation. +- `memory/history.jsonl` is the running archive of compressed past turns. +- `SOUL.md`, `USER.md`, and `memory/MEMORY.md` are the durable knowledge files. +- `GitStore` records how those durable files change over time. + +This keeps the system light in the moment, but reflective over time. + +## The Flow + +Memory moves through nanobot in two stages. + +### Stage 1: Consolidator + +When a conversation grows large enough to pressure the context window, nanobot does not try to carry every old message forever. + +Instead, the `Consolidator` summarizes the oldest safe slice of the conversation and appends that summary to `memory/history.jsonl`. + +This file is: + +- append-only +- cursor-based +- optimized for machine consumption first, human inspection second + +Each line is a JSON object: + +```json +{"cursor": 42, "timestamp": "2026-04-03 00:02", "content": "- User prefers dark mode\n- Decided to use PostgreSQL"} +``` + +It is not the final memory. It is the material from which final memory is shaped. + +### Stage 2: Dream + +`Dream` is the slower, more thoughtful layer. It runs on a cron schedule by default and can also be triggered manually. + +Dream reads: + +- new entries from `memory/history.jsonl` +- the current `SOUL.md` +- the current `USER.md` +- the current `memory/MEMORY.md` + +Then it works in two phases: + +1. It studies what is new and what is already known. +2. It edits the long-term files surgically, not by rewriting everything, but by making the smallest honest change that keeps memory coherent. + +This is why nanobot's memory is not just archival. It is interpretive. + +## The Files + +``` +workspace/ +├── SOUL.md # The bot's long-term voice and communication style +├── USER.md # Stable knowledge about the user +└── memory/ + ├── MEMORY.md # Project facts, decisions, and durable context + ├── history.jsonl # Append-only history summaries + ├── .cursor # Consolidator write cursor + ├── .dream_cursor # Dream consumption cursor + └── .git/ # Version history for long-term memory files +``` + +These files play different roles: + +- `SOUL.md` remembers how nanobot should sound. +- `USER.md` remembers who the user is and what they prefer. +- `MEMORY.md` remembers what remains true about the work itself. +- `history.jsonl` remembers what happened on the way there. + +## Why `history.jsonl` + +The old `HISTORY.md` format was pleasant for casual reading, but it was too fragile as an operational substrate. + +`history.jsonl` gives nanobot: + +- stable incremental cursors +- safer machine parsing +- easier batching +- cleaner migration and compaction +- a better boundary between raw history and curated knowledge + +You can still search it with familiar tools: + +```bash +# grep +grep -i "keyword" memory/history.jsonl + +# jq +cat memory/history.jsonl | jq -r 'select(.content | test("keyword"; "i")) | .content' | tail -20 + +# Python +python -c "import json; [print(json.loads(l).get('content','')) for l in open('memory/history.jsonl','r',encoding='utf-8') if l.strip() and 'keyword' in l.lower()][-20:]" +``` + +The difference is philosophical as much as technical: + +- `history.jsonl` is for structure +- `SOUL.md`, `USER.md`, and `MEMORY.md` are for meaning + +## Commands + +Memory is not hidden behind the curtain. Users can inspect and guide it. + +| Command | What it does | +|---------|--------------| +| `/dream` | Run Dream immediately | +| `/dream-log` | Show the latest Dream memory change | +| `/dream-log ` | Show a specific Dream change | +| `/dream-restore` | List recent Dream memory versions | +| `/dream-restore ` | Restore memory to the state before a specific change | + +These commands exist for a reason: automatic memory is powerful, but users should always retain the right to inspect, understand, and restore it. + +## Versioned Memory + +After Dream changes long-term memory files, nanobot can record that change with `GitStore`. + +This gives memory a history of its own: + +- you can inspect what changed +- you can compare versions +- you can restore a previous state + +That turns memory from a silent mutation into an auditable process. + +## Configuration + +Dream is configured under `agents.defaults.dream`: + +```json +{ + "agents": { + "defaults": { + "dream": { + "cron": "0 */2 * * *", + "model": null, + "max_batch_size": 20, + "max_iterations": 10 + } + } + } +} +``` + +| Field | Meaning | +|-------|---------| +| `cron` | How often Dream runs | +| `model` | Optional model override for Dream | +| `max_batch_size` | How many history entries Dream processes per run | +| `max_iterations` | The tool budget for Dream's editing phase | + +## In Practice + +What this means in daily use is simple: + +- conversations can stay fast without carrying infinite context +- durable facts can become clearer over time instead of noisier +- the user can inspect and restore memory when needed + +Memory should not feel like a dump. It should feel like continuity. + +That is what this design is trying to protect. diff --git a/docs/PYTHON_SDK.md b/docs/PYTHON_SDK.md index 357722e5e..2b51055a9 100644 --- a/docs/PYTHON_SDK.md +++ b/docs/PYTHON_SDK.md @@ -1,5 +1,7 @@ # Python SDK +> **Note:** This interface is currently an experiment in the latest source code version and is planned to officially ship in `v0.1.5`. + Use nanobot programmatically — load config, run the agent, get results. ## Quick Start