Compaction UI Enhancements
by @maverick-software
Background memory compaction with auto-trigger, chat summary paragraph, configurable threshold, model selector, settings tab, and result storage for OpenClaw...
clawhub install compaction-ui-enhancementsπ About This Skill
name: compaction-ui version: 2.3.0 description: "Background memory compaction with auto-trigger, chat summary paragraph, configurable threshold, model selector, settings tab, and result storage for OpenClaw Control UI."
Compaction UI v2.1.0
Memory compaction system for the OpenClaw Control UI β background execution with toast notifications, auto-trigger at configurable token thresholds, conversation summary paragraphs in compacted output, dedicated settings tab with model selector, and result history.
Status: β Active
| Component | Status | |-----------|--------| | Context Gauge Button | β Working | | Background Compaction (toast) | β Working | | Auto-Compaction Trigger | β Working | | Conversation Summary Paragraph | β Working | | Settings Tab (plugin-registered) | β Working | | Model Selector | β Working | | Last Result Storage + Viewer | β Working | | Settings Persistence & Reload | β Working | | Auth Hierarchy (OAuth > API > Fallback) | β Working | | Chat History Filters | β Working | | Full Background Isolation (no chat interference) | β Working |
Features
1. Context Gauge Button (app-render.helpers.ts)
A circular SVG progress ring in the chat toolbar that doubles as the manual compact trigger.
renderChatControls()sessionsResult.sessions[].totalTokens and contextTokens from session rows2. Background Compaction (Toast)
On click (or auto-trigger), compaction runs in the background using the standard bottom-right toast system β no blocking modal. The UI remains fully interactive.
backgroundJobToasts system consistent with all other background processes (cron, knowledge extraction, etc.)3. Auto-Compaction
After every chat response (final event), the UI checks token usage against the configured threshold. If exceeded:
4. Conversation Summary Paragraph
Every compaction output now begins with a ## Conversation Summary section before the structured ## Goal section. This is a 3-6 sentence natural language paragraph that:
Implementation: Custom instructions are injected into the upstream compaction LLM call via compact.ts. The instruction is prepended to any user-provided custom instructions (from /compact [instructions]), so both coexist.
Example output:
## Conversation Summary
The conversation began with the user requesting improvements to the compaction
system, specifically moving from a blocking modal to background toasts. Discussion
then shifted to adding a settings tab with auto-compaction controls. After
implementing and testing those features, the user noticed settings weren't
persisting across tab navigations, which led to a fix for the module-level
state cache. Finally, the user requested adding a narrative summary paragraph
to the compaction output for better context.Goal
...
5. Settings Tab (Plugin-Registered)
A dedicated Compaction tab under the Agent navigation group, registered via the Plugin UI architecture.
Registration: plugins-ui.ts β BUILTIN_UI_VIEWS with id: "compaction", group: "agent", position: 7, icon: "archive"
Cards:
#### Auto-Compaction Card
#### Model Card
#### Result Storage Card
#### Last Compaction Card
State Management:
resetCompactionSettingsState() exported for tests and tab switches6. Auth Hierarchy
Compaction uses resolveApiKeyForProvider via getApiKeyForModel β the same auth chain as chat:
OAuth β API Key β Fallback
No separate configuration needed. If OAuth (Claude Max) is configured as the primary auth profile, compaction uses it automatically. Custom model selection uses this same auth chain independently.
7. Result Storage
When enabled, the most recent compaction result is persisted to {agentDir}/compaction-config.json:
{
"settings": {
"autoEnabled": true,
"autoThresholdPercent": 60,
"storeLastResult": true,
"compactionModel": "anthropic/claude-sonnet-4-6"
},
"lastResult": {
"timestamp": 1709283600000,
"trigger": "manual",
"tokensBefore": 50614,
"tokensAfter": 4766,
"tokensSaved": 45848,
"percentReduction": 91,
"sessionKey": "agent:main:main",
"summary": "## Conversation Summary\nThe conversation focused on...\n\n## Goal\n..."
}
}
When storage is disabled, metadata (timestamps, token counts) is still saved but the summary text is omitted.
8. Chat History Filters
__openclaw.kind === "compaction" messagesArchitecture
Backend RPCs
| Method | Description |
|--------|-------------|
| sessions.compact | Execute compaction (records result after completion) |
| compaction.getSettings | Read settings from config file |
| compaction.saveSettings | Update settings (threshold auto-clamped 10-95%) |
| compaction.getLastResult | Get stored last compaction result |
| compaction.clearLastResult | Clear stored result |
Files Modified
| File | Purpose |
|------|---------|
| src/gateway/server-methods/compaction.ts | Settings RPCs, config I/O, result recording |
| src/gateway/server-methods/sessions.ts | sessions.compact RPC (records result after compaction) |
| src/gateway/server-methods/plugins-ui.ts | Plugin view registration |
| src/gateway/server-methods.ts | Handler wiring |
| src/gateway/server-methods-list.ts | Method registration |
| src/gateway/method-scopes.ts | Scope registration |
| src/agents/pi-embedded-runner/compact.ts | Chat summary instruction injection |
| ui/src/ui/app-render.helpers.ts | Context gauge + background toast trigger |
| ui/src/ui/app-gateway.ts | Auto-compaction check after final event |
| ui/src/ui/views/compaction-settings.ts | Settings tab view |
| ui/src/ui/app-render.ts | View wiring + import |
| ui/src/ui/views/chat.ts | Chat history filters |
Config File
{agentDir}/compaction-config.json β per-agent, created on first settings save.
Plugin Registration
The compaction tab is registered as a builtin plugin view in plugins-ui.ts:
{
id: "compaction",
label: "Compaction",
subtitle: "Memory Management",
icon: "archive",
group: "agent",
position: 7,
pluginId: "compaction-ui",
}
Known Gotchas
_state.loaded flag was preventing reloads. Now reloads every 2 seconds when re-entering the tab."provider/model" format (e.g. "anthropic/claude-sonnet-4-6"). Invalid formats are silently ignored and fall back to session default.readSessionMessages, the skip set must ONLY propagate through entries with a message field. Non-message protocol entries (type:"custom") bridge between logical turns β if their IDs enter the skip set, the entire remaining conversation gets hidden. The fix: only check parsed?.message entries against the skip set, and only add their IDs to it.app-render.helpers.ts must NEVER render a full-screen overlay modal. Compaction is a background process; all status is communicated via the bottom-right toast system. Remove any position:fixed; inset:0 overlay conditioned on compactState.phase. The button may show a spinner icon while running, but must not block the UI.Changelog
v2.1.0
## Conversation Summary narrative paragraph before structured sectionsreferences/ with current sourcev2.0.0
sessions.compact records before/after token counts and optional summarycompaction.getSettings, compaction.saveSettings, compaction.getLastResult, compaction.clearLastResultv1.0.0
sessions.compact RPC with LLM summarization, chat history NO_REPLY/HEARTBEAT_OK filtering, compaction divider lines