@monotykamary/pi-vcc 0.6.3 → 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 +8 -7
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/src/core/settings.ts +52 -15
- package/src/hooks/proactive-threshold.ts +12 -14
package/README.md
CHANGED
|
@@ -211,7 +211,7 @@ pi-vcc is one of four compaction approaches in the AI coding-agent ecosystem. He
|
|
|
211
211
|
- **Error resolution detection** — tsc errors in `[Outstanding Context]` are tagged `[RESOLVED]` when the file they reference was subsequently edited, letting the model skip stale errors.
|
|
212
212
|
- **Task-boundary-aware cut** — compaction splits at complete conversational turns, not mid-tool-call. If the assistant's response is in-flight (unmatched tool calls), the cut pushes back to keep the whole turn in the tail.
|
|
213
213
|
- **Structured anchors** — `[Anchors]` section lists commit hashes, error IDs, and key file paths for zero-tool-call recall. The model can find references at a glance instead of calling `vcc_recall`.
|
|
214
|
-
- **Per-model and global compaction thresholds** — configure different `reserveTokens` or `compactPercent` per model and globally, so models with different context windows compact at the right time. Proactive triggering on `agent_end` and `model_select` events compacts earlier for small-context models. Applies to both pi-vcc and pi-core compaction.
|
|
214
|
+
- **Per-model and global compaction thresholds** — configure different `reserveTokens`, `compactAtTokens`, or `compactPercent` per model and globally, so models with different context windows compact at the right time. Proactive triggering on `agent_end` and `model_select` events compacts earlier for small-context models. Applies to both pi-vcc and pi-core compaction.
|
|
215
215
|
|
|
216
216
|
## Install
|
|
217
217
|
|
|
@@ -567,24 +567,25 @@ Config lives at `~/.pi/agent/pi-vcc-config.json` (auto-scaffolded on first load
|
|
|
567
567
|
"modelThresholds": {
|
|
568
568
|
"neuralwatt/zai-org/GLM-5.1-FP8": { "reserveTokens": 32768 },
|
|
569
569
|
"neuralwatt/moonshotai/Kimi-K2.6": { "compactPercent": 65 },
|
|
570
|
-
"neuralwatt/
|
|
570
|
+
"neuralwatt/glm-5.1-long": { "compactAtTokens": 150000 }
|
|
571
571
|
},
|
|
572
|
-
"globalThreshold": { "
|
|
572
|
+
"globalThreshold": { "compactAtTokens": 150000 }
|
|
573
573
|
}
|
|
574
574
|
```
|
|
575
575
|
|
|
576
576
|
- **`overrideDefaultCompaction`** *(default `true`)*: when `true` (default), pi-vcc handles all compaction paths (`/compact`, auto-threshold, `/pi-vcc`). Set `false` to let pi core handle `/compact` and auto-threshold compactions via its default LLM-based compaction.
|
|
577
577
|
- **`debug`** *(default `false`)*: when `true`, each compaction writes detailed info to `/tmp/pi-vcc-debug.json` — message counts, cut boundary, summary preview, sections.
|
|
578
578
|
- **`modelThresholds`** *(default: none)*: per-model compaction thresholds. Keys match against `"provider/modelId"` (e.g., `"neuralwatt/zai-org/GLM-5.1-FP8"`) or just `"modelId"` (e.g., `"GLM-5.1"` — matched only when `provider/modelId` doesn't). Each value has:
|
|
579
|
-
- **`reserveTokens`**: tokens to reserve for the LLM response. Overrides pi-core's global `compaction.reserveTokens` for matching models. Controls *when* compaction triggers: `contextTokens > contextWindow − reserveTokens`. A higher value compacts earlier (more conservative); a lower value lets context grow larger. Takes precedence over `compactPercent` when
|
|
580
|
-
- **`
|
|
579
|
+
- **`reserveTokens`**: tokens to reserve for the LLM response. Overrides pi-core's global `compaction.reserveTokens` for matching models. Controls *when* compaction triggers: `contextTokens > contextWindow − reserveTokens`. A higher value compacts earlier (more conservative); a lower value lets context grow larger. Takes precedence over `compactAtTokens` and `compactPercent` when multiple are set.
|
|
580
|
+
- **`compactAtTokens`**: absolute context token count where compaction triggers: `contextTokens > compactAtTokens`. Useful when you want the same trigger point across models with different context windows, such as `{ "compactAtTokens": 150000 }`. Takes precedence over `compactPercent` when both are set.
|
|
581
|
+
- **`compactPercent`**: compaction trigger as a percentage of context window (1–99). Compaction fires when `contextTokens > contextWindow × compactPercent / 100`. E.g. `65` means "compact when context is 65% full". Ignored when `reserveTokens` or `compactAtTokens` is also set.
|
|
581
582
|
- **`keepRecentTokens`** *(optional)*: advisory token budget for pi-core's default compaction. Pi-vcc's own `buildOwnCut` uses task-boundary heuristics, so this only affects pi-core's cut when `overrideDefaultCompaction` is `false`.
|
|
582
|
-
- **`globalThreshold`** *(default: none)*: global threshold applied to all models not matched by `modelThresholds`. Uses `
|
|
583
|
+
- **`globalThreshold`** *(default: none)*: global threshold applied to all models not matched by `modelThresholds`. Uses `reserveTokens`, `compactAtTokens`, or `compactPercent`. If omitted, pi-core's global `compaction.reserveTokens` applies (no override).
|
|
583
584
|
- **`defaultThreshold`** *(default: none, deprecated)*: use `globalThreshold` instead. Backward compatible — still works.
|
|
584
585
|
|
|
585
586
|
### How compaction thresholds work
|
|
586
587
|
|
|
587
|
-
Pi-core's auto-compaction triggers when `contextTokens > contextWindow − reserveTokens`. The global `reserveTokens` (default 16384) is one-size-fits-all — but different models have very different context windows and cost profiles.
|
|
588
|
+
Pi-core's auto-compaction triggers when `contextTokens > contextWindow − reserveTokens`. The global `reserveTokens` (default 16384) is one-size-fits-all — but different models have very different context windows and cost profiles. Pi-vcc also supports `compactAtTokens` when you want an absolute trigger point independent of a model's context window.
|
|
588
589
|
|
|
589
590
|
Pi-vcc's thresholds provide proactive compaction at both the per-model and global level:
|
|
590
591
|
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monotykamary/pi-vcc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@monotykamary/pi-vcc",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.7.0",
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"knip": "6.14.1",
|
|
12
12
|
"typescript": "6.0.3"
|
package/package.json
CHANGED
package/src/core/settings.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
-
import { homedir } from "os";
|
|
3
2
|
import { dirname, join } from "path";
|
|
3
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
5
|
+
const settingsPath = (): string =>
|
|
6
|
+
process.env.PI_VCC_CONFIG_PATH ?? join(getAgentDir(), "pi-vcc-config.json");
|
|
7
7
|
/** Backwards-compat export. Resolves at access time, not import time. */
|
|
8
8
|
const SETTINGS_PATH = settingsPath();
|
|
9
9
|
|
|
@@ -19,9 +19,20 @@ export interface ModelThreshold {
|
|
|
19
19
|
* A higher value compacts earlier (more conservative); a lower value
|
|
20
20
|
* lets context grow larger before compacting.
|
|
21
21
|
*
|
|
22
|
-
* Takes precedence over compactPercent when
|
|
22
|
+
* Takes precedence over compactAtTokens and compactPercent when multiple are set.
|
|
23
23
|
*/
|
|
24
24
|
reserveTokens?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Absolute context token count where compaction triggers.
|
|
27
|
+
*
|
|
28
|
+
* This controls *when* compaction triggers:
|
|
29
|
+
* contextTokens > compactAtTokens
|
|
30
|
+
*
|
|
31
|
+
* Useful when you want the same trigger point across models with
|
|
32
|
+
* different context windows. Ignored when reserveTokens is also set;
|
|
33
|
+
* takes precedence over compactPercent.
|
|
34
|
+
*/
|
|
35
|
+
compactAtTokens?: number;
|
|
25
36
|
/**
|
|
26
37
|
* Compaction trigger as a percentage of context window (1–99).
|
|
27
38
|
* Compaction fires when: contextTokens > contextWindow × compactPercent / 100
|
|
@@ -29,7 +40,7 @@ export interface ModelThreshold {
|
|
|
29
40
|
* E.g. compactPercent: 65 means "compact when context is 65% full",
|
|
30
41
|
* equivalent to reserveTokens = 35% of contextWindow.
|
|
31
42
|
*
|
|
32
|
-
* Ignored when reserveTokens is also set.
|
|
43
|
+
* Ignored when reserveTokens or compactAtTokens is also set.
|
|
33
44
|
*/
|
|
34
45
|
compactPercent?: number;
|
|
35
46
|
/**
|
|
@@ -61,17 +72,16 @@ export interface PiVccSettings {
|
|
|
61
72
|
* "provider/modelId" (e.g., "neuralwatt/zai-org/GLM-5.1-FP8") or
|
|
62
73
|
* just "modelId" (e.g., "GLM-5.1-FP8").
|
|
63
74
|
*
|
|
64
|
-
* When a model matches, its reserveTokens/compactPercent
|
|
65
|
-
* pi-core's global compaction.reserveTokens for the *when to
|
|
66
|
-
* decision. This lets different models compact at different
|
|
67
|
-
* fill levels.
|
|
75
|
+
* When a model matches, its reserveTokens/compactAtTokens/compactPercent
|
|
76
|
+
* overrides pi-core's global compaction.reserveTokens for the *when to
|
|
77
|
+
* compact* decision. This lets different models compact at different
|
|
78
|
+
* context fill levels or absolute token counts.
|
|
68
79
|
*/
|
|
69
80
|
modelThresholds?: Record<string, ModelThreshold>;
|
|
70
81
|
/**
|
|
71
82
|
* Global threshold applied to all models not matched by modelThresholds.
|
|
72
|
-
* Uses
|
|
73
|
-
*
|
|
74
|
-
* compaction settings apply (no override).
|
|
83
|
+
* Uses reserveTokens, compactAtTokens, or compactPercent. If omitted,
|
|
84
|
+
* pi-core's global compaction settings apply (no override).
|
|
75
85
|
*/
|
|
76
86
|
globalThreshold?: ModelThreshold;
|
|
77
87
|
/**
|
|
@@ -91,8 +101,8 @@ const DEFAULT_SETTINGS: PiVccSettings = {
|
|
|
91
101
|
* Lookup order:
|
|
92
102
|
* 1. Exact match on "provider/modelId" key
|
|
93
103
|
* 2. Exact match on "modelId" key
|
|
94
|
-
*
|
|
95
|
-
*
|
|
104
|
+
* 3. globalThreshold from settings
|
|
105
|
+
* 4. undefined (no override — pi-core's global settings apply)
|
|
96
106
|
*/
|
|
97
107
|
export function getModelThreshold(
|
|
98
108
|
settings: PiVccSettings,
|
|
@@ -136,6 +146,33 @@ export function resolveReserveTokens(
|
|
|
136
146
|
return undefined;
|
|
137
147
|
}
|
|
138
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Resolve the context token count where compaction should trigger.
|
|
151
|
+
*
|
|
152
|
+
* Precedence: reserveTokens > compactAtTokens > compactPercent.
|
|
153
|
+
* Returns undefined when the threshold cannot produce a usable trigger.
|
|
154
|
+
*/
|
|
155
|
+
export function resolveTriggerTokens(
|
|
156
|
+
threshold: ModelThreshold,
|
|
157
|
+
contextWindow: number,
|
|
158
|
+
): number | undefined {
|
|
159
|
+
if (contextWindow <= 0) return undefined;
|
|
160
|
+
|
|
161
|
+
if (threshold.reserveTokens != null) {
|
|
162
|
+
return contextWindow - threshold.reserveTokens;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (threshold.compactAtTokens != null) {
|
|
166
|
+
const tokens = threshold.compactAtTokens;
|
|
167
|
+
if (!Number.isFinite(tokens) || tokens < 1) return undefined;
|
|
168
|
+
return Math.round(tokens);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const reserve = resolveReserveTokens(threshold, contextWindow);
|
|
172
|
+
if (reserve == null) return undefined;
|
|
173
|
+
return contextWindow - reserve;
|
|
174
|
+
}
|
|
175
|
+
|
|
139
176
|
const readJson = (path: string): Record<string, unknown> | null => {
|
|
140
177
|
try {
|
|
141
178
|
return JSON.parse(readFileSync(path, "utf-8"));
|
|
@@ -156,7 +193,7 @@ export function loadSettings(): PiVccSettings {
|
|
|
156
193
|
}
|
|
157
194
|
|
|
158
195
|
/**
|
|
159
|
-
* Ensure ~/.pi/agent/pi-vcc-config.json exists with default keys.
|
|
196
|
+
* Ensure the pi-vcc config file (default ~/.pi/agent/pi-vcc-config.json) exists with default keys.
|
|
160
197
|
* - File missing → create with full default block.
|
|
161
198
|
* - File exists but invalid JSON → no-op (don't clobber user file).
|
|
162
199
|
* - File exists and valid → fill in missing default keys, preserve existing values.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { loadSettings, getModelThreshold,
|
|
2
|
+
import { loadSettings, getModelThreshold, resolveTriggerTokens } from "../core/settings";
|
|
3
3
|
|
|
4
4
|
const formatTokens = (n: number): string => {
|
|
5
5
|
if (n >= 1000) return `${(n / 1000).toFixed(1)}k`;
|
|
@@ -32,7 +32,7 @@ export const resetProactiveState = () => {
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
* Check if
|
|
35
|
+
* Check if a configured threshold has been crossed and trigger compaction
|
|
36
36
|
* if so. Safe to call from multiple event handlers — cooldown prevents
|
|
37
37
|
* double-triggering.
|
|
38
38
|
*/
|
|
@@ -44,14 +44,13 @@ const checkAndTrigger = (ctx: { model?: any; getContextUsage?: () => any; compac
|
|
|
44
44
|
if (!threshold) return;
|
|
45
45
|
|
|
46
46
|
const contextWindow = ctx.model?.contextWindow ?? 0;
|
|
47
|
-
const
|
|
48
|
-
if (
|
|
47
|
+
const effectiveThreshold = resolveTriggerTokens(threshold, contextWindow);
|
|
48
|
+
if (effectiveThreshold == null) return;
|
|
49
49
|
|
|
50
50
|
const usage = ctx.getContextUsage?.();
|
|
51
51
|
if (!usage || usage.tokens === null) return;
|
|
52
52
|
|
|
53
|
-
// This threshold's compaction trigger point
|
|
54
|
-
const effectiveThreshold = contextWindow - reserve;
|
|
53
|
+
// This threshold's compaction trigger point.
|
|
55
54
|
|
|
56
55
|
// Only trigger if context EXCEEDS the threshold.
|
|
57
56
|
if (usage.tokens <= effectiveThreshold) return;
|
|
@@ -80,19 +79,18 @@ const checkAndTrigger = (ctx: { model?: any; getContextUsage?: () => any; compac
|
|
|
80
79
|
};
|
|
81
80
|
|
|
82
81
|
/**
|
|
83
|
-
* Registers proactive
|
|
82
|
+
* Registers proactive configured compaction thresholds.
|
|
84
83
|
*
|
|
85
84
|
* Three triggers:
|
|
86
85
|
*
|
|
87
86
|
* 1. `agent_end` — after each agent run completes, check if context
|
|
88
|
-
* exceeds the
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* at this point. We step in and trigger it proactively.
|
|
87
|
+
* exceeds the active configured threshold. If that threshold is lower
|
|
88
|
+
* than pi-core's global threshold (meaning this config wants to compact
|
|
89
|
+
* earlier), pi-core won't trigger compaction — so we do.
|
|
92
90
|
*
|
|
93
|
-
* 2. `model_select` — when switching
|
|
94
|
-
* threshold
|
|
95
|
-
*
|
|
91
|
+
* 2. `model_select` — when switching models, the new model may have a
|
|
92
|
+
* different threshold. Check immediately in case current context exceeds
|
|
93
|
+
* the new threshold.
|
|
96
94
|
*
|
|
97
95
|
* 3. `session_compact` — cooldown tracking + clear proactiveTriggerActive.
|
|
98
96
|
* After any compaction completes, we set a cooldown to prevent
|