pi-mega-compact 0.6.9 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -8
- package/dist/extensions/dashboard-server.js +17 -6
- package/dist/extensions/mega-commands.js +12 -1
- package/dist/extensions/mega-compact.test.js +286 -51
- package/dist/extensions/mega-config.js +67 -5
- package/dist/extensions/mega-events.js +151 -27
- package/dist/extensions/mega-runtime.js +163 -32
- package/dist/extensions/openclaw-mega-compact.js +291 -0
- package/dist/src/dedup-engine.test.js +63 -38
- package/dist/src/minilm.js +92 -0
- package/dist/src/wordpiece.js +129 -0
- package/extensions/dashboard-server.ts +17 -6
- package/extensions/mega-commands.ts +12 -1
- package/extensions/mega-compact.test.ts +947 -516
- package/extensions/mega-config.ts +84 -6
- package/extensions/mega-dashboard.ts +11 -0
- package/extensions/mega-events.ts +558 -360
- package/extensions/mega-runtime.ts +168 -32
- package/package.json +1 -1
- package/src/dedup-engine.test.ts +103 -42
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ sessions into a **local SQLite store** and offers **deduped inline recall** —
|
|
|
6
6
|
running **locally inside the extension**, with **no remote MCP server** and
|
|
7
7
|
**zero network calls at runtime** (PREVENT-PI-004).
|
|
8
8
|
|
|
9
|
-
> **Current version:** `v0.6.
|
|
9
|
+
> **Current version:** `v0.6.9` — storage backend is **`node:sqlite`**
|
|
10
10
|
> (`DatabaseSync`, a Node ≥22.13 built-in), replacing the old `better-sqlite3`
|
|
11
11
|
> native addon and the per-session gzipped JSON checkpoint files. **Zero native
|
|
12
12
|
> build step, fully local, zero network at runtime.** Legacy
|
|
@@ -23,10 +23,12 @@ running **locally inside the extension**, with **no remote MCP server** and
|
|
|
23
23
|
pi's context window is finite. When a session gets long — especially a team run
|
|
24
24
|
with sub-agents — pi-mega-compact keeps it going without overflowing:
|
|
25
25
|
|
|
26
|
-
1. **Watches one signal.** A single live `pressure = currentTokens /
|
|
26
|
+
1. **Watches one signal.** A single live `pressure = currentTokens / effectiveThreshold`
|
|
27
27
|
drives everything — the tier label, how aggressively the live trim drops
|
|
28
|
-
context, and how often durable memory is reviewed.
|
|
29
|
-
|
|
28
|
+
context, and how often durable memory is reviewed. `effectiveThreshold` is
|
|
29
|
+
`tierPct × contextWindow` (a **% of the model's context window**), so the
|
|
30
|
+
trim fires below pi's native ~80% auto-compaction for any model size. As
|
|
31
|
+
context fills, the whole system reacts together; as it's relieved, it backs off.
|
|
30
32
|
2. **Compacts in two layers.** On every LLM call it returns a **live, compacted
|
|
31
33
|
view** (the model sees a summary + recent anchor, non-destructively). And it
|
|
32
34
|
persists a durable **checkpoint** — and, at each agent settle during a team
|
|
@@ -233,7 +235,7 @@ The commands (slash commands inside pi):
|
|
|
233
235
|
| `/mega-help` | Explain the toolbar widget terms (live tier, gate, dedup, tokens saved). |
|
|
234
236
|
| `/mega-compat-check` | Detect extension conflicts (duplicate commands / overlapping handlers) across installed pi extensions. |
|
|
235
237
|
|
|
236
|
-
The **tier** you see in the toolbar and dashboard is a *live pressure band* (`low` → `medium` → `high` → `ultra` → `mega`) that climbs automatically as your context window fills and falls back as it's relieved — it is driven by `currentTokens /
|
|
238
|
+
The **tier** you see in the toolbar and dashboard is a *live pressure band* (`low` → `medium` → `high` → `ultra` → `mega`) that climbs automatically as your context window fills and falls back as it's relieved — it is driven by `currentTokens / effectiveThreshold`, not a manual setting. The base compaction *threshold* is set by `MEGACOMPACT_TIER` at startup as a **% of the model context window** (`low` 50% · `medium` 60% · `high` 70% · `ultra` 70% · `mega` 75%; default `low`) — the fire point is `tierPct × contextWindow`, so it always lands below pi's native ~80% auto-compaction (any model size). The old static token amounts (50k/100k/200k/1M/10M) are now only the boot fallback used before the first context event reports a window. `/mega-tier` was removed in v0.6.0. Higher pressure also deepens the live trim and reviews durable memory more often — the whole system reacts as one.
|
|
237
239
|
| `/mega-dashboard` | Start the **localhost-only** live dashboard and open it in a browser (token gauge, store stats, live event stream, per-repo + cross-repo drift). |
|
|
238
240
|
| `/mega-dashboard-status` | Report dashboard server status. |
|
|
239
241
|
| `/mega-dashboard-stop` | Stop the dashboard server. |
|
|
@@ -266,9 +268,9 @@ before starting pi.
|
|
|
266
268
|
|
|
267
269
|
| Variable | Default | Meaning |
|
|
268
270
|
|---|---|---|
|
|
269
|
-
| `MEGACOMPACT_FAST_GATE_PCT` | `70` | Context-usage % that arms the auto-trigger. |
|
|
270
|
-
| `MEGACOMPACT_TIER` | `low` | Named trigger preset — sets the
|
|
271
|
-
| `MEGACOMPACT_THRESHOLD_TOKENS` | _(tier default)_ | Explicit token budget
|
|
271
|
+
| `MEGACOMPACT_FAST_GATE_PCT` | `70` | Context-usage % that arms the auto-trigger. Defaults to the tier's % of window (`tierPct*100`): low 50 · med 60 · high 70 · ultra 70 · mega 75. Override raises the arming floor. |
|
|
272
|
+
| `MEGACOMPACT_TIER` | `low` | Named trigger preset — sets the compaction threshold as a **% of the model context window**: `low`(50%) `medium`(60%) `high`(70%) `ultra`(70%) `mega`(75%). Fire point = `tierPct × contextWindow`, so it always fires below pi's native ~80% auto-compaction (any model size). The old static token amounts (50k/100k/200k/1M/10M) are now only the **boot fallback** used before the first context event reports a window. Default `low`. |
|
|
273
|
+
| `MEGACOMPACT_THRESHOLD_TOKENS` | _(tier default)_ | Explicit **absolute** token budget (the `custom` tier). Overrides `MEGACOMPACT_TIER` when set and is **never percent-scaled** — use this to pin an exact token fire point regardless of model window. |
|
|
272
274
|
| `MEGACOMPACT_ANCHOR_USER_MESSAGES` | `3` | Never drop the most recent N user messages (anchor floor). |
|
|
273
275
|
| `MEGACOMPACT_PRESERVE_RECENT` | `4` | Preserve the most recent N messages verbatim. |
|
|
274
276
|
| `MEGACOMPACT_AUTO` | `true` | Enable the auto-trigger. |
|
|
@@ -184,14 +184,15 @@ function readSnapshot(snapshotPath) {
|
|
|
184
184
|
tier: "unknown",
|
|
185
185
|
presetTier: "unknown",
|
|
186
186
|
pressure: 0,
|
|
187
|
-
config: { fastGatePct: 80, thresholdTokens: 100_000, anchorUserMessages: 1, preserveRecent: 2, auto: true, autoInlineK: 3 },
|
|
187
|
+
config: { fastGatePct: 80, thresholdTokens: 100_000, tierPct: null, effectiveThresholdPct: null, anchorUserMessages: 1, preserveRecent: 2, auto: true, autoInlineK: 3 },
|
|
188
188
|
session: { id: null, state: null, persistedThisSession: false, lastCheckpointId: null, lastCompactedFrom: 0 },
|
|
189
189
|
context: { tokens: null, percent: null, contextWindow: 0 },
|
|
190
|
-
trigger: { armed: false, ready: false, currentTokens: null, thresholdTokens: 100_000, fastGatePct: 80 },
|
|
190
|
+
trigger: { armed: false, ready: false, currentTokens: null, thresholdTokens: 100_000, fastGatePct: 80, tierPct: null, effectiveThresholdPct: null },
|
|
191
191
|
store: { checkpointCount: 0, totalTokenEstimate: 0, originalTokens: 0, tokensSaved: 0, injectedCount: 0, dedupHitRate: 0, storageDedupRate: 0, dedupCollapsed: 0 },
|
|
192
192
|
crew: { activeAgents: 0, currentTurn: 0 },
|
|
193
193
|
repo: { checkpointCount: 0, totalTokenEstimate: 0, originalTokens: 0, tokensSaved: 0, sessionCount: 0, dedupAttempts: 0, dedupCollapsed: 0, storageDedupRate: 0 },
|
|
194
194
|
integrity: { regionsRetained: 0, compressedOriginalBytes: 0, duplicatesCollapsed: 0, bytesPermanentlyDeleted: 0 },
|
|
195
|
+
compression: { session: { tokensIn: 0, tokensOut: 0, tokensFreed: 0, compressionPct: 0, dedupPct: 0 }, repo: { tokensIn: 0, tokensOut: 0, tokensFreed: 0, compressionPct: 0, dedupPct: 0 } },
|
|
195
196
|
model: undefined,
|
|
196
197
|
};
|
|
197
198
|
}
|
|
@@ -377,9 +378,9 @@ function dashboardHtml(tierName) {
|
|
|
377
378
|
<div class="conf-grid">
|
|
378
379
|
<span class="label" title="Live pressure band — climbs low→mega as context fills the window.">Tier (live)</span><span class="value" id="cf-tier">${tierName}</span>
|
|
379
380
|
<span class="label" title="The env-resolved base compaction preset (low/medium/high/ultra/mega) that set the token threshold.">Preset</span><span class="value" id="cf-preset">—</span>
|
|
380
|
-
<span class="label" title="Live pressure = currentTokens /
|
|
381
|
-
<span class="label">Threshold</span><span class="value" id="cf-threshold">—</span>
|
|
382
|
-
<span class="label">Fast Gate</span><span class="value" id="cf-gate">—</span>
|
|
381
|
+
<span class="label" title="Live pressure = currentTokens / threshold — % of the model context window (threshold fires at the tier's % of window).">Pressure</span><span class="value" id="cf-pressure">—</span>
|
|
382
|
+
<span class="label" title="Compaction threshold = tierPct × model context window — mega-compact trims BELOW pi's native ~80% auto-compact for any model size.">Threshold</span><span class="value" id="cf-threshold">—</span>
|
|
383
|
+
<span class="label" title="Fast-gate arming floor — the live trim arms once context passes this % of the window.">Fast Gate</span><span class="value" id="cf-gate">—</span>
|
|
383
384
|
<span class="label">Auto</span><span class="value" id="cf-auto">—</span>
|
|
384
385
|
<span class="label">Anchor</span><span class="value" id="cf-anchor">—</span>
|
|
385
386
|
</div>
|
|
@@ -600,7 +601,17 @@ function dashboardHtml(tierName) {
|
|
|
600
601
|
document.getElementById('cf-tier').textContent = d.tier + ' (live)';
|
|
601
602
|
document.getElementById('cf-preset').textContent = d.presetTier;
|
|
602
603
|
document.getElementById('cf-pressure').textContent = Math.round((d.pressure || 0) * 100) + '%';
|
|
603
|
-
|
|
604
|
+
// (b) Threshold: show the effective token threshold AND the % of the model
|
|
605
|
+
// context window it represents (percentage-based tiers). d.config.tierPct
|
|
606
|
+
// is present on the live snapshot written by the runtime (Phase-1/2a).
|
|
607
|
+
var cfgPct = d.config.tierPct;
|
|
608
|
+
var cw = d.context.contextWindow || 0;
|
|
609
|
+
var thresholdTxt = d.config.thresholdTokens.toLocaleString();
|
|
610
|
+
if (cfgPct != null && cw > 0) {
|
|
611
|
+
thresholdTxt += ' (' + Math.round(cfgPct * 100) + '% of ' + cw.toLocaleString() + ')';
|
|
612
|
+
}
|
|
613
|
+
document.getElementById('cf-threshold').textContent = thresholdTxt;
|
|
614
|
+
// (c) Fast Gate: arming floor — live trim arms once context passes this %.
|
|
604
615
|
document.getElementById('cf-gate').textContent = d.config.fastGatePct + '%';
|
|
605
616
|
document.getElementById('cf-auto').textContent = d.config.auto ? 'enabled' : 'disabled';
|
|
606
617
|
document.getElementById('cf-anchor').textContent = d.config.anchorUserMessages;
|
|
@@ -116,9 +116,20 @@ export function registerCommands(pi, runtime, config) {
|
|
|
116
116
|
}
|
|
117
117
|
catch { /* non-fatal */ }
|
|
118
118
|
const crossRepoStr = `${crossRepoInjections} cross-repo injections recorded · ${repoCount} repos indexed`;
|
|
119
|
+
// Effective compaction threshold = tierPct × model context window (kept
|
|
120
|
+
// BELOW pi's native ~80% auto-compact for any model size). Falls back to
|
|
121
|
+
// the boot token value when the window is unknown (custom tier / pre-
|
|
122
|
+
// model-select). Display matches the dashboard's percentage-based view.
|
|
123
|
+
const effThreshold = config.tierPct != null && ctxWindow > 0
|
|
124
|
+
? Math.round(config.tierPct * ctxWindow)
|
|
125
|
+
: config.thresholdTokens;
|
|
126
|
+
const winStr = ctxWindow > 0
|
|
127
|
+
? (ctxWindow >= 1_000_000 ? `${Math.round(ctxWindow / 1_000_000)}M` : `${Math.round(ctxWindow / 1_000)}k`)
|
|
128
|
+
: "?";
|
|
129
|
+
const tierPctStr = config.tierPct != null ? `${Math.round(config.tierPct * 100)}%` : "n/a";
|
|
119
130
|
ctx.ui.notify(`[mega-compact] pct=${pct} tokens=${tokens} tier=${runtime.pressureBand} (live) preset=${config.tier} ` +
|
|
120
131
|
`pressure=${Math.round(runtime.pressure * 100)}% fastGate=${config.fastGatePct}% ` +
|
|
121
|
-
`threshold=${config.
|
|
132
|
+
`threshold=${effThreshold.toLocaleString()} (${tierPctStr} of ${winStr} window) tierPct=${config.tierPct != null ? config.tierPct.toFixed(2) : "n/a"} auto=${config.auto} autoInline=${config.autoInline}\n` +
|
|
122
133
|
`[mega-compact] store: ${st.checkpointCount} chkpt · ` +
|
|
123
134
|
`${st.totalTokenEstimate} tok · last=${st.lastCheckpointId ?? "—"} · ` +
|
|
124
135
|
`injected=${st.injectedCount} · dedup=${(st.dedupHitRate * 100).toFixed(0)}%\n` +
|