mirror of
https://github.com/LeoYeAI/openclaw-master-skills.git
synced 2026-07-27 22:15:43 +00:00
233 lines
11 KiB
Markdown
233 lines
11 KiB
Markdown
---
|
|
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.
|
|
|
|
- **Placement:** After session selector dropdown in `renderChatControls()`
|
|
- **Data source:** `sessionsResult.sessions[].totalTokens` and `contextTokens` from 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 `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:
|
|
|
|
- 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`:
|
|
|
|
```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`:
|
|
|
|
```typescript
|
|
{
|
|
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.loaded` flag 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.
|
|
- **parentId skip-set propagation must be message-only:** When filtering memory flush messages from `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.
|
|
- **No blocking modal — ever:** The gauge button in `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 paragraph:** Compaction output now starts with a `## Conversation Summary` narrative 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.compact` records 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.compact` RPC with LLM summarization, chat history NO_REPLY/HEARTBEAT_OK filtering, compaction divider lines
|