@monotykamary/pi-vcc 0.3.16 → 0.3.17

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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@monotykamary/pi-vcc",
3
- "version": "0.3.15",
3
+ "version": "0.3.17",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@monotykamary/pi-vcc",
9
- "version": "0.3.15",
9
+ "version": "0.3.17",
10
10
  "devDependencies": {
11
11
  "knip": "6.14.1",
12
12
  "typescript": "6.0.3"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monotykamary/pi-vcc",
3
- "version": "0.3.16",
3
+ "version": "0.3.17",
4
4
  "description": "Algorithmic conversation compactor for pi - transcript-preserving structured summaries, no LLM calls",
5
5
  "main": "index.ts",
6
6
  "keywords": [
@@ -1,8 +1,7 @@
1
1
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
2
  import { writeFileSync } from "fs";
3
3
  import { compile, type CompileInput } from "../core/summarize";
4
- import { loadSettings, getModelThreshold, resolveReserveTokens, type PiVccSettings } from "../core/settings";
5
- import { isProactiveTriggerActive } from "./proactive-threshold";
4
+ import { loadSettings, type PiVccSettings } from "../core/settings";
6
5
  import { triggerInvisibleContinue } from "../core/invisible-continue";
7
6
  import type { PiVccCompactionDetails } from "../details";
8
7
 
@@ -279,34 +278,23 @@ export const registerBeforeCompactHook = (pi: ExtensionAPI) => {
279
278
  const { preparation, branchEntries, customInstructions } = event;
280
279
  const settings = loadSettings();
281
280
 
282
- // Per-model threshold check — applies regardless of which compactor handles
283
- // the actual summary. When pi-core's global threshold triggers compaction
284
- // but the current model's per-model threshold hasn't been crossed yet,
285
- // cancel to avoid compacting prematurely.
281
+ // Per-model threshold guard was previously applied here, cancelling
282
+ // compaction when context was below the per-model threshold. This
283
+ // blocked manual /compact from working because session_before_compact
284
+ // carries no "reason" field — manual and auto compactions are
285
+ // indistinguishable (both have customInstructions: undefined).
286
286
  //
287
- // This is NOT applied to explicit /pi-vcc commands — if the user asked
288
- // for a compaction, honor it.
287
+ // The per-model threshold is now served entirely by the proactive
288
+ // trigger (in proactive-threshold.ts), which fires on agent_end /
289
+ // model_select when the per-model threshold is crossed. This correctly
290
+ // compacts earlier than pi-core's global threshold without needing to
291
+ // cancel any compaction here.
292
+ //
293
+ // If pi-core's global threshold fires before the per-model threshold
294
+ // is crossed, the compaction proceeds — slightly premature from the
295
+ // per-model threshold's perspective, but this is preferable to blocking
296
+ // an explicit user action (/compact).
289
297
  const isPiVcc = customInstructions === PI_VCC_COMPACT_INSTRUCTION;
290
- if (!isPiVcc && !isProactiveTriggerActive()) {
291
- const threshold = getModelThreshold(settings, ctx.model);
292
- if (threshold) {
293
- const contextWindow = ctx.model?.contextWindow ?? 0;
294
- const reserve = resolveReserveTokens(threshold, contextWindow);
295
- if (reserve != null && contextWindow > 0) {
296
- const effectiveThreshold = contextWindow - reserve;
297
- if (preparation.tokensBefore <= effectiveThreshold) {
298
- try {
299
- const pct = Math.round((preparation.tokensBefore / contextWindow) * 100);
300
- ctx?.ui?.notify?.(
301
- `pi-vcc: Skipped compaction — ${pct}% of context window used (threshold: ${formatTokens(effectiveThreshold)} tok)`,
302
- "info",
303
- );
304
- } catch {}
305
- return { cancel: true };
306
- }
307
- }
308
- }
309
- }
310
298
 
311
299
  // Always handle explicit /pi-vcc marker.
312
300
  // Otherwise, only handle when user opted in via settings.
@@ -19,7 +19,7 @@ afterAll(() => {
19
19
  });
20
20
 
21
21
  function createMockPi(model?: { id: string; provider?: string; contextWindow?: number }) {
22
- let handler: ((event: any, ctx: any) => any) | undefined;
22
+ const handlers: Record<string, ((e: any, c: any) => any)[]> = {};
23
23
  const notifyCalls: Array<{ msg: string; level: string }> = [];
24
24
  const ctx = {
25
25
  hasUI: true,
@@ -30,15 +30,19 @@ function createMockPi(model?: { id: string; provider?: string; contextWindow?: n
30
30
  },
31
31
  },
32
32
  } as any;
33
- return {
34
- pi: {
35
- on: (eventName: string, h: (e: any, c: any) => any) => {
36
- if (eventName === "session_before_compact") handler = h;
37
- },
38
- } as any,
39
- invoke: (event: any) => handler!(event, ctx),
40
- notifyCalls,
33
+ const pi = {
34
+ on: (eventName: string, h: (e: any, c: any) => any) => {
35
+ if (!handlers[eventName]) handlers[eventName] = [];
36
+ handlers[eventName].push(h);
37
+ },
38
+ } as any;
39
+ const emit = (eventName: string, event: any = {}) => {
40
+ const hs = handlers[eventName] ?? [];
41
+ let result: any;
42
+ for (const h of hs) result = h(event, ctx);
43
+ return result;
41
44
  };
45
+ return { pi, ctx, emit, notifyCalls };
42
46
  }
43
47
 
44
48
  function setConfig(cfg: Record<string, unknown>) {
@@ -70,7 +74,12 @@ describe("session_before_compact: per-model threshold", () => {
70
74
  if (existsSync(CONFIG_PATH)) unlinkSync(CONFIG_PATH);
71
75
  });
72
76
 
73
- test("cancels when context is below per-model threshold (provider/modelId)", () => {
77
+ test("compaction proceeds when context is below per-model threshold", () => {
78
+ // The threshold guard was removed because session_before_compact carries no
79
+ // reason field — manual /compact and auto-compaction are indistinguishable.
80
+ // The proactive trigger handles compacting earlier than pi-core's global
81
+ // threshold; this hook no longer blocks compaction that arrives before the
82
+ // per-model threshold.
74
83
  setConfig({
75
84
  debug: false,
76
85
  overrideDefaultCompaction: true,
@@ -78,27 +87,27 @@ describe("session_before_compact: per-model threshold", () => {
78
87
  "neuralwatt/GLM-5.1": { reserveTokens: 32768 },
79
88
  },
80
89
  });
81
- const { pi, invoke, notifyCalls } = createMockPi({
90
+ const { pi, ctx, emit } = createMockPi({
82
91
  id: "GLM-5.1",
83
92
  provider: "neuralwatt",
84
93
  contextWindow: 200000,
85
94
  });
86
95
  registerBeforeCompactHook(pi);
87
96
 
88
- // 100k tokens < 200k - 32768 = 167232 → below threshold
97
+ // 100k tokens < 200k - 32768 = 167232 → below threshold, but proceeds
89
98
  const entries = [
90
99
  msg("m1", "user", "hello"),
91
100
  msg("m2", "assistant", "hi"),
92
101
  msg("m3", "user", "do work"),
93
102
  msg("m4", "assistant", "done"),
94
103
  ];
95
- const result = invoke(makeEvent(entries, undefined, 100000));
96
- expect(result).toEqual({ cancel: true });
97
- expect(notifyCalls.length).toBeGreaterThanOrEqual(1);
98
- expect(notifyCalls[0].msg).toContain("Skipped compaction");
104
+ const result = emit("session_before_compact", makeEvent(entries, undefined, 100000));
105
+ // No longer cancelled — threshold guard removed
106
+ expect(result.cancel).toBeUndefined();
107
+ expect(result.compaction).toBeDefined();
99
108
  });
100
109
 
101
- test("allows compaction when context exceeds per-model threshold", () => {
110
+ test("compaction proceeds when context exceeds per-model threshold", () => {
102
111
  setConfig({
103
112
  debug: false,
104
113
  overrideDefaultCompaction: true,
@@ -106,7 +115,7 @@ describe("session_before_compact: per-model threshold", () => {
106
115
  "neuralwatt/GLM-5.1": { reserveTokens: 32768 },
107
116
  },
108
117
  });
109
- const { pi, invoke } = createMockPi({
118
+ const { pi, ctx, emit } = createMockPi({
110
119
  id: "GLM-5.1",
111
120
  provider: "neuralwatt",
112
121
  contextWindow: 200000,
@@ -120,64 +129,38 @@ describe("session_before_compact: per-model threshold", () => {
120
129
  msg("m3", "user", "do work"),
121
130
  msg("m4", "assistant", "done"),
122
131
  ];
123
- const result = invoke(makeEvent(entries, undefined, 180000));
124
- // Not cancelled — pi-vcc proceeds with its own summary
132
+ const result = emit("session_before_compact", makeEvent(entries, undefined, 180000));
125
133
  expect(result.cancel).toBeUndefined();
126
134
  expect(result.compaction).toBeDefined();
127
135
  });
128
136
 
129
- test("cancels when context is below globalThreshold with compactPercent", () => {
130
- // compactPercent: 65 → reserve = 128000 * 0.35 = 44800 → threshold = 83200
131
- setConfig({
132
- debug: false,
133
- overrideDefaultCompaction: true,
134
- globalThreshold: { compactPercent: 65 },
135
- });
136
- const { pi, invoke } = createMockPi({
137
- id: "some-model",
138
- provider: "some-provider",
139
- contextWindow: 128000,
140
- });
141
- registerBeforeCompactHook(pi);
142
-
143
- // 50k tokens < 83200 → below threshold
144
- const entries = [
145
- msg("m1", "user", "hello"),
146
- msg("m2", "assistant", "hi"),
147
- msg("m3", "user", "do work"),
148
- msg("m4", "assistant", "done"),
149
- ];
150
- const result = invoke(makeEvent(entries, undefined, 50000));
151
- expect(result).toEqual({ cancel: true });
152
- });
153
-
154
- test("allows compaction when context exceeds globalThreshold with compactPercent", () => {
137
+ test("compaction proceeds with globalThreshold compactPercent", () => {
155
138
  // compactPercent: 65 → reserve = 128000 * 0.35 = 44800 → threshold = 83200
156
139
  setConfig({
157
140
  debug: false,
158
141
  overrideDefaultCompaction: true,
159
142
  globalThreshold: { compactPercent: 65 },
160
143
  });
161
- const { pi, invoke } = createMockPi({
144
+ const { pi, ctx, emit } = createMockPi({
162
145
  id: "some-model",
163
146
  provider: "some-provider",
164
147
  contextWindow: 128000,
165
148
  });
166
149
  registerBeforeCompactHook(pi);
167
150
 
168
- // 100k tokens > 83200 → above threshold
151
+ // 50k tokens < 83200 → below threshold, but proceeds
169
152
  const entries = [
170
153
  msg("m1", "user", "hello"),
171
154
  msg("m2", "assistant", "hi"),
172
155
  msg("m3", "user", "do work"),
173
156
  msg("m4", "assistant", "done"),
174
157
  ];
175
- const result = invoke(makeEvent(entries, undefined, 100000));
158
+ const result = emit("session_before_compact", makeEvent(entries, undefined, 50000));
176
159
  expect(result.cancel).toBeUndefined();
177
160
  expect(result.compaction).toBeDefined();
178
161
  });
179
162
 
180
- test("cancels when context is below modelThreshold with compactPercent", () => {
163
+ test("compaction proceeds with modelThreshold compactPercent", () => {
181
164
  // compactPercent: 80 → reserve = 200000 * 0.20 = 40000 → threshold = 160000
182
165
  setConfig({
183
166
  debug: false,
@@ -186,68 +169,48 @@ describe("session_before_compact: per-model threshold", () => {
186
169
  "neuralwatt/GLM-5.1": { compactPercent: 80 },
187
170
  },
188
171
  });
189
- const { pi, invoke } = createMockPi({
172
+ const { pi, ctx, emit } = createMockPi({
190
173
  id: "GLM-5.1",
191
174
  provider: "neuralwatt",
192
175
  contextWindow: 200000,
193
176
  });
194
177
  registerBeforeCompactHook(pi);
195
178
 
196
- // 100k tokens < 160000 → below threshold
179
+ // 100k tokens < 160000 → below threshold, but proceeds
197
180
  const entries = [
198
181
  msg("m1", "user", "hello"),
199
182
  msg("m2", "assistant", "hi"),
200
183
  msg("m3", "user", "do work"),
201
184
  msg("m4", "assistant", "done"),
202
185
  ];
203
- const result = invoke(makeEvent(entries, undefined, 100000));
204
- expect(result).toEqual({ cancel: true });
205
- });
206
-
207
- test("globalThreshold with compactPercent falls back from defaultThreshold", () => {
208
- setConfig({
209
- debug: false,
210
- overrideDefaultCompaction: true,
211
- defaultThreshold: { reserveTokens: 16384 },
212
- });
213
- const { pi, invoke } = createMockPi({
214
- id: "some-model",
215
- provider: "some-provider",
216
- contextWindow: 128000,
217
- });
218
- registerBeforeCompactHook(pi);
219
-
220
- // 50k tokens < 128k - 16384 = 111616 → below threshold
221
- const entries = [
222
- msg("m1", "user", "hello"),
223
- msg("m2", "assistant", "hi"),
224
- ];
225
- const result = invoke(makeEvent(entries, undefined, 50000));
226
- expect(result).toEqual({ cancel: true });
186
+ const result = emit("session_before_compact", makeEvent(entries, undefined, 100000));
187
+ expect(result.cancel).toBeUndefined();
188
+ expect(result.compaction).toBeDefined();
227
189
  });
228
190
 
229
- test("cancels when context is below defaultThreshold", () => {
191
+ test("compaction proceeds with defaultThreshold", () => {
230
192
  setConfig({
231
193
  debug: false,
232
194
  overrideDefaultCompaction: true,
233
195
  defaultThreshold: { reserveTokens: 16384 },
234
196
  });
235
- const { pi, invoke } = createMockPi({
197
+ const { pi, ctx, emit } = createMockPi({
236
198
  id: "some-model",
237
199
  provider: "some-provider",
238
200
  contextWindow: 128000,
239
201
  });
240
202
  registerBeforeCompactHook(pi);
241
203
 
242
- // 50k tokens < 128k - 16384 = 111616 → below threshold
204
+ // 50k tokens < 128k - 16384 = 111616 → below threshold, but proceeds
243
205
  const entries = [
244
206
  msg("m1", "user", "hello"),
245
207
  msg("m2", "assistant", "hi"),
246
208
  msg("m3", "user", "do work"),
247
209
  msg("m4", "assistant", "done"),
248
210
  ];
249
- const result = invoke(makeEvent(entries, undefined, 50000));
250
- expect(result).toEqual({ cancel: true });
211
+ const result = emit("session_before_compact", makeEvent(entries, undefined, 50000));
212
+ expect(result.cancel).toBeUndefined();
213
+ expect(result.compaction).toBeDefined();
251
214
  });
252
215
 
253
216
  test("does NOT cancel on /pi-vcc even when below threshold", () => {
@@ -258,51 +221,48 @@ describe("session_before_compact: per-model threshold", () => {
258
221
  "neuralwatt/GLM-5.1": { reserveTokens: 32768 },
259
222
  },
260
223
  });
261
- const { pi, invoke } = createMockPi({
224
+ const { pi, ctx, emit } = createMockPi({
262
225
  id: "GLM-5.1",
263
226
  provider: "neuralwatt",
264
227
  contextWindow: 200000,
265
228
  });
266
229
  registerBeforeCompactHook(pi);
267
230
 
268
- // Below threshold, but explicit /pi-vcc command — should NOT cancel
231
+ // Below threshold, but explicit /pi-vcc command
269
232
  const entries = [
270
233
  msg("m1", "user", "hello"),
271
234
  msg("m2", "assistant", "hi"),
272
235
  msg("m3", "user", "do work"),
273
236
  msg("m4", "assistant", "done"),
274
237
  ];
275
- const result = invoke(makeEvent(entries, PI_VCC_COMPACT_INSTRUCTION, 100000));
276
- // Not cancelled — explicit /pi-vcc bypasses threshold check
238
+ const result = emit("session_before_compact", makeEvent(entries, PI_VCC_COMPACT_INSTRUCTION, 100000));
277
239
  expect(result.cancel).toBeUndefined();
278
240
  expect(result.compaction).toBeDefined();
279
241
  });
280
242
 
281
- test("does not cancel when no modelThresholds configured", () => {
243
+ test("compaction proceeds when no modelThresholds configured", () => {
282
244
  setConfig({
283
245
  debug: false,
284
246
  overrideDefaultCompaction: true,
285
247
  });
286
- const { pi, invoke } = createMockPi({
248
+ const { pi, ctx, emit } = createMockPi({
287
249
  id: "GLM-5.1",
288
250
  provider: "neuralwatt",
289
251
  contextWindow: 200000,
290
252
  });
291
253
  registerBeforeCompactHook(pi);
292
254
 
293
- // No modelThresholds → no threshold override → fall through to normal flow
294
255
  const entries = [
295
256
  msg("m1", "user", "hello"),
296
257
  msg("m2", "assistant", "hi"),
297
258
  msg("m3", "user", "do work"),
298
259
  msg("m4", "assistant", "done"),
299
260
  ];
300
- const result = invoke(makeEvent(entries, undefined, 100000));
301
- // Not cancelled by threshold check (may be cancelled by other logic)
261
+ const result = emit("session_before_compact", makeEvent(entries, undefined, 100000));
302
262
  expect(result.cancel === true).toBe(false);
303
263
  });
304
264
 
305
- test("does not cancel when model is undefined", () => {
265
+ test("compaction proceeds when model is undefined", () => {
306
266
  setConfig({
307
267
  debug: false,
308
268
  overrideDefaultCompaction: true,
@@ -310,8 +270,7 @@ describe("session_before_compact: per-model threshold", () => {
310
270
  "GLM-5.1": { reserveTokens: 32768 },
311
271
  },
312
272
  });
313
- // No model provided — ctx.model is undefined
314
- const { pi, invoke } = createMockPi(undefined);
273
+ const { pi, ctx, emit } = createMockPi(undefined);
315
274
  registerBeforeCompactHook(pi);
316
275
 
317
276
  const entries = [
@@ -320,12 +279,11 @@ describe("session_before_compact: per-model threshold", () => {
320
279
  msg("m3", "user", "do work"),
321
280
  msg("m4", "assistant", "done"),
322
281
  ];
323
- const result = invoke(makeEvent(entries, undefined, 100000));
324
- // No model → can't check threshold → fall through to normal flow
282
+ const result = emit("session_before_compact", makeEvent(entries, undefined, 100000));
325
283
  expect(result.cancel === true).toBe(false);
326
284
  });
327
285
 
328
- test("threshold check also applies when overrideDefaultCompaction is false", () => {
286
+ test("compaction proceeds with overrideDefaultCompaction false", () => {
329
287
  setConfig({
330
288
  debug: false,
331
289
  overrideDefaultCompaction: false,
@@ -333,45 +291,21 @@ describe("session_before_compact: per-model threshold", () => {
333
291
  "neuralwatt/GLM-5.1": { reserveTokens: 32768 },
334
292
  },
335
293
  });
336
- const { pi, invoke } = createMockPi({
337
- id: "GLM-5.1",
338
- provider: "neuralwatt",
339
- contextWindow: 200000,
340
- });
341
- registerBeforeCompactHook(pi);
342
-
343
- // Below threshold → cancel, even though pi-vcc wouldn't handle the summary
344
- const entries = [
345
- msg("m1", "user", "hello"),
346
- msg("m2", "assistant", "hi"),
347
- ];
348
- const result = invoke(makeEvent(entries, undefined, 100000));
349
- expect(result).toEqual({ cancel: true });
350
- });
351
-
352
- test("modelId-only key matches when provider/modelId does not", () => {
353
- setConfig({
354
- debug: false,
355
- overrideDefaultCompaction: true,
356
- modelThresholds: {
357
- "GLM-5.1": { reserveTokens: 32768 },
358
- },
359
- });
360
- const { pi, invoke } = createMockPi({
294
+ const { pi, ctx, emit } = createMockPi({
361
295
  id: "GLM-5.1",
362
296
  provider: "neuralwatt",
363
297
  contextWindow: 200000,
364
298
  });
365
299
  registerBeforeCompactHook(pi);
366
300
 
367
- // Should match on modelId-only key
301
+ // Below threshold, overrideDefaultCompaction: false → pi-vcc doesn't
302
+ // handle the summary, but also doesn't cancel (threshold guard removed)
368
303
  const entries = [
369
304
  msg("m1", "user", "hello"),
370
305
  msg("m2", "assistant", "hi"),
371
- msg("m3", "user", "do work"),
372
- msg("m4", "assistant", "done"),
373
306
  ];
374
- const result = invoke(makeEvent(entries, undefined, 100000));
375
- expect(result).toEqual({ cancel: true });
307
+ const result = emit("session_before_compact", makeEvent(entries, undefined, 100000));
308
+ // Not cancelled — returns undefined (pi-vcc doesn't handle it)
309
+ expect(result).toBeUndefined();
376
310
  });
377
311
  });
@@ -5,9 +5,10 @@
5
5
  * - When proactive trigger calls ctx.compact(), session_before_compact
6
6
  * must NOT cancel the compaction even if tokensBefore differs from
7
7
  * getContextUsage().
8
- * - When the global threshold triggers compaction but the model can
9
- * handle more (per-model threshold not crossed), session_before_compact
10
- * must cancel.
8
+ * - The per-model threshold guard was removed from session_before_compact
9
+ * because the event carries no "reason" field — manual /compact and
10
+ * auto-compaction are indistinguishable. The proactive trigger handles
11
+ * the "compact earlier than pi-core" direction.
11
12
  */
12
13
  import { describe, test, expect, afterEach, beforeAll, afterAll } from "bun:test";
13
14
  import { existsSync, unlinkSync, writeFileSync, mkdtempSync, rmSync } from "fs";
@@ -100,11 +101,6 @@ describe("integration: proactive trigger + before-compact", () => {
100
101
  });
101
102
 
102
103
  test("proactive trigger then before-compact: does NOT cancel when proactiveTriggerActive", () => {
103
- // Scenario: agent_end fires, getContextUsage says 110k tokens,
104
- // per-model threshold is 95232 (128k - 32768). Proactive triggers compact.
105
- // Then session_before_compact fires with tokensBefore = 94000
106
- // (slightly different due to estimation).
107
- // Without the proactiveTriggerActive guard, this would be cancelled.
108
104
  setConfig({
109
105
  debug: false,
110
106
  overrideDefaultCompaction: true,
@@ -119,13 +115,9 @@ describe("integration: proactive trigger + before-compact", () => {
119
115
  registerProactiveThresholdHook(pi);
120
116
  registerBeforeCompactHook(pi);
121
117
 
122
- // Step 1: agent_end fires → proactive trigger calls ctx.compact()
123
118
  emit("agent_end", { type: "agent_end", messages: [] });
124
119
  expect(compactCalls).toHaveLength(1);
125
120
 
126
- // Step 2: session_before_compact fires with tokensBefore = 94000
127
- // (below the 95232 threshold — but we should NOT cancel because
128
- // we ourselves triggered this compaction)
129
121
  const entries = [
130
122
  msg("m1", "user", "hello"),
131
123
  msg("m2", "assistant", "hi"),
@@ -136,14 +128,14 @@ describe("integration: proactive trigger + before-compact", () => {
136
128
 
137
129
  // Should NOT cancel — proactiveTriggerActive is true
138
130
  expect(result?.cancel).toBeUndefined();
139
- // Should proceed with compaction (pi-vcc's own summary)
140
131
  expect(result?.compaction).toBeDefined();
141
132
  });
142
133
 
143
- test("global trigger + before-compact: CANCELS when per-model threshold not crossed and no proactive trigger", () => {
144
- // Scenario: pi-core's global threshold triggers compaction,
145
- // but the model's per-model threshold hasn't been crossed.
146
- // No proactive trigger was set — this is pi-core's own initiative.
134
+ test("global trigger + before-compact: compaction proceeds (threshold guard removed)", () => {
135
+ // Previously: pi-core's global threshold triggers compaction below the
136
+ // per-model threshold → cancelled. Now: the threshold guard is removed
137
+ // because manual /compact can't be distinguished from auto-compaction,
138
+ // so compaction proceeds.
147
139
  setConfig({
148
140
  debug: false,
149
141
  overrideDefaultCompaction: true,
@@ -151,24 +143,23 @@ describe("integration: proactive trigger + before-compact", () => {
151
143
  "neuralwatt/GLM-5.1": { reserveTokens: 32768 },
152
144
  },
153
145
  });
154
- const { pi, ctx, emit, compactCalls } = createMockPi(
146
+ const { pi, ctx, emit } = createMockPi(
155
147
  { id: "GLM-5.1", provider: "neuralwatt", contextWindow: 128000 },
156
- // getContextUsage says 80k — well below per-model threshold
157
148
  { tokens: 80000, contextWindow: 128000, percent: 63 },
158
149
  );
159
150
  registerProactiveThresholdHook(pi);
160
151
  registerBeforeCompactHook(pi);
161
152
 
162
- // No agent_end fired (global threshold triggered this)
163
153
  const entries = [
164
154
  msg("m1", "user", "hello"),
165
155
  msg("m2", "assistant", "hi"),
166
156
  msg("m3", "user", "do work"),
167
157
  msg("m4", "assistant", "done"),
168
158
  ];
169
- // tokensBefore = 90k < 95232 — should cancel
170
159
  const result = emit("session_before_compact", makeBeforeCompactEvent(entries, undefined, 90000));
171
- expect(result).toEqual({ cancel: true });
160
+ // No longer cancelled — threshold guard removed
161
+ expect(result?.cancel).toBeUndefined();
162
+ expect(result?.compaction).toBeDefined();
172
163
  });
173
164
 
174
165
  test("proactiveTriggerActive is cleared after session_compact", () => {
@@ -186,16 +177,13 @@ describe("integration: proactive trigger + before-compact", () => {
186
177
  registerProactiveThresholdHook(pi);
187
178
  registerBeforeCompactHook(pi);
188
179
 
189
- // Step 1: proactive trigger
190
180
  emit("agent_end", { type: "agent_end", messages: [] });
191
181
  expect(compactCalls).toHaveLength(1);
192
182
 
193
- // Step 2: compaction completes
194
183
  emit("session_compact", { type: "session_compact", compactionEntry: {} });
195
184
 
196
- // Step 3: now a subsequent session_before_compact (e.g., from pi-core
197
- // also triggering) with tokensBelow below threshold — should CANCEL
198
- // because proactiveTriggerActive was cleared by session_compact
185
+ // After session_compact, proactiveTriggerActive is cleared.
186
+ // But the threshold guard is also removed, so compaction proceeds.
199
187
  const entries = [
200
188
  msg("m1", "user", "hello"),
201
189
  msg("m2", "assistant", "hi"),
@@ -203,10 +191,11 @@ describe("integration: proactive trigger + before-compact", () => {
203
191
  msg("m4", "assistant", "done"),
204
192
  ];
205
193
  const result = emit("session_before_compact", makeBeforeCompactEvent(entries, undefined, 90000));
206
- expect(result).toEqual({ cancel: true });
194
+ expect(result?.cancel).toBeUndefined();
195
+ expect(result?.compaction).toBeDefined();
207
196
  });
208
197
 
209
- test("explicit /pi-vcc bypasses both the proactive flag AND threshold guard", () => {
198
+ test("explicit /pi-vcc proceeds regardless of context level", () => {
210
199
  setConfig({
211
200
  debug: false,
212
201
  overrideDefaultCompaction: true,
@@ -216,19 +205,18 @@ describe("integration: proactive trigger + before-compact", () => {
216
205
  });
217
206
  const { pi, ctx, emit } = createMockPi(
218
207
  { id: "GLM-5.1", provider: "neuralwatt", contextWindow: 128000 },
219
- { tokens: 50000, contextWindow: 128000, percent: 39 },
208
+ { tokens: 5000, contextWindow: 128000, percent: 4 },
220
209
  );
221
210
  registerProactiveThresholdHook(pi);
222
211
  registerBeforeCompactHook(pi);
223
212
 
224
- // Direct /pi-vcc with tokens well below threshold — should still proceed
225
213
  const entries = [
226
214
  msg("m1", "user", "hello"),
227
215
  msg("m2", "assistant", "hi"),
228
216
  msg("m3", "user", "do work"),
229
217
  msg("m4", "assistant", "done"),
230
218
  ];
231
- const result = emit("session_before_compact", makeBeforeCompactEvent(entries, "__pi_vcc__", 50000));
219
+ const result = emit("session_before_compact", makeBeforeCompactEvent(entries, "__pi_vcc__", 5000));
232
220
  expect(result?.cancel).toBeUndefined();
233
221
  expect(result?.compaction).toBeDefined();
234
222
  });
@@ -241,10 +229,6 @@ describe("integration: proactive trigger + before-compact with overrideDefaultCo
241
229
  });
242
230
 
243
231
  test("proactive trigger fires, before-compact doesn't cancel, then pi-core handles summary", () => {
244
- // When overrideDefaultCompaction: false, pi-vcc doesn't handle the summary
245
- // for non-/pi-vcc compactions. But the threshold guard and proactive trigger
246
- // should still work — the threshold guard controls WHEN compaction triggers,
247
- // and pi-core handles the actual summary.
248
232
  setConfig({
249
233
  debug: false,
250
234
  overrideDefaultCompaction: false,
@@ -259,14 +243,9 @@ describe("integration: proactive trigger + before-compact with overrideDefaultCo
259
243
  registerProactiveThresholdHook(pi);
260
244
  registerBeforeCompactHook(pi);
261
245
 
262
- // agent_end fires → proactive trigger
263
246
  emit("agent_end", { type: "agent_end", messages: [] });
264
247
  expect(compactCalls).toHaveLength(1);
265
248
 
266
- // session_before_compact fires: threshold is crossed (tokensBefore = 110k
267
- // > 95232), and our guard allows it because proactiveTriggerActive.
268
- // Then overrideDefaultCompaction: false means pi-vcc returns undefined,
269
- // letting pi-core handle the summary.
270
249
  const entries = [
271
250
  msg("m1", "user", "hello"),
272
251
  msg("m2", "assistant", "hi"),
@@ -275,11 +254,10 @@ describe("integration: proactive trigger + before-compact with overrideDefaultCo
275
254
  ];
276
255
  const result = emit("session_before_compact", makeBeforeCompactEvent(entries, undefined, 110000));
277
256
  // pi-vcc doesn't handle it (overrideDefaultCompaction: false) → returns undefined
278
- // pi-core will handle the summary
279
257
  expect(result).toBeUndefined();
280
258
  });
281
259
 
282
- test("threshold guard cancels even with overrideDefaultCompaction: false", () => {
260
+ test("compaction proceeds even with overrideDefaultCompaction: false (threshold guard removed)", () => {
283
261
  setConfig({
284
262
  debug: false,
285
263
  overrideDefaultCompaction: false,
@@ -294,15 +272,16 @@ describe("integration: proactive trigger + before-compact with overrideDefaultCo
294
272
  registerProactiveThresholdHook(pi);
295
273
  registerBeforeCompactHook(pi);
296
274
 
297
- // No proactive trigger (context below threshold)
298
- // Pi-core's global threshold triggers compaction, but per-model threshold
299
- // says the model can handle more → cancel
275
+ // Previously this would cancel (threshold guard). Now: compaction
276
+ // proceeds (threshold guard removed).
300
277
  const entries = [
301
278
  msg("m1", "user", "hello"),
302
279
  msg("m2", "assistant", "hi"),
303
280
  ];
304
281
  const result = emit("session_before_compact", makeBeforeCompactEvent(entries, undefined, 80000));
305
- expect(result).toEqual({ cancel: true });
282
+ // No longer cancelled — returns undefined (pi-vcc doesn't handle it,
283
+ // but doesn't block it either)
284
+ expect(result).toBeUndefined();
306
285
  });
307
286
  });
308
287
 
@@ -326,11 +305,9 @@ describe("integration: cooldown prevents double compaction", () => {
326
305
  );
327
306
  registerProactiveThresholdHook(pi);
328
307
 
329
- // agent_end triggers compact and sets cooldown
330
308
  emit("agent_end", { type: "agent_end", messages: [] });
331
309
  expect(compactCalls).toHaveLength(1);
332
310
 
333
- // model_select fires on same turn — blocked by cooldown
334
311
  emit("model_select", { type: "model_select" });
335
312
  expect(compactCalls).toHaveLength(1);
336
313
  });
@@ -352,7 +329,6 @@ describe("integration: cooldown prevents double compaction", () => {
352
329
  emit("agent_end", { type: "agent_end", messages: [] });
353
330
  expect(compactCalls).toHaveLength(1);
354
331
 
355
- // No session_compact between — cooldown still active
356
332
  emit("agent_end", { type: "agent_end", messages: [] });
357
333
  expect(compactCalls).toHaveLength(1);
358
334
  });