mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 04:36:04 +00:00
chore: Run pnpm format:fix.
This commit is contained in:
@@ -5,6 +5,7 @@ read_when:
|
||||
- You are changing auto-compaction behavior or adding “pre-compaction” housekeeping
|
||||
- You want to implement memory flushes or silent system turns
|
||||
---
|
||||
|
||||
# Session Management & Compaction (Deep Dive)
|
||||
|
||||
This document explains how OpenClaw manages sessions end-to-end:
|
||||
@@ -18,6 +19,7 @@ This document explains how OpenClaw manages sessions end-to-end:
|
||||
- **Silent housekeeping** (e.g. memory writes that shouldn’t produce user-visible output)
|
||||
|
||||
If you want a higher-level overview first, start with:
|
||||
|
||||
- [/concepts/session](/concepts/session)
|
||||
- [/concepts/compaction](/concepts/compaction)
|
||||
- [/concepts/session-pruning](/concepts/session-pruning)
|
||||
@@ -38,12 +40,12 @@ OpenClaw is designed around a single **Gateway process** that owns session state
|
||||
|
||||
OpenClaw persists sessions in two layers:
|
||||
|
||||
1) **Session store (`sessions.json`)**
|
||||
1. **Session store (`sessions.json`)**
|
||||
- Key/value map: `sessionKey -> SessionEntry`
|
||||
- Small, mutable, safe to edit (or delete entries)
|
||||
- Tracks session metadata (current session id, last activity, toggles, token counters, etc.)
|
||||
|
||||
2) **Transcript (`<sessionId>.jsonl`)**
|
||||
2. **Transcript (`<sessionId>.jsonl`)**
|
||||
- Append-only transcript with tree structure (entries have `id` + `parentId`)
|
||||
- Stores the actual conversation + tool calls + compaction summaries
|
||||
- Used to rebuild the model context for future turns
|
||||
@@ -64,7 +66,7 @@ OpenClaw resolves these via `src/config/sessions.ts`.
|
||||
|
||||
## Session keys (`sessionKey`)
|
||||
|
||||
A `sessionKey` identifies *which conversation bucket* you’re in (routing + isolation).
|
||||
A `sessionKey` identifies _which conversation bucket_ you’re in (routing + isolation).
|
||||
|
||||
Common patterns:
|
||||
|
||||
@@ -83,6 +85,7 @@ The canonical rules are documented at [/concepts/session](/concepts/session).
|
||||
Each `sessionKey` points at a current `sessionId` (the transcript file that continues the conversation).
|
||||
|
||||
Rules of thumb:
|
||||
|
||||
- **Reset** (`/new`, `/reset`) creates a new `sessionId` for that `sessionKey`.
|
||||
- **Daily reset** (default 4:00 AM local time on the gateway host) creates a new `sessionId` on the next message after the reset boundary.
|
||||
- **Idle expiry** (`session.reset.idleMinutes` or legacy `session.idleMinutes`) creates a new `sessionId` when a message arrives after the idle window. When daily + idle are both configured, whichever expires first wins.
|
||||
@@ -122,13 +125,15 @@ The store is safe to edit, but the Gateway is the authority: it may rewrite or r
|
||||
Transcripts are managed by `@mariozechner/pi-coding-agent`’s `SessionManager`.
|
||||
|
||||
The file is JSONL:
|
||||
|
||||
- First line: session header (`type: "session"`, includes `id`, `cwd`, `timestamp`, optional `parentSession`)
|
||||
- Then: session entries with `id` + `parentId` (tree)
|
||||
|
||||
Notable entry types:
|
||||
|
||||
- `message`: user/assistant/toolResult messages
|
||||
- `custom_message`: extension-injected messages that *do* enter model context (can be hidden from UI)
|
||||
- `custom`: extension state that does *not* enter model context
|
||||
- `custom_message`: extension-injected messages that _do_ enter model context (can be hidden from UI)
|
||||
- `custom`: extension state that does _not_ enter model context
|
||||
- `compaction`: persisted compaction summary with `firstKeptEntryId` and `tokensBefore`
|
||||
- `branch_summary`: persisted summary when navigating a tree branch
|
||||
|
||||
@@ -140,10 +145,11 @@ OpenClaw intentionally does **not** “fix up” transcripts; the Gateway uses `
|
||||
|
||||
Two different concepts matter:
|
||||
|
||||
1) **Model context window**: hard cap per model (tokens visible to the model)
|
||||
2) **Session store counters**: rolling stats written into `sessions.json` (used for /status and dashboards)
|
||||
1. **Model context window**: hard cap per model (tokens visible to the model)
|
||||
2. **Session store counters**: rolling stats written into `sessions.json` (used for /status and dashboards)
|
||||
|
||||
If you’re tuning limits:
|
||||
|
||||
- The context window comes from the model catalog (and can be overridden via config).
|
||||
- `contextTokens` in the store is a runtime estimate/reporting value; don’t treat it as a strict guarantee.
|
||||
|
||||
@@ -156,6 +162,7 @@ For more, see [/token-use](/token-use).
|
||||
Compaction summarizes older conversation into a persisted `compaction` entry in the transcript and keeps recent messages intact.
|
||||
|
||||
After compaction, future turns see:
|
||||
|
||||
- The compaction summary
|
||||
- Messages after `firstKeptEntryId`
|
||||
|
||||
@@ -167,12 +174,13 @@ Compaction is **persistent** (unlike session pruning). See [/concepts/session-pr
|
||||
|
||||
In the embedded Pi agent, auto-compaction triggers in two cases:
|
||||
|
||||
1) **Overflow recovery**: the model returns a context overflow error → compact → retry.
|
||||
2) **Threshold maintenance**: after a successful turn, when:
|
||||
1. **Overflow recovery**: the model returns a context overflow error → compact → retry.
|
||||
2. **Threshold maintenance**: after a successful turn, when:
|
||||
|
||||
`contextTokens > contextWindow - reserveTokens`
|
||||
|
||||
Where:
|
||||
|
||||
- `contextWindow` is the model’s context window
|
||||
- `reserveTokens` is headroom reserved for prompts + the next model output
|
||||
|
||||
@@ -189,8 +197,8 @@ Pi’s compaction settings live in Pi settings:
|
||||
compaction: {
|
||||
enabled: true,
|
||||
reserveTokens: 16384,
|
||||
keepRecentTokens: 20000
|
||||
}
|
||||
keepRecentTokens: 20000,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -224,6 +232,7 @@ You can observe compaction and session state via:
|
||||
OpenClaw supports “silent” turns for background tasks where the user should not see intermediate output.
|
||||
|
||||
Convention:
|
||||
|
||||
- The assistant starts its output with `NO_REPLY` to indicate “do not deliver a reply to the user”.
|
||||
- OpenClaw strips/suppresses this in the delivery layer.
|
||||
|
||||
@@ -239,18 +248,20 @@ erase critical context.
|
||||
|
||||
OpenClaw uses the **pre-threshold flush** approach:
|
||||
|
||||
1) Monitor session context usage.
|
||||
2) When it crosses a “soft threshold” (below Pi’s compaction threshold), run a silent
|
||||
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.
|
||||
3. Use `NO_REPLY` so the user sees nothing.
|
||||
|
||||
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)
|
||||
|
||||
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).
|
||||
|
||||
Reference in New Issue
Block a user