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.
@@ -25,6 +25,21 @@ export const COMPACT_TIERS = {
25
25
  } as const;
26
26
  export type CompactTier = keyof typeof COMPACT_TIERS;
27
27
 
28
+ /**
29
+ * Compaction thresholds as a FRACTION of the model's context window (NOT a
30
+ * static token amount). The live + durable trim fire at tier% of the window,
31
+ * so they always fire BELOW pi's native auto-compaction (~80% of window) for
32
+ * any model size (200k or 1M). `custom` (explicit MEGACOMPACT_THRESHOLD_TOKENS)
33
+ * is NOT scaled by this map — it stays an absolute token count.
34
+ */
35
+ export const TIER_PCT: Record<CompactTier, number> = {
36
+ low: 0.5,
37
+ medium: 0.6,
38
+ high: 0.7,
39
+ ultra: 0.7,
40
+ mega: 0.75,
41
+ };
42
+
28
43
  /**
29
44
  * Resolved, frozen-at-load config. `tier` is the base compaction PRESET chosen
30
45
  * by env (low/medium/high/ultra/mega) — it sets the threshold token budget and
@@ -34,6 +49,12 @@ export type CompactTier = keyof typeof COMPACT_TIERS;
34
49
  */
35
50
  export interface MegaConfig {
36
51
  tier: CompactTier | "custom";
52
+ /**
53
+ * Compaction threshold as a fraction of the model context window (e.g. 0.70
54
+ * for "high"). null for `custom` (explicit MEGACOMPACT_THRESHOLD_TOKENS, which
55
+ * stays an ABSOLUTE token count, never percent-scaled).
56
+ */
57
+ tierPct: number | null;
37
58
  thresholdTokens: number;
38
59
  stateDir: string;
39
60
  fastGatePct: number;
@@ -89,16 +110,72 @@ function envBool(name: string, fallback: boolean): boolean {
89
110
  return v === "true" || v === "1";
90
111
  }
91
112
 
92
- /** Resolve the effective token threshold from TIER (or explicit) env vars. */
93
- function resolveThreshold(): { tier: CompactTier | "custom"; thresholdTokens: number } {
113
+ /**
114
+ * Resolve the effective token threshold from TIER (or explicit) env vars.
115
+ *
116
+ * For a named tier the returned `thresholdTokens` is a BOOT FALLBACK
117
+ * (`round(tierPct * 200_000)`) — sane before any context event reaches the
118
+ * runtime. The true fire point is computed per-window at runtime via
119
+ * `effectiveThresholdTokens(...)`. `custom` (explicit MEGACOMPACT_THRESHOLD_TOKENS)
120
+ * keeps `tierPct: null` and an ABSOLUTE `thresholdTokens` (never percent-scaled).
121
+ */
122
+ function resolveThreshold(): {
123
+ tier: CompactTier | "custom";
124
+ tierPct: number | null;
125
+ thresholdTokens: number;
126
+ } {
94
127
  const explicit = process.env.MEGACOMPACT_THRESHOLD_TOKENS;
95
128
  if (explicit != null && explicit !== "") {
96
129
  const n = Number(explicit);
97
- if (Number.isFinite(n)) return { tier: "custom", thresholdTokens: n };
130
+ if (Number.isFinite(n)) return { tier: "custom", tierPct: null, thresholdTokens: n };
98
131
  }
99
132
  const raw = (process.env.MEGACOMPACT_TIER ?? "low").toLowerCase();
100
133
  const tier = (raw in COMPACT_TIERS ? raw : "low") as CompactTier;
101
- return { tier, thresholdTokens: COMPACT_TIERS[tier] };
134
+ const tierPct = TIER_PCT[tier];
135
+ // Boot fallback: sane gate before the first context event provides a window.
136
+ const thresholdTokens = Math.round(tierPct * 200_000);
137
+ return { tier, tierPct, thresholdTokens };
138
+ }
139
+
140
+ /**
141
+ * Pure helper: the real compaction fire point, given the model context window.
142
+ *
143
+ * custom -> explicitThreshold (ABSOLUTE, never percent-scaled)
144
+ * tiered+window>0 -> round(tierPct * window)
145
+ * tiered+window<=0 -> fallbackThreshold (boot fallback; no window known yet)
146
+ *
147
+ * This is the single source of truth consumed by the runtime gates
148
+ * (FAST GATE / autoCompactCheck / agent_end durable trigger) and the
149
+ * pressure/armed/ready computations. Keeping it pure makes it trivially
150
+ * unit-testable without the pi runtime.
151
+ */
152
+ export function effectiveThresholdTokens(opts: {
153
+ tierPct: number | null;
154
+ fallbackThreshold: number;
155
+ window: number;
156
+ explicitThreshold?: number;
157
+ }): number {
158
+ if (opts.tierPct == null) {
159
+ // custom: absolute threshold, never percent-scaled
160
+ return opts.explicitThreshold ?? opts.fallbackThreshold;
161
+ }
162
+ if (opts.window > 0) return Math.round(opts.tierPct * opts.window);
163
+ return opts.fallbackThreshold;
164
+ }
165
+
166
+ /**
167
+ * Resolve the optional manual arming-floor override (MEGACOMPACT_FAST_GATE_PCT).
168
+ * Kept for backward-compat: when unset, the default arming floor equals the
169
+ * tier's percent threshold (tierPct*100) so the dashboard stays consistent;
170
+ * `custom` (tierPct null) falls back to the legacy 70% default.
171
+ */
172
+ function resolveFastGatePct(tierPct: number | null): number {
173
+ const raw = process.env.MEGACOMPACT_FAST_GATE_PCT;
174
+ if (raw != null && raw !== "") {
175
+ const n = Number(raw);
176
+ if (Number.isFinite(n)) return n;
177
+ }
178
+ return tierPct != null ? Math.round(tierPct * 100) : 70;
102
179
  }
103
180
 
104
181
  /**
@@ -119,13 +196,14 @@ export {
119
196
 
120
197
  /** Build the resolved config from env + defaults. */
121
198
  export function loadConfig(): MegaConfig {
122
- const { tier, thresholdTokens } = resolveThreshold();
199
+ const { tier, tierPct, thresholdTokens } = resolveThreshold();
123
200
  return {
124
201
  tier,
202
+ tierPct,
125
203
  // Global default; the live store/dashboard are rebound per-repo at runtime
126
204
  // via MegaRuntime.bindRepo() so each git repo gets its own isolated state dir.
127
205
  stateDir: process.env.MEGACOMPACT_STATE_DIR ?? STATE_DIR_DEFAULT,
128
- fastGatePct: envFlag("MEGACOMPACT_FAST_GATE_PCT", 70),
206
+ fastGatePct: resolveFastGatePct(tierPct),
129
207
  thresholdTokens,
130
208
  anchorUserMessages: envFlag("MEGACOMPACT_ANCHOR_USER_MESSAGES", 3),
131
209
  preserveRecent: envFlag("MEGACOMPACT_PRESERVE_RECENT", 4),
@@ -28,6 +28,12 @@ export interface DashboardSnapshot {
28
28
  config: {
29
29
  fastGatePct: number;
30
30
  thresholdTokens: number;
31
+ /** Compaction threshold as a fraction of the model context window (e.g.
32
+ * 0.70 for "high"); null for `custom` (absolute token threshold). */
33
+ tierPct: number | null;
34
+ /** Effective threshold as a % of the window (tierPct*100), or null for
35
+ * `custom`; reflects the live window when known. */
36
+ effectiveThresholdPct: number | null;
31
37
  anchorUserMessages: number;
32
38
  preserveRecent: number;
33
39
  auto: boolean;
@@ -54,6 +60,11 @@ export interface DashboardSnapshot {
54
60
  currentTokens: number | null;
55
61
  thresholdTokens: number;
56
62
  fastGatePct: number;
63
+ /** Compaction threshold as a fraction of the model context window; null
64
+ * for `custom`. */
65
+ tierPct: number | null;
66
+ /** Effective threshold as a % of the window; null for `custom`. */
67
+ effectiveThresholdPct: number | null;
57
68
  };
58
69
  store: {
59
70
  checkpointCount: number;