@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 +3 -4
- package/cached-summary.ts +1 -2
- package/dist/index.js +2 -7
- package/index.ts +1 -4
- package/package.json +1 -1
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.
|
|
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.
|
|
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
|
|
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,
|
|
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,
|
|
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;
|