pi-mega-compact 0.21.6 → 0.21.8

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 CHANGED
@@ -1,9 +1,7 @@
1
1
  # pi-mega-compact
2
2
 
3
3
  > **⚠️ LTS — patches only (2026-08-13).** This extension is maintained for bug fixes only. New feature development has moved to **[radcode](https://github.com/TheArchitectit/radcode)**, a Rust pi.dev replacement that has ported mega-compact's compaction/recall/dedup/RAPTOR stack. See [`docs/LTS.md`](docs/LTS.md) and [`docs/SUCCESSION.md`](docs/SUCCESSION.md).
4
- >
5
- Pending public release
6
- >
4
+
7
5
  A local-first context compressor for the [pi coding agent](https://github.com/earendil-works/pi). Keeps long sessions running without overflowing the context window. Local by default — no cloud, no API calls, no telemetry. Bring your own localhost embedder (Ollama, ONNX, TEI) for better semantic matches, or opt in to a remote endpoint if you need to.
8
6
 
9
7
  ## Features
@@ -132,6 +132,7 @@ export const SETTINGS = [
132
132
  settings: [
133
133
  num("MEGACOMPACT_THRESHOLD_PCT", "Compaction Threshold", "Fraction of the actual model context window at which compaction fires — 0.80 fires at 80% used (leaves 20% free). Applies to any model size; a per-model Model Thresholds row overrides it", 0.8, 0.1, 0.95),
134
134
  num("MEGACOMPACT_THRASH_REARM_PCT", "Thrash Re-arm %", "After an ineffective compaction (live window did not shrink), refuse to re-fire until the live window grows by this fraction of the effective threshold. Default 0.10 (10%)", 0.1, 0.01, 0.5),
135
+ boolDirect("MEGACOMPACT_OUTPUT_ERROR_COMPACT", "Output-Error Compact", "When a model response is truncated mid-output (stopReason: 'length'), trip a one-shot forced compaction to free input headroom. Closes the small-context deadlock where the model truncates below the input threshold.", true),
135
136
  ],
136
137
  },
137
138
  {
@@ -185,6 +186,8 @@ export const EXCLUDED_SETTINGS = [
185
186
  "MEGACOMPACT_RAPTOR_LEVEL_WEIGHTS",
186
187
  // Internal calibration, not user-facing.
187
188
  "MEGACOMPACT_FTS5_MAX_BM25",
189
+ // Boot-fallback context window — display-seed only, never a firing gate.
190
+ "MEGACOMPACT_DEFAULT_CONTEXT_WINDOW",
188
191
  // COS-FP-A: per-content-type L2 override landing slots. Null/unset by
189
192
  // default and NOT wired into the live L2 decision this sprint — the
190
193
  // top-level MEGACOMPACT_L2_THRESHOLD is the single runtime firing point. A
@@ -87,7 +87,21 @@ export function registerContextHandler(pi, runtime, config) {
87
87
  /* non-fatal */
88
88
  }
89
89
  runtime.lastCtxPercent = pct ?? null;
90
- runtime.lastCtxWindow = usage?.contextWindow ?? 0;
90
+ // Resolve the model window used by the token gate + live-trim tail-cap.
91
+ // Prefer the provider-reported usage window (authoritative when present);
92
+ // fall back to the captured model snapshot's contextWindow (populated from
93
+ // models.json / pi's model registry) when the provider does not report it
94
+ // via getContextUsage(). plexus (OpenAI-compatible) omits contextWindow in
95
+ // usage, so without this fallback lastCtxWindow is 0 for those providers —
96
+ // which silently disables the live-trim tail-cap (guarded on ctxWindow>0)
97
+ // and the token-gate window math, so mega-compact never reserves output
98
+ // headroom and a 32k model's own output overflows the window each turn.
99
+ // Mirrors the gate's existing pct fallback (gateCheck.ts S27).
100
+ const reportedWindow = usage?.contextWindow ?? 0;
101
+ runtime.lastCtxWindow =
102
+ reportedWindow > 0
103
+ ? reportedWindow
104
+ : (runtime.currentModel?.contextWindow ?? 0);
91
105
  runtime.snapshot(ctx);
92
106
  if (!config.auto) {
93
107
  const tailed = tailResult();
@@ -99,23 +113,6 @@ export function registerContextHandler(pi, runtime, config) {
99
113
  // S27 DB-mirror + VC1B ledger append. Runs BEFORE the fast-gate so every
100
114
  // message is captured, even if we don't compact this turn. Non-fatal.
101
115
  appendMirrorAndLedger(runtime, config, messages);
102
- // Phase H.1: output-error catch noop guard. When forceCompactNextGate is
103
- // armed (Phase H: model truncated its output → lengthStop.ts set the flag
104
- // at turn_end), check piCompactWouldNoop BEFORE evaluateGate consumes the
105
- // flag. If pi would noop (session too small to summarize — the transcript
106
- // is under pi's keepRecentTokens floor), clear the flag + return the tail
107
- // result silently instead of forcing a proceed that will throw "Nothing
108
- // to compact (session too small)" to the user. The session is genuinely
109
- // too small to compact — skipping is correct (the model retries on the
110
- // next turn regardless). Gated by config.outputErrorCompact (default ON;
111
- // OFF = byte-identical pre-H.1).
112
- if (config.outputErrorCompact &&
113
- runtime.rt.forceCompactNextGate &&
114
- piCompactWouldNoop(ctx)) {
115
- runtime.rt.forceCompactNextGate = false;
116
- runtime.diagCtxOutputErrorTrip++;
117
- return tailResult() ?? undefined;
118
- }
119
116
  // S29 FAST GATE: drive the auto-trigger off the context percent (see
120
117
  // gateCheck.ts). Returns a tailed view when the gate does not pass.
121
118
  const gate = evaluateGate(runtime, config, { pct, currentTokens, tailResult });
@@ -294,6 +294,12 @@ export const SETTINGS: ReadonlyArray<SettingGroup> = [
294
294
  0.01,
295
295
  0.5,
296
296
  ),
297
+ boolDirect(
298
+ "MEGACOMPACT_OUTPUT_ERROR_COMPACT",
299
+ "Output-Error Compact",
300
+ "When a model response is truncated mid-output (stopReason: 'length'), trip a one-shot forced compaction to free input headroom. Closes the small-context deadlock where the model truncates below the input threshold.",
301
+ true,
302
+ ),
297
303
  ],
298
304
  },
299
305
  {
@@ -376,6 +382,8 @@ export const EXCLUDED_SETTINGS: readonly string[] = [
376
382
  "MEGACOMPACT_RAPTOR_LEVEL_WEIGHTS",
377
383
  // Internal calibration, not user-facing.
378
384
  "MEGACOMPACT_FTS5_MAX_BM25",
385
+ // Boot-fallback context window — display-seed only, never a firing gate.
386
+ "MEGACOMPACT_DEFAULT_CONTEXT_WINDOW",
379
387
  // COS-FP-A: per-content-type L2 override landing slots. Null/unset by
380
388
  // default and NOT wired into the live L2 decision this sprint — the
381
389
  // top-level MEGACOMPACT_L2_THRESHOLD is the single runtime firing point. A
@@ -116,7 +116,21 @@ export function registerContextHandler(
116
116
  /* non-fatal */
117
117
  }
118
118
  runtime.lastCtxPercent = pct ?? null;
119
- runtime.lastCtxWindow = usage?.contextWindow ?? 0;
119
+ // Resolve the model window used by the token gate + live-trim tail-cap.
120
+ // Prefer the provider-reported usage window (authoritative when present);
121
+ // fall back to the captured model snapshot's contextWindow (populated from
122
+ // models.json / pi's model registry) when the provider does not report it
123
+ // via getContextUsage(). plexus (OpenAI-compatible) omits contextWindow in
124
+ // usage, so without this fallback lastCtxWindow is 0 for those providers —
125
+ // which silently disables the live-trim tail-cap (guarded on ctxWindow>0)
126
+ // and the token-gate window math, so mega-compact never reserves output
127
+ // headroom and a 32k model's own output overflows the window each turn.
128
+ // Mirrors the gate's existing pct fallback (gateCheck.ts S27).
129
+ const reportedWindow = usage?.contextWindow ?? 0;
130
+ runtime.lastCtxWindow =
131
+ reportedWindow > 0
132
+ ? reportedWindow
133
+ : (runtime.currentModel?.contextWindow ?? 0);
120
134
  runtime.snapshot(ctx);
121
135
  if (!config.auto) {
122
136
  const tailed = tailResult();
@@ -130,26 +144,6 @@ export function registerContextHandler(
130
144
  // message is captured, even if we don't compact this turn. Non-fatal.
131
145
  appendMirrorAndLedger(runtime, config, messages);
132
146
 
133
- // Phase H.1: output-error catch noop guard. When forceCompactNextGate is
134
- // armed (Phase H: model truncated its output → lengthStop.ts set the flag
135
- // at turn_end), check piCompactWouldNoop BEFORE evaluateGate consumes the
136
- // flag. If pi would noop (session too small to summarize — the transcript
137
- // is under pi's keepRecentTokens floor), clear the flag + return the tail
138
- // result silently instead of forcing a proceed that will throw "Nothing
139
- // to compact (session too small)" to the user. The session is genuinely
140
- // too small to compact — skipping is correct (the model retries on the
141
- // next turn regardless). Gated by config.outputErrorCompact (default ON;
142
- // OFF = byte-identical pre-H.1).
143
- if (
144
- config.outputErrorCompact &&
145
- runtime.rt.forceCompactNextGate &&
146
- piCompactWouldNoop(ctx)
147
- ) {
148
- runtime.rt.forceCompactNextGate = false;
149
- runtime.diagCtxOutputErrorTrip++;
150
- return tailResult() ?? undefined;
151
- }
152
-
153
147
  // S29 FAST GATE: drive the auto-trigger off the context percent (see
154
148
  // gateCheck.ts). Returns a tailed view when the gate does not pass.
155
149
  const gate = evaluateGate(runtime, config, { pct, currentTokens, tailResult });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-mega-compact",
3
- "version": "0.21.6",
3
+ "version": "0.21.8",
4
4
  "description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
5
5
  "type": "module",
6
6
  "license": "BSD-3-Clause",