[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6ECW35TC8YPWFY5XKXNERWT":3,"skill-same:01M6ECW35TC8YPWFY5XKXNERWT":69},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":26,"linkOnly":27,"markdownContent":28,"markdownBody":28,"frontMatter":29,"refName":30,"commitSha":31,"skillDirectory":32,"forksCount":33,"repositoryHtmlUrl":34,"repositoryHomepageUrl":35,"ownerHtmlUrl":36,"ownerBlogUrl":6,"ownerDescription":37,"updatedAt":38,"install":39,"resources":52},"01M6ECW35TC8YPWFY5XKXNERWT","compaction-ui-enhancements",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FLeoYeAI\u002Fopenclaw-master-skills\u002Fcompaction-ui-enhancements\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[23,24,25],"ui","compaction","compaction ui enhancements","2026-11-10 10:12:30",false,"# Compaction UI v2.1.0\n\nMemory 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.\n\n## Status: ✅ Active\n\n| Component | Status |\n|-----------|--------|\n| Context Gauge Button | ✅ Working |\n| Background Compaction (toast) | ✅ Working |\n| Auto-Compaction Trigger | ✅ Working |\n| Conversation Summary Paragraph | ✅ Working |\n| Settings Tab (plugin-registered) | ✅ Working |\n| Model Selector | ✅ Working |\n| Last Result Storage + Viewer | ✅ Working |\n| Settings Persistence & Reload | ✅ Working |\n| Auth Hierarchy (OAuth > API > Fallback) | ✅ Working |\n| Chat History Filters | ✅ Working |\n| Full Background Isolation (no chat interference) | ✅ Working |\n\n## Features\n\n### 1. Context Gauge Button (`app-render.helpers.ts`)\n\nA circular SVG progress ring in the chat toolbar that doubles as the manual compact trigger.\n\n- **Placement:** After session selector dropdown in `renderChatControls()`\n- **Data source:** `sessionsResult.sessions[].totalTokens` and `contextTokens` from session rows\n- **Colors:** Green (\u003C60%), Yellow (60-85%), Red (≥85%)\n- **Disabled:** When utilization \u003C20% or during active compaction\n- **Tooltip:** Shows \"Context: XK \u002F YK tokens (Z%)\"\n\n### 2. Background Compaction (Toast)\n\nOn click (or auto-trigger), compaction runs in the background using the standard bottom-right toast system — **no blocking modal**. The UI remains fully interactive.\n\n- **Running toast:** Shows \"Memory Compaction\" with spinner\n- **Complete toast:** Shows \"Compacted: XK → YK\" with checkmark (auto-dismisses after 5s)\n- **Error toast:** Shows failure message (auto-dismisses after 5s)\n- Uses `backgroundJobToasts` system consistent with all other background processes (cron, knowledge extraction, etc.)\n\n### 3. Auto-Compaction\n\nAfter every chat response (`final` event), the UI checks token usage against the configured threshold. If exceeded:\n\n- Background compaction triggers automatically\n- Toast shows \"Auto-Compacting (X%)\" with the current utilization\n- 5-minute debounce prevents repeated triggers\n- Chat refreshes automatically after successful compaction\n- Silent toast removal if nothing was compacted\n\n### 4. Conversation Summary Paragraph\n\nEvery compaction output now begins with a `## Conversation Summary` section **before** the structured `## Goal` section. This is a 3-6 sentence natural language paragraph that:\n\n- Describes the overall topic(s) of the conversation\n- Explains the flow of discussion and key transitions\n- Summarizes how the conversation progressed\n- Written in past tense as a narrative overview\n\n**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 `\u002Fcompact [instructions]`), so both coexist.\n\n**Example output:**\n```\n## Conversation Summary\nThe conversation began with the user requesting improvements to the compaction\nsystem, specifically moving from a blocking modal to background toasts. Discussion\nthen shifted to adding a settings tab with auto-compaction controls. After\nimplementing and testing those features, the user noticed settings weren't\npersisting across tab navigations, which led to a fix for the module-level\nstate cache. Finally, the user requested adding a narrative summary paragraph\nto the compaction output for better context.\n\n## Goal\n...\n```\n\n### 5. Settings Tab (Plugin-Registered)\n\nA dedicated Compaction tab under the **Agent** navigation group, registered via the Plugin UI architecture.\n\n**Registration:** `plugins-ui.ts` → `BUILTIN_UI_VIEWS` with `id: \"compaction\"`, `group: \"agent\"`, `position: 7`, `icon: \"archive\"`\n\n**Cards:**\n\n#### Auto-Compaction Card\n- **Toggle:** Enable\u002Fdisable automatic compaction\n- **Threshold slider:** 10% to 95% (default: 60%)\n- **Color-coded:** Green (\u003C60%), Yellow (60-85%), Red (≥85%)\n\n#### Model Card\n- **Dropdown:** Select a specific model for compaction or use session default\n- **Grouped by provider** with context window sizes shown\n- **Warning callout** when custom model selected (API key reminder)\n- **Fallback:** If custom model fails, automatically falls back to session default\n\n#### Result Storage Card\n- **Toggle:** Opt-in to save the compacted summary text for review\n\n#### Last Compaction Card\n- **Before\u002FAfter:** Large styled token counts in a 2-column grid\n- **Stats:** Tokens saved, percent reduction, trigger type, timestamp, session key\n- **View Results:** Expandable summary viewer (when storage is enabled)\n- **Clear:** Reset stored result\n- **Hint:** Shows \"Enable Store Results\" message when storage is off\n\n**State Management:**\n- Module-level state persists across re-renders within a session\n- Settings reload from backend every time the tab is visited (2-second staleness threshold)\n- `resetCompactionSettingsState()` exported for tests and tab switches\n\n### 6. Auth Hierarchy\n\nCompaction uses `resolveApiKeyForProvider` via `getApiKeyForModel` — the same auth chain as chat:\n\n**OAuth → API Key → Fallback**\n\nNo 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.\n\n### 7. Result Storage\n\nWhen enabled, the most recent compaction result is persisted to `{agentDir}\u002Fcompaction-config.json`:\n\n```json\n{\n  \"settings\": {\n    \"autoEnabled\": true,\n    \"autoThresholdPercent\": 60,\n    \"storeLastResult\": true,\n    \"compactionModel\": \"anthropic\u002Fclaude-sonnet-4-6\"\n  },\n  \"lastResult\": {\n    \"timestamp\": 1709283600000,\n    \"trigger\": \"manual\",\n    \"tokensBefore\": 50614,\n    \"tokensAfter\": 4766,\n    \"tokensSaved\": 45848,\n    \"percentReduction\": 91,\n    \"sessionKey\": \"agent:main:main\",\n    \"summary\": \"## Conversation Summary\\nThe conversation focused on...\\n\\n## Goal\\n...\"\n  }\n}\n```\n\nWhen storage is disabled, metadata (timestamps, token counts) is still saved but the summary text is omitted.\n\n### 8. Chat History Filters\n\n- **NO_REPLY\u002FHEARTBEAT_OK filtering:** Skips assistant messages with these exact texts\n- **Compaction divider:** Renders labeled divider line for `__openclaw.kind === \"compaction\"` messages\n\n## Architecture\n\n### Backend RPCs\n\n| Method | Description |\n|--------|-------------|\n| `sessions.compact` | Execute compaction (records result after completion) |\n| `compaction.getSettings` | Read settings from config file |\n| `compaction.saveSettings` | Update settings (threshold auto-clamped 10-95%) |\n| `compaction.getLastResult` | Get stored last compaction result |\n| `compaction.clearLastResult` | Clear stored result |\n\n### Files Modified\n\n| File | Purpose |\n|------|---------|\n| `src\u002Fgateway\u002Fserver-methods\u002Fcompaction.ts` | Settings RPCs, config I\u002FO, result recording |\n| `src\u002Fgateway\u002Fserver-methods\u002Fsessions.ts` | `sessions.compact` RPC (records result after compaction) |\n| `src\u002Fgateway\u002Fserver-methods\u002Fplugins-ui.ts` | Plugin view registration |\n| `src\u002Fgateway\u002Fserver-methods.ts` | Handler wiring |\n| `src\u002Fgateway\u002Fserver-methods-list.ts` | Method registration |\n| `src\u002Fgateway\u002Fmethod-scopes.ts` | Scope registration |\n| `src\u002Fagents\u002Fpi-embedded-runner\u002Fcompact.ts` | Chat summary instruction injection |\n| `ui\u002Fsrc\u002Fui\u002Fapp-render.helpers.ts` | Context gauge + background toast trigger |\n| `ui\u002Fsrc\u002Fui\u002Fapp-gateway.ts` | Auto-compaction check after final event |\n| `ui\u002Fsrc\u002Fui\u002Fviews\u002Fcompaction-settings.ts` | Settings tab view |\n| `ui\u002Fsrc\u002Fui\u002Fapp-render.ts` | View wiring + import |\n| `ui\u002Fsrc\u002Fui\u002Fviews\u002Fchat.ts` | Chat history filters |\n\n### Config File\n\n`{agentDir}\u002Fcompaction-config.json` — per-agent, created on first settings save.\n\n### Plugin Registration\n\nThe compaction tab is registered as a builtin plugin view in `plugins-ui.ts`:\n\n```typescript\n{\n  id: \"compaction\",\n  label: \"Compaction\",\n  subtitle: \"Memory Management\",\n  icon: \"archive\",\n  group: \"agent\",\n  position: 7,\n  pluginId: \"compaction-ui\",\n}\n```\n\n## Known Gotchas\n\n- **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.\n- **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.\n- **Compaction model format:** Must be `\"provider\u002Fmodel\"` format (e.g. `\"anthropic\u002Fclaude-sonnet-4-6\"`). Invalid formats are silently ignored and fall back to session default.\n- **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.\n- **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.\n\n## Changelog\n\n### v2.1.0\n- **Conversation summary paragraph:** Compaction output now starts with a `## Conversation Summary` narrative paragraph before structured sections\n- **Model selector:** Choose a specific model for compaction or use session default, with provider-grouped dropdown\n- **Settings reload fix:** Tab now reloads settings from backend every 2s instead of caching forever\n- **Reference files updated:** Synced `references\u002F` with current source\n\n### v2.0.0\n- **Background compaction:** Replaced blocking full-screen modal with background job toast\n- **Auto-compaction:** Triggers after chat response when token usage exceeds threshold (configurable, default 60%, 5-minute debounce)\n- **Settings tab:** Plugin-registered Compaction tab under Agent nav group\n- **Result recording:** `sessions.compact` records before\u002Fafter token counts and optional summary\n- **Auth hierarchy:** Same OAuth → API → Fallback chain as chat\n- **Settings RPCs:** `compaction.getSettings`, `compaction.saveSettings`, `compaction.getLastResult`, `compaction.clearLastResult`\n\n### v1.0.0\n- Initial release: Context gauge button, blocking modal with animated phases, `sessions.compact` RPC with LLM summarization, chat history NO_REPLY\u002FHEARTBEAT_OK filtering, compaction divider lines\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002FLeoYeAI\u002Fopenclaw-master-skills\u002Fcompaction-ui-enhancements",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":40,"prompt":50,"zipAvailable":51},[41,44,47],{"tool":42,"command":43},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill compaction-ui-enhancements",{"tool":45,"command":46},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill compaction-ui-enhancements",{"tool":48,"command":49},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill compaction-ui-enhancements","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FLeoYeAI\u002Fopenclaw-master-skills\u002Fcompaction-ui-enhancements\u002FSKILL.md",true,[53,59,65],{"path":54,"resourceType":55,"resourceTypeDesc":56,"sizeBytes":57,"sourceHtmlUrl":58},"checklist.md","REFERENCE","参考文档",1792,"https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-performance-test\u002Fchecklist.md",{"path":60,"resourceType":61,"resourceTypeDesc":62,"sizeBytes":63,"sourceHtmlUrl":64},"customize.toml","OTHER","其他",1638,"https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-performance-test\u002Fcustomize.toml",{"path":66,"resourceType":55,"resourceTypeDesc":56,"sizeBytes":67,"sourceHtmlUrl":68},"performance-template.md",5859,"https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.kiro\u002Fskills\u002Fgds-performance-test\u002Fperformance-template.md",[70,84,94,103,109,116],{"skillNo":71,"name":72,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":80,"publishedAt":26},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[75],{"categoryNo":76,"categoryName":77,"taxonomyType":78,"taxonomyTypeDesc":79},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[81,82,83],"model","model hierarchy","model hierarchy skill",{"skillNo":85,"name":86,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":90,"publishedAt":26},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[89],{"categoryNo":76,"categoryName":77,"taxonomyType":78,"taxonomyTypeDesc":79},[91,92,93],"MCP","zoom","zoom mcp",{"skillNo":95,"name":96,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":97,"categories":98,"keywords":99,"publishedAt":26},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[100,101,102,92],"sdk","zoom apps sdk","apps",{"skillNo":104,"name":105,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":26},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[105],{"skillNo":110,"name":111,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":112,"categories":113,"keywords":115,"publishedAt":26},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[114],{"categoryNo":76,"categoryName":77,"taxonomyType":78,"taxonomyTypeDesc":79},[111],{"skillNo":117,"name":118,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":119,"categories":120,"keywords":121,"publishedAt":26},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[118]]