@nijaru/pi-provider-compaction 0.0.11 → 0.0.12

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
@@ -39,15 +39,14 @@ The summary request extends the captured logical prompt, rather than serializing
39
39
  ```json
40
40
  {
41
41
  "providerCompaction": {
42
- "cachedSummaries": true,
43
- "outcomeNotifications": false
42
+ "cachedSummaries": true
44
43
  }
45
44
  }
46
45
  ```
47
46
 
48
47
  These are the defaults on hosts exposing Pi's `getSettings` API; older hosts retain native compaction with cached summaries disabled. Optional `cacheRetention` accepts `"short"`, `"long"`, or `"none"`; omission inherits Pi/provider behavior. Retention is applied per request, not through process-wide environment changes. A longer tier can increase cache-write charges and only works where the adapter/backend supports it.
49
48
 
50
- A cache hit is best effort, not a promised saving. Countdown estimates use the model's declared `promptCache` lifetime for the active tier, measured conservatively from request dispatch. Missing lifetimes remain unknown: DeepSeek, for example, [documents best-effort eviction over hours to days](https://api-docs.deepseek.com/guides/kv_cache/), not a predictable expiry. Pi's successful warmer requests refresh the observed cycle and countdown.
49
+ A cache hit is best effort, not a promised saving. Expiry estimates use the model's declared `promptCache` lifetime for the active tier, measured conservatively from request dispatch. Missing lifetimes remain unknown: DeepSeek, for example, [documents best-effort eviction over hours to days](https://api-docs.deepseek.com/guides/kv_cache/), not a predictable expiry. Pi's successful warmer requests refresh the observed cycle and estimated expiry.
51
50
 
52
51
  With [pi-compactor's opt-in idle expiry policy](https://github.com/nijaru/pi-compactor#cache-aware-idle-compaction), compaction can run before an estimated expiry. Both extensions share a live ownership/input guard, checked before paid summary and native-checkpoint stages regardless of extension order. A failed or revoked cached-only attempt cancels instead of starting an ordinary summary. It does not start a continuation.
53
52
 
@@ -77,7 +76,7 @@ Legacy v1/v2 whole-history checkpoints remain inspectable but are never reinterp
77
76
 
78
77
  ## Diagnose portable fallback
79
78
 
80
- Committed compaction entries retain the selected path, elapsed time, reported usage, and estimated cost. Optional outcome notifications show those measurements, not hypothetical savings. Portable fallback appends a `pi-provider-compaction:diagnostic` session entry with a fixed reason. Cancelled attempts with reported usage retain that usage in the same diagnostic record; without a saved checkpoint, Pi's extension API cannot include it in compaction totals. Diagnostics stay out of model context and never include request content, credentials, or backend error text.
79
+ Committed compaction entries retain the selected path, elapsed time, reported usage, and estimated cost. Portable fallback appends a `pi-provider-compaction:diagnostic` session entry with a fixed reason. Cancelled attempts with reported usage retain that usage in the same diagnostic record; without a saved checkpoint, Pi's extension API cannot include it in compaction totals. Diagnostics stay out of model context and never include request content, credentials, or backend error text.
81
80
 
82
81
  These records describe attempts made while the extension was loaded; they cannot explain earlier compactions retroactively. A committed native checkpoint does not by itself prove that a later request replayed it.
83
82
 
package/cached-summary.ts CHANGED
@@ -17,13 +17,12 @@ export interface CacheState {
17
17
  cachedTokens: number;
18
18
  inputTokens: number;
19
19
  }
20
- export interface CacheConfig { cachedSummaries: boolean; cacheRetention?: CacheRetention; outcomeNotifications: boolean }
20
+ export interface CacheConfig { cachedSummaries: boolean; cacheRetention?: CacheRetention }
21
21
  export function cacheConfig(settings: unknown): CacheConfig {
22
22
  const raw = isObject(settings) && isObject(settings.providerCompaction) ? settings.providerCompaction : {};
23
23
  return {
24
24
  cachedSummaries: raw.cachedSummaries !== false,
25
25
  cacheRetention: raw.cacheRetention === "long" || raw.cacheRetention === "short" || raw.cacheRetention === "none" ? raw.cacheRetention : undefined,
26
- outcomeNotifications: raw.outcomeNotifications === true,
27
26
  };
28
27
  }
29
28
  export function supportsCachedSummary(model: Model<any> | undefined): boolean {
package/dist/index.js CHANGED
@@ -1591,8 +1591,7 @@ function cacheConfig(settings) {
1591
1591
  const raw = isObject(settings) && isObject(settings.providerCompaction) ? settings.providerCompaction : {};
1592
1592
  return {
1593
1593
  cachedSummaries: raw.cachedSummaries !== false,
1594
- cacheRetention: raw.cacheRetention === "long" || raw.cacheRetention === "short" || raw.cacheRetention === "none" ? raw.cacheRetention : undefined,
1595
- outcomeNotifications: raw.outcomeNotifications === true
1594
+ cacheRetention: raw.cacheRetention === "long" || raw.cacheRetention === "short" || raw.cacheRetention === "none" ? raw.cacheRetention : undefined
1596
1595
  };
1597
1596
  }
1598
1597
  function supportsCachedSummary(model) {
@@ -2257,7 +2256,7 @@ function supportedRouteOptions(model, options) {
2257
2256
  return !["AZURE_OPENAI_BASE_URL", "AZURE_OPENAI_RESOURCE_NAME", "AZURE_OPENAI_API_VERSION", "AZURE_OPENAI_DEPLOYMENT_NAME_MAP"].some((key) => process.env[key] !== undefined && options.env?.[key] === undefined);
2258
2257
  }
2259
2258
  function pi_provider_compaction_default(pi) {
2260
- const configuration = () => typeof pi.getSettings === "function" ? cacheConfig(pi.getSettings()) : { cachedSummaries: false, outcomeNotifications: false, cacheRetention: undefined };
2259
+ const configuration = () => typeof pi.getSettings === "function" ? cacheConfig(pi.getSettings()) : { cachedSummaries: false, cacheRetention: undefined };
2261
2260
  const secret = randomBytes(32);
2262
2261
  const routeDigest = (value) => createHmac("sha256", secret).update(JSON.stringify(value)).digest("hex");
2263
2262
  let runtimeId = randomUUID2();
@@ -2705,10 +2704,6 @@ function pi_provider_compaction_default(pi) {
2705
2704
  const owned = isObject(recorded) && equal(recorded, lastOutcome);
2706
2705
  if (!owned && !fallbackReason && readNativeCompactionDetails(event.compactionEntry.details)?.version !== 3)
2707
2706
  fallback("another handler supplied the committed result");
2708
- if (owned) {
2709
- if (configuration().outcomeNotifications && lastOutcome)
2710
- context.ui.notify(`Compacted via ${lastOutcome.path} in ${(lastOutcome.elapsedMs / 1000).toFixed(1)}s${lastOutcome.usage ? `; cache read ${lastOutcome.usage.cacheRead}, write ${lastOutcome.usage.cacheWrite}; estimated cost $${lastOutcome.usage.cost.total.toFixed(6)}` : ""}`, "info");
2711
- }
2712
2707
  if (fallbackReason)
2713
2708
  pi.appendEntry("pi-provider-compaction:diagnostic", { status: `portable: ${fallbackReason}` });
2714
2709
  active = undefined;
package/index.ts CHANGED
@@ -157,7 +157,7 @@ export default function (pi: ExtensionAPI): void {
157
157
  // hook/privacy policy, even if the visible summary text happens to match.
158
158
  // Older hosts in the native adapter's supported range lack getSettings.
159
159
  // Keep their existing native path; cache preferences require that host API.
160
- const configuration = () => typeof pi.getSettings === "function" ? cacheConfig(pi.getSettings()) : { cachedSummaries: false, outcomeNotifications: false, cacheRetention: undefined };
160
+ const configuration = () => typeof pi.getSettings === "function" ? cacheConfig(pi.getSettings()) : { cachedSummaries: false, cacheRetention: undefined };
161
161
  const secret = randomBytes(32);
162
162
  const routeDigest = (value: unknown) => createHmac("sha256", secret).update(JSON.stringify(value)).digest("hex");
163
163
  let runtimeId = randomUUID();
@@ -493,9 +493,6 @@ export default function (pi: ExtensionAPI): void {
493
493
  const recorded = isObject(event.compactionEntry.details) ? event.compactionEntry.details.providerCompaction : undefined;
494
494
  const owned = isObject(recorded) && equal(recorded, lastOutcome);
495
495
  if (!owned && !fallbackReason && readNativeCompactionDetails(event.compactionEntry.details)?.version !== 3) fallback("another handler supplied the committed result");
496
- if (owned) {
497
- if (configuration().outcomeNotifications && lastOutcome) context.ui.notify(`Compacted via ${lastOutcome.path} in ${(lastOutcome.elapsedMs / 1000).toFixed(1)}s${lastOutcome.usage ? `; cache read ${lastOutcome.usage.cacheRead}, write ${lastOutcome.usage.cacheWrite}; estimated cost $${lastOutcome.usage.cost.total.toFixed(6)}` : ""}`, "info");
498
- }
499
496
  // Only static diagnostics are persisted, never request/auth data or error text.
500
497
  if (fallbackReason) pi.appendEntry("pi-provider-compaction:diagnostic", { status: `portable: ${fallbackReason}` });
501
498
  active = undefined; snapshot = undefined; cache = undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nijaru/pi-provider-compaction",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "type": "module",
5
5
  "description": "Provider-native context compaction adapters for Pi",
6
6
  "keywords": [