pi-zip 0.2.1 → 0.2.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-zip",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Keeps long Pi sessions cheap without losing anything: folds old tool output only when the prompt cache has already gone cold, and every fold can be recalled byte for byte. Zero config.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/plan.ts CHANGED
@@ -282,6 +282,7 @@ export interface PlanOpts {
282
282
  relax?: boolean; // default RELAX_PREV_TURN
283
283
  minGain?: number;
284
284
  inturnAge?: number; // default settings().inturnAge (PI_ZIP_INTURN_AGE, 60); 0 = outputs of the protected turns never fold on age
285
+ noSummary?: boolean; // a summary was already made while this cache stayed warm: no second one unless the context is at/above the compaction room
285
286
  rereadOnly?: boolean; // zip_recall is not available to the model: fold only outputs that can be re-read (classify "rereadable")
286
287
  pastTtl?: boolean; // a user return after the declared TTL: a warm plan may relax into the previous user turn too (RELAX_PREV_TURN)
287
288
  }
@@ -417,7 +418,13 @@ export function planContext(entries: Any[], o: PlanOpts): PlanResult | null {
417
418
  }
418
419
  }
419
420
  let ctxAfterFolds = ctxEst - savings();
420
- const sumTrigger: "cold" | "valve" | null = ctxAfterFolds > coldCap ? trig : null;
421
+ // what no summary can remove: the system prompt, the protected turns (after their folds) and the previous summary, which the next
422
+ // one carries forward; the cap is never chased below it (a context that is mostly this floor would be re-summarised for nothing)
423
+ const prevSum = blocks[0]?.kind === "summary" ? blocks[0].tokens : 0;
424
+ const floor = o.sys + prevSum + blocks.reduce((a, b) => a + (protectedTurn(b) ? (tokOverride.get(b.idx) ?? b.tokens) : 0), 0);
425
+ const target = Math.max(coldCap, floor + SUMMARY_FLOOR);
426
+ const atRoom = room !== null && k * ctxAfterFolds >= room;
427
+ const sumTrigger: "cold" | "valve" | null = ctxAfterFolds > target && (!o.noSummary || atRoom) ? trig : null;
421
428
  let cutIdx: number | null = null;
422
429
  let prefixTokens = 0;
423
430
  let summaryTokensPlanned = 0;
@@ -436,7 +443,7 @@ export function planContext(entries: Any[], o: PlanOpts): PlanResult | null {
436
443
  acc += tokOverride.get(i) ?? blocks[i].tokens;
437
444
  }
438
445
  const total = o.sys + acc;
439
- const S = (x: number) => clamp(SUMMARY_RATIO * x, SUMMARY_FLOOR, SUMMARY_CAP);
446
+ const S = (x: number) => Math.max(clamp(SUMMARY_RATIO * x, SUMMARY_FLOOR, SUMMARY_CAP), prevSum); // the next summary carries the previous one forward
440
447
  if (cuts.length) {
441
448
  let pick = cuts[cuts.length - 1];
442
449
  for (const c of cuts) if (total - pre[c] + S(pre[c]) <= coldCap) { pick = c; break; }
package/src/run.ts CHANGED
@@ -94,6 +94,8 @@ export class Zip implements ZipControl {
94
94
 
95
95
  /** zip_recall declared to the model? Checked at session start and before every run (index.ts); a `--tools` allowlist hides it. */
96
96
  recallOk = true;
97
+ /** A summary was persisted since the last cold run start: later warm plans make none unless at the compaction room. */
98
+ summarizedWarm = false;
97
99
  setRecallOk(ok: boolean) {
98
100
  if (ok !== this.recallOk) this.ledger({ type: "recall_available", ok });
99
101
  this.recallOk = ok;
@@ -146,7 +148,7 @@ export class Zip implements ZipControl {
146
148
  private opts(ctx: Any, pending: boolean, mode: "cold" | "warm", entries: Any[], pWarm = mode === "cold" ? 0 : 1): { o: PlanOpts; cal: Calibration } {
147
149
  const sys = this.sysTokens(ctx);
148
150
  const cal = calibrate(entries, sys);
149
- return { cal, o: { mode, sys, k: cal.k, cwd: (ctx?.cwd as string) ?? process.cwd(), recalled: this.recalled, model: ctx?.model, promptPending: pending, rereadOnly: !this.recallOk, reserve: this.reserve(ctx), steerIds: this.steerIds, law: this.law(ctx, pWarm), trace: [] } };
151
+ return { cal, o: { mode, sys, k: cal.k, cwd: (ctx?.cwd as string) ?? process.cwd(), recalled: this.recalled, model: ctx?.model, promptPending: pending, rereadOnly: !this.recallOk, noSummary: mode === "warm" && this.summarizedWarm, reserve: this.reserve(ctx), steerIds: this.steerIds, law: this.law(ctx, pWarm), trace: [] } };
150
152
  }
151
153
 
152
154
  private law(ctx: Any, pWarm: number): Law {
@@ -234,6 +236,7 @@ export class Zip implements ZipControl {
234
236
  if (!this.prevKey) ({ key: this.prevKey, total: this.prevTotal } = lastPrompt(branch)); // fresh process: the session's newest response
235
237
  const { cold, reason, ttl, pWarm: p, src, gapS, pastTtl } = detectCold(ctx.model, this.lastReqMs, branch, Date.now(), this.lastModelKey, (g, prior) => pWarm(this.ent, g, prior));
236
238
  this.cold = cold;
239
+ if (cold) this.summarizedWarm = false; // a cold return may summarise again
237
240
  this.pastTtl = pastTtl;
238
241
  this.pWarm = p;
239
242
  this.survSrc = src;
@@ -512,6 +515,7 @@ export class Zip implements ZipControl {
512
515
  return undefined;
513
516
  }
514
517
  const bad = checkEdits(o.blocks, o.userTurns, live, cut);
518
+ if (!bad && cut) this.summarizedWarm = true; // one summary per warm stretch (two in a row cost two uncached calls; the second gains little)
515
519
  if (bad) {
516
520
  this.ledger({ type: "guard_drop", turnIndex: e.turnIndex, reason: bad, folds: live.length, source: plan.source });
517
521
  plan.persisted = false; // keep the request-local view: never switch the fold set mid-run