pi-fold 1.0.4 → 3.0.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.
@@ -18,29 +18,17 @@
18
18
  export interface RollbackProbe {
19
19
  name: string;
20
20
  present: boolean;
21
- /** Null when the surface carries no arity contract. */
22
21
  arity: number | null;
23
22
  expectedArity: number | null;
24
- /** A surface the lane cannot run without. */
25
23
  required: boolean;
26
24
  }
27
25
 
28
26
  export interface RollbackProbeReport {
29
27
  probes: RollbackProbe[];
30
28
  failures: string[];
31
- /** Every REQUIRED surface answered. */
32
29
  armed: boolean;
33
30
  }
34
31
 
35
- /**
36
- * The session-manager surfaces the lane calls, and the arities it calls them with.
37
- *
38
- * `branch` and `resetLeaf` are the rollback itself; `appendLabelChange` is the lineage
39
- * marker, and it must run BEFORE the branch because it appends at the current leaf and
40
- * advances it, so a label applied afterwards lands on the surviving path instead of the
41
- * abandoned one. The readers are required because the lane cannot locate the error
42
- * entry without them.
43
- */
44
32
  const SESSION_MANAGER_PROBES: ReadonlyArray<{ name: string; arity: number | null; required: boolean }> = Object.freeze([
45
33
  { name: "branch", arity: 1, required: true },
46
34
  { name: "resetLeaf", arity: 0, required: true },
@@ -70,10 +58,6 @@ export function probeRollbackSurfaces(sessionManager: unknown): RollbackProbeRep
70
58
  if (expected.required) failures.push(`sessionManager.${expected.name} is missing`);
71
59
  continue;
72
60
  }
73
- // Arity is advisory on purpose: a host that adds an optional parameter has not
74
- // broken the call, and refusing to arm over it would be a false alarm. A MISSING
75
- // parameter has broken it, so the probe fails only when the surface takes fewer
76
- // arguments than the lane passes.
77
61
  if (expected.arity !== null && arity !== null && arity < expected.arity && expected.required) {
78
62
  failures.push(`sessionManager.${expected.name} takes ${arity} argument(s), the lane passes ${expected.arity}`);
79
63
  }
@@ -81,7 +65,6 @@ export function probeRollbackSurfaces(sessionManager: unknown): RollbackProbeRep
81
65
  return { probes, failures, armed: failures.length === 0 };
82
66
  }
83
67
 
84
- /** The keys `_runAutoCompaction` puts on the overflow event, and the lane reads. */
85
68
  const OVERFLOW_EVENT_KEYS: ReadonlyArray<string> = Object.freeze([
86
69
  "reason", "willRetry", "branchEntries", "signal",
87
70
  ]);
@@ -104,16 +87,6 @@ function entryMessage(entry: unknown): Record<string, unknown> | null {
104
87
  return message && typeof message === "object" ? message as Record<string, unknown> : null;
105
88
  }
106
89
 
107
- /**
108
- * The entry the provider rejected: the trailing assistant message whose stop reason is
109
- * the error pi turned the rejection into.
110
- *
111
- * It must be the last MESSAGE on the branch. Custom entries after it are telemetry --
112
- * this runtime's own event stream appends there -- and they go with the rollback, which
113
- * is what should happen to records of a request that never landed. A later CONVERSATION
114
- * entry is a different story: something else already moved the leaf, and rolling back to
115
- * this entry's parent would abandon work the lane never looked at.
116
- */
117
90
  export function findOverflowErrorEntry(branchEntries: unknown[]): {
118
91
  id: string;
119
92
  parentId: string | null;
@@ -139,14 +112,6 @@ function contentParts(message: Record<string, unknown>): Record<string, unknown>
139
112
  Boolean(part) && typeof part === "object");
140
113
  }
141
114
 
142
- /**
143
- * Tool calls the rolled-back tail leaves unanswered.
144
- *
145
- * Possible only when a run died between persisting an assistant tool-call message and
146
- * persisting its results. A queued user turn after an unsatisfied tool call is a
147
- * malformed transcript for every provider, so this is the one shape where the rollback
148
- * happens and the replay does not.
149
- */
150
115
  export function unansweredToolCalls(branchEntries: unknown[]): string[] {
151
116
  if (!Array.isArray(branchEntries) || !branchEntries.length) return [];
152
117
  const answered = new Set<string>();
@@ -169,17 +134,6 @@ export function unansweredToolCalls(branchEntries: unknown[]): string[] {
169
134
  return pending.filter((id) => !answered.has(id));
170
135
  }
171
136
 
172
- /**
173
- * The invariant the whole lane rests on, stated as arithmetic.
174
- *
175
- * pi strips the trailing error message from `agent.state.messages` before it emits the
176
- * overflow event, so at the recovery point agent state already equals the rolled-back
177
- * branch, and moving the session leaf is the only step left. That equality is an
178
- * ordering of two internal steps rather than a promise, so it is measured instead of
179
- * assumed: the rebuilt session context must come back exactly the error entry's own
180
- * contribution shorter, no more and no less. More means the branch overshot; less means
181
- * it did not move, and either way the retry would send a window nobody built.
182
- */
183
137
  export function preStripHolds(input: {
184
138
  sessionMessagesBefore: number;
185
139
  sessionMessagesAfter: number;
@@ -188,13 +142,6 @@ export function preStripHolds(input: {
188
142
  return input.sessionMessagesAfter === input.sessionMessagesBefore - input.errorEntryMessages;
189
143
  }
190
144
 
191
- /**
192
- * The notice the agent reads on the retried turn.
193
- *
194
- * One message, because pi drains steering one at a time. It says the three things the
195
- * agent cannot see for itself: the request was rejected for size, the session rolled
196
- * back and folded, and its work continues from where it was.
197
- */
198
145
  export function rollbackNoticeText(input: {
199
146
  brandNoun: string;
200
147
  toolName: string;