Better Chat Compaction + WebUI
Background memory compaction with auto-trigger, chat summary paragraph, configurable threshold, model selector, settings tab, and result storage for OpenClaw...
技能说明
name: compaction-ui version: 2.1.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 |
| Compaction Divider Lines | ✅ 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.
- 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%)"
2. 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.
- Running toast: Shows "Memory Compaction" with spinner
- Complete toast: Shows "Compacted: XK → YK" with checkmark (auto-dismisses after 5s)
- Error toast: Shows failure message (auto-dismisses after 5s)
- Uses
backgroundJobToastssystem 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:
- Background compaction triggers automatically
- Toast shows "Auto-Compacting (X%)" with the current utilization
- 5-minute debounce prevents repeated triggers
- Chat refreshes automatically after successful compaction
- Silent toast removal if nothing was compacted
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:
- Describes the overall topic(s) of the conversation
- Explains the flow of discussion and key transitions
- Summarizes how the conversation progressed
- Written in past tense as a narrative overview
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
- Toggle: Enable/disable automatic compaction
- Threshold slider: 10% to 95% (default: 60%)
- Color-coded: Green (<60%), Yellow (60-85%), Red (≥85%)
Model Card
- Dropdown: Select a specific model for compaction or use session default
- Grouped by provider with context window sizes shown
- Warning callout when custom model selected (API key reminder)
- Fallback: If custom model fails, automatically falls back to session default
Result Storage Card
- Toggle: Opt-in to save the compacted summary text for review
Last Compaction Card
- Before/After: Large styled token counts in a 2-column grid
- Stats: Tokens saved, percent reduction, trigger type, timestamp, session key
- View Results: Expandable summary viewer (when storage is enabled)
- Clear: Reset stored result
- Hint: Shows "Enable Store Results" message when storage is off
State Management:
- Module-level state persists across re-renders within a session
- Settings reload from backend every time the tab is visited (2-second staleness threshold)
resetCompactionSettingsState()exported for tests and tab switches
6. 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
- NO_REPLY/HEARTBEAT_OK filtering: Skips assistant messages with these exact texts
- Compaction divider: Renders labeled divider line for
__openclaw.kind === "compaction"messages
Architecture
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
- Settings not persisting across tab visits: Fixed in v2.1.0. The module-level
_state.loadedflag was preventing reloads. Now reloads every 2 seconds when re-entering the tab. - Model selector requires API keys: If you select a custom model, make sure the provider's API key is configured. The UI shows a warning callout.
- Compaction model format: Must be
"provider/model"format (e.g."anthropic/claude-sonnet-4-6"). Invalid formats are silently ignored and fall back to session default.
Changelog
v2.1.0
- Conversation summary paragraph: Compaction output now starts with a
## Conversation Summarynarrative paragraph before structured sections - Model selector: Choose a specific model for compaction or use session default, with provider-grouped dropdown
- Settings reload fix: Tab now reloads settings from backend every 2s instead of caching forever
- Reference files updated: Synced
references/with current source
v2.0.0
- Background compaction: Replaced blocking full-screen modal with background job toast
- Auto-compaction: Triggers after chat response when token usage exceeds threshold (configurable, default 60%, 5-minute debounce)
- Settings tab: Plugin-registered Compaction tab under Agent nav group
- Result recording:
sessions.compactrecords before/after token counts and optional summary - Auth hierarchy: Same OAuth → API → Fallback chain as chat
- Settings RPCs:
compaction.getSettings,compaction.saveSettings,compaction.getLastResult,compaction.clearLastResult
v1.0.0
- Initial release: Context gauge button, blocking modal with animated phases,
sessions.compactRPC with LLM summarization, chat history NO_REPLY/HEARTBEAT_OK filtering, compaction divider lines
如何使用「Better Chat Compaction + WebUI」?
- 打开小龙虾AI(Web 或 iOS App)
- 点击上方「立即使用」按钮,或在对话框中输入任务描述
- 小龙虾AI 会自动匹配并调用「Better Chat Compaction + WebUI」技能完成任务
- 结果即时呈现,支持继续对话优化