Compaction UI
Adds a manual compaction button with context utilization gauge to the OpenClaw Control UI chat toolbar.
Components
1. Context Gauge Button (app-render.helpers.ts)
A circular SVG progress ring that doubles as the compact trigger.
- Placement: After session selector dropdown in
renderChatControls() - Data source:
sessionsResult.sessions[].totalTokensandcontextTokensfrom session rows - Colors: Green (<60%), Yellow (60-85%), Red (≥85%)
- Disabled: When utilization <20% or during active compaction
- Tooltip: Shows "Context: XK / YK tokens (Z%)"
On click, calls sessions.compact RPC and shows a modal overlay with animated progress phases:
- "Preparing compaction…"
- "Reading session history…"
- "Summarizing conversation…"
- "Compacting context window…"
- "✅ Compaction Complete — XK → YK tokens" (holds 2s, then auto-closes and refreshes chat)
See references/context-gauge-ui.diff.md for the full renderContextGauge() implementation.
2. LLM-Based sessions.compact RPC (sessions.ts)
Replaces the original line-trimming RPC with real LLM summarization via compactEmbeddedPiSession().
Flow:
- Resolve session entry, agent ID, model/provider from config
- Abort any active agent run on the session
- Call
compactEmbeddedPiSession()withtrigger: "manual" - Update session store with new token counts and increment
compactionCount - Return
{ ok, compacted, tokensBefore, tokensAfter, reason }
See references/sessions-compact-rpc.diff.md for the full diff.
3. Chat History Filters (chat.ts)
- NO_REPLY/HEARTBEAT_OK filtering: Skip assistant messages where full text content is exactly
NO_REPLYorHEARTBEAT_OKinbuildChatItems() - Compaction divider: Detects
raw.__openclaw.kind === "compaction"on message objects and renders a labeled divider line
See references/chat-filters.diff.md for the diff.
4. Compaction Marker in JSONL
The pi-agent compaction engine writes type: "compaction" entries to session JSONL files. The readSessionMessages() function in session-utils.fs.ts converts these to synthetic messages with __openclaw: { kind: "compaction" } for the UI to detect.
Installation
Apply the three patches in references/ against the OpenClaw source tree:
cd /path/to/openclaw
git apply skills/compaction-ui/references/sessions-compact-rpc.diff.md
git apply skills/compaction-ui/references/context-gauge-ui.diff.md
git apply skills/compaction-ui/references/chat-filters.diff.md
npm run build
Then restart the gateway.
Key Architecture Notes
- The gauge reads token data from
GatewaySessionRow.totalTokensandcontextTokensfields, populated by the session store after each agent turn compactEmbeddedPiSessionrequires live LLM access (resolves model/provider/apiKey from config) — compaction takes 10-30s- The modal uses
position:fixedoverlay withbackdrop-filter:blur(3px)and a CSS keyframe animation for the progress bar - After compaction, chat refresh is deferred until after the 2s "complete" display to prevent the modal from being wiped by re-render