feat: add pre-compaction memory flush
This commit is contained in:
@@ -99,6 +99,8 @@ These are the standard files Clawdbot expects inside the workspace:
|
||||
- Curated long-term memory.
|
||||
- Only load in the main, private session (not shared/group contexts).
|
||||
|
||||
See [Memory](/concepts/memory) for the workflow and automatic memory flush.
|
||||
|
||||
- `skills/` (optional)
|
||||
- Workspace-specific skills.
|
||||
- Overrides managed/bundled skills when names collide.
|
||||
|
||||
@@ -22,6 +22,9 @@ You’ll see:
|
||||
- `🧹 Auto-compaction complete` in verbose mode
|
||||
- `/status` showing `🧹 Compactions: <count>`
|
||||
|
||||
Before compaction, Clawdbot can run a **silent memory flush** turn to store
|
||||
durable notes to disk. See [Memory](/concepts/memory) for details and config.
|
||||
|
||||
## Manual compaction
|
||||
Use `/compact` (optionally with instructions) to force a compaction pass:
|
||||
```
|
||||
|
||||
66
docs/concepts/memory.md
Normal file
66
docs/concepts/memory.md
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
summary: "How Clawdbot memory works (workspace files + automatic memory flush)"
|
||||
read_when:
|
||||
- You want the memory file layout and workflow
|
||||
- You want to tune the automatic pre-compaction memory flush
|
||||
---
|
||||
# Memory
|
||||
|
||||
Clawdbot memory is **plain Markdown in the agent workspace**. The files are the
|
||||
source of truth; the model only “remembers” what gets written to disk.
|
||||
|
||||
## Memory files (Markdown)
|
||||
|
||||
The default workspace layout uses two memory layers:
|
||||
|
||||
- `memory/YYYY-MM-DD.md`
|
||||
- Daily log (append-only).
|
||||
- Read today + yesterday at session start.
|
||||
- `MEMORY.md` (optional)
|
||||
- Curated long-term memory.
|
||||
- **Only load in the main, private session** (never in group contexts).
|
||||
|
||||
These files live under the workspace (`agents.defaults.workspace`, default
|
||||
`~/clawd`). See [Agent workspace](/concepts/agent-workspace) for the full layout.
|
||||
|
||||
## When to write memory
|
||||
|
||||
- Decisions, preferences, and durable facts go to `MEMORY.md`.
|
||||
- Day-to-day notes and running context go to `memory/YYYY-MM-DD.md`.
|
||||
- If someone says “remember this,” write it down (don’t keep it in RAM).
|
||||
|
||||
## Automatic memory flush (pre-compaction ping)
|
||||
|
||||
When a session is **close to auto-compaction**, Clawdbot triggers a **silent
|
||||
agentic turn** that reminds the model to write durable memory **before** the
|
||||
context is compacted. The default prompt encourages the model to respond with
|
||||
`NO_REPLY` when there’s nothing to store, so the user never sees this turn.
|
||||
|
||||
This is controlled by `agents.defaults.compaction.memoryFlush`:
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
compaction: {
|
||||
reserveTokensFloor: 20000,
|
||||
memoryFlush: {
|
||||
enabled: true,
|
||||
softThresholdTokens: 4000,
|
||||
systemPrompt: "Session nearing compaction. Store durable memories now.",
|
||||
prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Details:
|
||||
- **Soft threshold**: flush triggers when the session token estimate crosses
|
||||
`contextWindow - reserveTokensFloor - softThresholdTokens`.
|
||||
- **Silent** by default: prompts include `NO_REPLY` so nothing is delivered.
|
||||
- **One flush per compaction cycle** (tracked in `sessions.json`).
|
||||
|
||||
For the full compaction lifecycle, see
|
||||
[Session management + compaction](/reference/session-management-compaction).
|
||||
@@ -608,6 +608,7 @@
|
||||
"token-use",
|
||||
"concepts/oauth",
|
||||
"concepts/agent-workspace",
|
||||
"concepts/memory",
|
||||
"concepts/multi-agent",
|
||||
"concepts/compaction",
|
||||
"concepts/session",
|
||||
|
||||
@@ -1368,6 +1368,40 @@ Example (adaptive tuned):
|
||||
|
||||
See [/concepts/session-pruning](/concepts/session-pruning) for behavior details.
|
||||
|
||||
#### `agents.defaults.compaction` (reserve headroom + memory flush)
|
||||
|
||||
`agents.defaults.compaction.reserveTokensFloor` enforces a minimum `reserveTokens`
|
||||
value for Pi compaction (default: `20000`). Set it to `0` to disable the floor.
|
||||
|
||||
`agents.defaults.compaction.memoryFlush` runs a **silent** agentic turn before
|
||||
auto-compaction, instructing the model to store durable memories on disk (e.g.
|
||||
`memory/YYYY-MM-DD.md`). It triggers when the session token estimate crosses a
|
||||
soft threshold below the compaction limit.
|
||||
|
||||
Defaults:
|
||||
- `memoryFlush.enabled`: `true`
|
||||
- `memoryFlush.softThresholdTokens`: `4000`
|
||||
- `memoryFlush.prompt` / `memoryFlush.systemPrompt`: built-in defaults with `NO_REPLY`
|
||||
|
||||
Example (tuned):
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
compaction: {
|
||||
reserveTokensFloor: 24000,
|
||||
memoryFlush: {
|
||||
enabled: true,
|
||||
softThresholdTokens: 6000,
|
||||
systemPrompt: "Session nearing compaction. Store durable memories now.",
|
||||
prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Block streaming:
|
||||
- `agents.defaults.blockStreamingDefault`: `"on"`/`"off"` (default off).
|
||||
- Provider overrides: `*.blockStreaming` (and per-account variants) to force block streaming on/off.
|
||||
|
||||
@@ -107,6 +107,8 @@ Key fields (not exhaustive):
|
||||
- Token counters (best-effort / provider-dependent):
|
||||
- `inputTokens`, `outputTokens`, `totalTokens`, `contextTokens`
|
||||
- `compactionCount`: how often auto-compaction completed for this session key
|
||||
- `memoryFlushAt`: timestamp for the last pre-compaction memory flush
|
||||
- `memoryFlushCompactionCount`: compaction count when the last flush ran
|
||||
|
||||
The store is safe to edit, but the Gateway is the authority: it may rewrite or rehydrate entries as sessions run.
|
||||
|
||||
@@ -191,12 +193,15 @@ Pi’s compaction settings live in Pi settings:
|
||||
|
||||
Clawdbot also enforces a safety floor for embedded runs:
|
||||
|
||||
- If `compaction.reserveTokens < 20000`, Clawdbot bumps it to 20000.
|
||||
- If `compaction.reserveTokens < reserveTokensFloor`, Clawdbot bumps it.
|
||||
- Default floor is `20000` tokens.
|
||||
- Set `agents.defaults.compaction.reserveTokensFloor: 0` to disable the floor.
|
||||
- If it’s already higher, Clawdbot leaves it alone.
|
||||
|
||||
Why: leave enough headroom for multi-turn “housekeeping” (like memory writes) before compaction becomes unavoidable.
|
||||
|
||||
Implementation: `ensurePiCompactionReserveTokens()` in `src/agents/pi-settings.ts` (called from `src/agents/pi-embedded-runner.ts`).
|
||||
Implementation: `ensurePiCompactionReserveTokens()` in `src/agents/pi-settings.ts`
|
||||
(called from `src/agents/pi-embedded-runner.ts`).
|
||||
|
||||
---
|
||||
|
||||
@@ -223,22 +228,33 @@ As of `2026.1.10`, Clawdbot also suppresses **draft/typing streaming** when a pa
|
||||
|
||||
---
|
||||
|
||||
## Pre-compaction “memory flush” (design)
|
||||
## Pre-compaction “memory flush” (implemented)
|
||||
|
||||
Goal: before auto-compaction happens, run a short sequence of turns that writes durable state to disk (e.g. `memory/YYYY-MM-DD.md` in the agent workspace) so compaction can’t erase critical context.
|
||||
Goal: before auto-compaction happens, run a silent agentic turn that writes durable
|
||||
state to disk (e.g. `memory/YYYY-MM-DD.md` in the agent workspace) so compaction can’t
|
||||
erase critical context.
|
||||
|
||||
Two viable hooks:
|
||||
Clawdbot uses the **pre-threshold flush** approach:
|
||||
|
||||
1) **Pre-threshold flush (Clawdbot-side)**
|
||||
- Monitor session context usage.
|
||||
- When it crosses a “soft threshold” (below Pi’s real compaction threshold), enqueue a silent “write memory now” directive to the agent.
|
||||
- Use `NO_REPLY` so the user sees nothing.
|
||||
1) Monitor session context usage.
|
||||
2) When it crosses a “soft threshold” (below Pi’s compaction threshold), run a silent
|
||||
“write memory now” directive to the agent.
|
||||
3) Use `NO_REPLY` so the user sees nothing.
|
||||
|
||||
2) **Pi extension hook (`session_before_compact`)**
|
||||
- Pi’s extension API exposes a `session_before_compact` event that receives compaction preparation details and can cancel or replace compaction.
|
||||
- Clawdbot can ship an extension that reacts here and performs housekeeping (and/or produces a custom compaction result).
|
||||
Config (`agents.defaults.compaction.memoryFlush`):
|
||||
- `enabled` (default: `true`)
|
||||
- `softThresholdTokens` (default: `4000`)
|
||||
- `prompt` (user message for the flush turn)
|
||||
- `systemPrompt` (extra system prompt appended for the flush turn)
|
||||
|
||||
Clawdbot currently documents the *concept* of daily memory in the workspace template (see [/concepts/agent-workspace](/concepts/agent-workspace)) but does not yet ship an automated pre-compaction flush loop.
|
||||
Notes:
|
||||
- The default prompt/system prompt include a `NO_REPLY` hint to suppress delivery.
|
||||
- The flush runs once per compaction cycle (tracked in `sessions.json`).
|
||||
- The flush runs only for embedded Pi sessions (CLI backends skip it).
|
||||
- See [Memory](/concepts/memory) for the workspace file layout and write patterns.
|
||||
|
||||
Pi also exposes a `session_before_compact` hook in the extension API, but Clawdbot’s
|
||||
flush logic lives on the Gateway side today.
|
||||
|
||||
---
|
||||
|
||||
@@ -251,4 +267,3 @@ Clawdbot currently documents the *concept* of daily memory in the workspace temp
|
||||
- compaction settings (`reserveTokens` too high for the model window can cause earlier compaction)
|
||||
- tool-result bloat: enable/tune session pruning
|
||||
- Silent turns leaking? Confirm the reply starts with `NO_REPLY` (exact token) and you’re on a build that includes the streaming suppression fix.
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ clawdbot setup
|
||||
```
|
||||
|
||||
Full workspace layout + backup guide: [Agent workspace](/concepts/agent-workspace)
|
||||
Memory workflow: [Memory](/concepts/memory)
|
||||
|
||||
Optional: choose a different workspace with `agents.defaults.workspace` (supports `~`).
|
||||
|
||||
|
||||
@@ -197,6 +197,15 @@ ClawdHub installs into `./skills` under your current directory; Clawdbot treats
|
||||
|
||||
Yes. See [Sandboxing](/gateway/sandboxing). For Docker-specific setup (full gateway in Docker or sandbox images), see [Docker](/install/docker).
|
||||
|
||||
### How does memory work?
|
||||
|
||||
Clawdbot memory is just Markdown files in the agent workspace:
|
||||
- Daily notes in `memory/YYYY-MM-DD.md`
|
||||
- Curated long-term notes in `MEMORY.md` (main/private sessions only)
|
||||
|
||||
Clawdbot also runs a **silent pre-compaction memory flush** to remind the model
|
||||
to write durable notes before auto-compaction. See [Memory](/concepts/memory).
|
||||
|
||||
## Where things live on disk
|
||||
|
||||
### Where does Clawdbot store its data?
|
||||
|
||||
@@ -34,6 +34,7 @@ Use these hubs to discover every page, including deep dives and reference docs t
|
||||
- [Architecture](/concepts/architecture)
|
||||
- [Agent runtime](/concepts/agent)
|
||||
- [Agent workspace](/concepts/agent-workspace)
|
||||
- [Memory](/concepts/memory)
|
||||
- [Agent loop](/concepts/agent-loop)
|
||||
- [Streaming + chunking](/concepts/streaming)
|
||||
- [Multi-agent routing](/concepts/multi-agent)
|
||||
|
||||
Reference in New Issue
Block a user