@namzu/sdk 42.0.0 → 42.0.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/dist/manager/resident/outbox.d.ts +8 -8
  3. package/dist/manager/resident/store.d.ts +4 -4
  4. package/dist/runtime/query/cancelled-before-start.d.ts +34 -0
  5. package/dist/runtime/query/cancelled-before-start.d.ts.map +1 -0
  6. package/dist/runtime/query/cancelled-before-start.js +152 -0
  7. package/dist/runtime/query/cancelled-before-start.js.map +1 -0
  8. package/dist/runtime/query/checkpoint.d.ts +21 -0
  9. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  10. package/dist/runtime/query/checkpoint.js +23 -0
  11. package/dist/runtime/query/checkpoint.js.map +1 -1
  12. package/dist/runtime/query/executor/tool-call-admission.d.ts +57 -0
  13. package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -0
  14. package/dist/runtime/query/executor/tool-call-admission.js +373 -0
  15. package/dist/runtime/query/executor/tool-call-admission.js.map +1 -0
  16. package/dist/runtime/query/executor.d.ts +70 -35
  17. package/dist/runtime/query/executor.d.ts.map +1 -1
  18. package/dist/runtime/query/executor.js +46 -380
  19. package/dist/runtime/query/executor.js.map +1 -1
  20. package/dist/runtime/query/finalize-run.d.ts +55 -0
  21. package/dist/runtime/query/finalize-run.d.ts.map +1 -0
  22. package/dist/runtime/query/finalize-run.js +113 -0
  23. package/dist/runtime/query/finalize-run.js.map +1 -0
  24. package/dist/runtime/query/index.d.ts +4 -9
  25. package/dist/runtime/query/index.d.ts.map +1 -1
  26. package/dist/runtime/query/index.js +238 -893
  27. package/dist/runtime/query/index.js.map +1 -1
  28. package/dist/runtime/query/iteration/index.d.ts +6 -161
  29. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  30. package/dist/runtime/query/iteration/index.js +23 -523
  31. package/dist/runtime/query/iteration/index.js.map +1 -1
  32. package/dist/runtime/query/iteration/outstanding-work.d.ts +158 -0
  33. package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -0
  34. package/dist/runtime/query/iteration/outstanding-work.js +365 -0
  35. package/dist/runtime/query/iteration/outstanding-work.js.map +1 -0
  36. package/dist/runtime/query/iteration/phases/plan.d.ts.map +1 -1
  37. package/dist/runtime/query/iteration/phases/plan.js +13 -2
  38. package/dist/runtime/query/iteration/phases/plan.js.map +1 -1
  39. package/dist/runtime/query/iteration/step-shaping.d.ts +41 -0
  40. package/dist/runtime/query/iteration/step-shaping.d.ts.map +1 -0
  41. package/dist/runtime/query/iteration/step-shaping.js +184 -0
  42. package/dist/runtime/query/iteration/step-shaping.js.map +1 -0
  43. package/dist/runtime/query/prepare-run.d.ts +94 -0
  44. package/dist/runtime/query/prepare-run.d.ts.map +1 -0
  45. package/dist/runtime/query/prepare-run.js +589 -0
  46. package/dist/runtime/query/prepare-run.js.map +1 -0
  47. package/dist/runtime/query/release-run.d.ts +56 -0
  48. package/dist/runtime/query/release-run.d.ts.map +1 -0
  49. package/dist/runtime/query/release-run.js +101 -0
  50. package/dist/runtime/query/release-run.js.map +1 -0
  51. package/dist/runtime/query/resume-pending.d.ts +112 -1
  52. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  53. package/dist/runtime/query/resume-pending.js +133 -0
  54. package/dist/runtime/query/resume-pending.js.map +1 -1
  55. package/dist/store/evidence/compaction-archive.d.ts +2 -2
  56. package/dist/types/run/config.d.ts +12 -5
  57. package/dist/types/run/config.d.ts.map +1 -1
  58. package/package.json +4 -4
  59. package/src/runtime/query/cancelled-before-start.ts +189 -0
  60. package/src/runtime/query/checkpoint.ts +22 -0
  61. package/src/runtime/query/executor/tool-call-admission.ts +473 -0
  62. package/src/runtime/query/executor.ts +63 -442
  63. package/src/runtime/query/finalize-run.ts +192 -0
  64. package/src/runtime/query/index.ts +270 -1011
  65. package/src/runtime/query/iteration/index.ts +40 -586
  66. package/src/runtime/query/iteration/outstanding-work.ts +386 -0
  67. package/src/runtime/query/iteration/phases/plan.ts +18 -2
  68. package/src/runtime/query/iteration/step-shaping.ts +271 -0
  69. package/src/runtime/query/prepare-run.ts +718 -0
  70. package/src/runtime/query/release-run.ts +168 -0
  71. package/src/runtime/query/resume-pending.ts +158 -0
  72. package/src/types/run/config.ts +12 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,227 @@
1
1
  # Changelog
2
2
 
3
+ ## 42.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 175dab2: Nothing a consumer installs changes. These are devDependencies and toolchain
8
+ pins: no runtime dependency, export, type or default moved, and the published
9
+ surface is identical.
10
+
11
+ Four advisories, all dev-time, closed by moving the package that carried them
12
+ rather than by patching around them:
13
+
14
+ - `knip` `^6.4.1` → `^6.37.0`, which carries `smol-toml` ≥ 1.8.0 — the version
15
+ that fixes `GHSA-7w5x-hrqm-74c2` (a malformed-TOML denial of service).
16
+ - `tsx` `^4.19.0` → `^4.23.13`, which depends on `esbuild ~0.28.0`, fixing
17
+ `GHSA-g7r4-m6w7-qqqr` (arbitrary file read from the development server, and
18
+ only on Windows) — and collapsing two `esbuild` copies in the tree into one.
19
+ - `js-yaml`, twice, fixed by a workspace override rather than a parent upgrade,
20
+ because both copies arrive deep inside the Changesets CLI's own tree:
21
+ `^3.15.2` for the 3.x line and `^4.3.2` for the 4.x line, closing
22
+ `GHSA-2883-xcg3-v3hh` (a merge-key CPU exhaustion). Neither override widens
23
+ beyond what the parent already declared — `3.15.2` satisfies `^3.13.1` and
24
+ `4.3.2` satisfies `^4.1.0` — so no package is forced outside its range.
25
+
26
+ - 8d5223b: Nothing a consumer installs or calls changes, and that is the whole of this
27
+ release. `vitest` moves from `^3.2.6` to `^4.1.11` in the `devDependencies` of
28
+ all nineteen packages that declared it, and `@vitest/coverage-v8` moves with it
29
+ in `@namzu/sdk`. Every occurrence is a devDependency — checked, not assumed —
30
+ so `dependencies`, `peerDependencies`, exports, types, defaults and the wire
31
+ shape are untouched, and the published tarballs differ from the previous
32
+ release only in `package.json#devDependencies`.
33
+
34
+ The reason is a security fix with no 3.x backport. `GHSA-82fw-gwwq-j7x9`
35
+ ("Path Traversal / Arbitrary File Read via `@vitest/mocker` Redirect Mock")
36
+ covers `vitest` and `@vitest/mocker` from `2.1.0` up to `4.1.11`, so `^3.2.6`
37
+ can only be resolved by leaving the 3.x line. `4.1.11` is the first patched
38
+ release and is what the lockfile now resolves for both.
39
+
40
+ What this costs anyone who works on the repository rather than with it: the
41
+ upgrade was not a version bump. Vitest 4 changed test discovery, coverage
42
+ configuration, mock construction and reporter output, and each of those broke
43
+ something here that had to be migrated rather than worked around. Those fixes
44
+ are all under `__tests__/`, `vitest.config.ts` files and `scripts/`, none of
45
+ which is published, which is why this is a patch and not a major.
46
+
47
+ You do not need to do anything. If you pin `vitest` yourself to run this
48
+ project's own suites, note that the config files it ships are now written for
49
+ `>= 4.1.11` and will not run under 3.x.
50
+
51
+ ## 42.0.1
52
+
53
+ ### Patch Changes
54
+
55
+ - 325cc6a: Internal module layout only. `query()`'s prelude, its pre-start cancellation
56
+ path, its post-loop settlement and its cleanup, the iteration loop's
57
+ outstanding-work and step-shaping helpers, and the executor's tool-call
58
+ admission family now live in their own modules —
59
+ `runtime/query/prepare-run.ts`, `runtime/query/cancelled-before-start.ts`,
60
+ `runtime/query/finalize-run.ts`, `runtime/query/release-run.ts`,
61
+ `runtime/query/iteration/outstanding-work.ts`,
62
+ `runtime/query/iteration/step-shaping.ts` and
63
+ `runtime/query/executor/tool-call-admission.ts` — instead of inside
64
+ `index.ts`, `iteration/index.ts` and `executor.ts`.
65
+
66
+ Nothing a consumer observes changes, so taking the upgrade requires no code
67
+ change: no export is added, removed or renamed; the `RunEvent` stream carries
68
+ the same events in the same order; and budget, checkpoint, HITL and run
69
+ lifecycle semantics are untouched. The one shared module surface that moved
70
+ is the settle-grace policy (`settleGraceMs` / `awaitedJobGraceMs`'s home —
71
+ re-exported from `iteration/index.ts`, so its importers are unaffected).
72
+
73
+ - d77fbc2: Four defects in query orchestration, all `patch`. Two change observable
74
+ behaviour; two do not, and none of the four adds an export, removes one,
75
+ narrows a union or changes a default.
76
+
77
+ **A Stop now takes effect while a run is parked on plan approval.** The plan
78
+ gate awaited the host's `resumeHandler` directly, where the tool-review and
79
+ iteration-checkpoint parks race it against the run's abort signal, so a run
80
+ parked on plan approval ignored a Stop until the host answered — and the plan
81
+ gate runs in the iteration loop rather than inside a tool call, so nothing
82
+ bounded the wait. A Stop now resolves that park as an `abort` decision, which
83
+ settles the run as `cancelled` with `stopReason: 'cancelled'`, the same
84
+ resolution the other two parks have produced since the abort race was added to
85
+ them.
86
+
87
+ This is `patch` and not `minor` deliberately, so the reasoning is on the
88
+ record rather than implied: a host that was relying on the old behaviour was
89
+ relying on a hang, which is exactly the defect the abort race was introduced
90
+ to remove from the other two parks, and nothing about the parked state
91
+ changes shape — same `HITLDecisionRequest`, same `CheckpointId`, same
92
+ `HITLResumeDecision` union, and a `stopReason` that already existed. A parked
93
+ plan is still recorded durably before the await, and the Stop RESOLVES that
94
+ row as `{action: 'abort'}` — so `findPendingCheckpoint` stops serving the
95
+ plan, the run reads `cancelled`, and the park survives only as a resolved row
96
+ in `listCheckpoints`, carrying the request and the `abort` that ended it. A
97
+ host that needs the question to stay open must therefore park the decision
98
+ itself before calling `query()` and answer from its own queue, which is the
99
+ same posture this asks of a host on the other two parks.
100
+
101
+ **An abandoned run's record is terminal — unless a human is still being
102
+ asked.** A host that leaves the stream early — `for await (… ) break`, or
103
+ `gen.return()` — ran the run's teardown and stopped short of `finalize()`.
104
+ Since `finalize()` is the only caller of `RunPersistence.persist()`, the
105
+ durable record was whatever `init()` wrote, which is not a terminal state:
106
+ `deriveRunStatus` read it back as `queued`, work waiting to start, for a run
107
+ whose jobs were killed and whose sandbox was destroyed. Such a run is now
108
+ recorded `cancelled`. There is no new `RunExecutionStatus`, no new
109
+ `StopReason` and no new event — there is no consumer left to emit one to, and
110
+ the run did not fail, so `failed` would name an error that never happened.
111
+
112
+ A run whose consumer left while a park was OUTSTANDING is the exception, and
113
+ deliberately so: a park is a promise to a human, that run is resumable, and
114
+ `deriveRunStatus` reads a terminal status before it reads the park — so
115
+ writing `cancelled` there would have turned `awaiting_hitl` into `cancelled`
116
+ for a run somebody still owes an answer. The durable state decides, not the
117
+ in-memory state, because `handleHITLDecision` emits `run_paused` and drains it
118
+ BEFORE it sets its stop reason: a consumer that leaves on that event leaves a
119
+ run whose status is `running` and whose stop reason is unset at the instant
120
+ its park is already durable. Such a run is left exactly as it stands — no
121
+ verdict and no write, since the park row is its durable state — and a host
122
+ clears it by answering the park or by `expire`-ing an expired one.
123
+
124
+ What is durable here is the STATUS: measured against a real `RunDiskStore`,
125
+ `run.json` goes from `status: 'idle'` to `status: 'cancelled'` with an
126
+ `endedAt` for the mid-flight case, and stays non-terminal for the parked one.
127
+ `run.json` carries neither `stopReason` nor `result` for any run today, so the
128
+ `stopReason: 'cancelled'` that `markCancelled()` sets in memory is not written
129
+ there either: that is a separate defect, fixed separately, and nothing in this
130
+ change depends on it.
131
+
132
+ **A park answered by a resumed run is resolved, for the plan arm too.** The
133
+ resume path resolves the park its decision answers; the set of park/decision
134
+ pairs it covered named one park per condition, and the `plan_approval` arm was
135
+ missing — a run resumed with `{action: 'approve_plan'}` COMPLETED with its
136
+ park still outstanding, so a host was told a human still owed it an answer, a
137
+ second resume of the finished run was refused `awaiting-decision`, and with no
138
+ `hitlParkTtlMs` no `deadlineAt` existed either, leaving the row beyond
139
+ `expire` and beyond prune. Both plan verdicts now answer the park, through one
140
+ map from park type to answering decision so an arm cannot go missing by being
141
+ absent from a condition again. Resolving it does not depend on the resumed
142
+ process being able to act on it: nothing restores a plan on the resume path,
143
+ which is its own defect, and gating this on it would leave the row outstanding
144
+ for exactly the runs that need it cleared.
145
+
146
+ **Pruning no longer deletes a checkpoint a host is still waiting on.** With
147
+ `runConfig.pruneKeepLast` set, `CheckpointManager.prune` deleted the oldest
148
+ checkpoints by `createdAt` with no test for an unresolved park, while
149
+ `findPendingCheckpoint` and `listExpiredParks` in the same file treat one as
150
+ the thing a host is waiting on. A checkpoint carrying an unanswered question
151
+ is the row an approval queue serves, and collecting it deleted the question.
152
+ Prune still keeps the newest `keepLast` — the run's resume point is never at
153
+ risk — and now skips any candidate whose park is unresolved, so pruning
154
+ briefly holds a few more rows while a park is outstanding. A host that never
155
+ sets `pruneKeepLast` is unaffected entirely: that gate still means "never
156
+ prune". Expired parks are skipped too; the sweep for those is `expire`, which
157
+ resolves the park and keeps the record.
158
+
159
+ **The `executeBatch` docblock no longer claims a guarantee the throwing path
160
+ does not provide.** It said every `tool_use` is answered "by construction".
161
+ That holds for every path that returns — denials, approvals, a rejected
162
+ batch, a partial failure the fill-the-holes loop closes — and not for a call
163
+ that throws: `serial = serial.then(run)` means one rejection skips every
164
+ later serial call, so `Promise.all` rejects, the fill-the-holes loop never
165
+ runs, the batch produces no messages at all and the assistant turn keeps its
166
+ `tool_use` blocks unanswered for a resume to repair. The comment now says so.
167
+ No behaviour changed here; the guarantee was never provided on that path and
168
+ the run-level outcome is unchanged.
169
+
170
+ **One test that measured the machine instead of the code is de-flaked, with
171
+ no behaviour change at all.** `the-window-is-asked-once.test.ts`'s "falls
172
+ back and runs when metadata stays pending" drove a run with `timeoutMs: 20`
173
+ — which is simultaneously the run's budget and the context-window resolver's
174
+ private deadline — and then asserted that the run settled inside a 1000 ms
175
+ poll. The two 20 ms deadlines raced on a real clock: the run's own seam
176
+ checks could see the budget already spent by the very wait the deadline
177
+ exists to end, so the case failed in BOTH directions — no model request at
178
+ all, and a second one after the stream was cut — in three of five full-suite
179
+ runs, while passing every time on its own. It now runs under a fake clock
180
+ advanced exactly once, by exactly the deadline, and reads the resolver's
181
+ aborted signal before it waits on anything. The assertions are the same
182
+ ones, and none of them rests on a wall clock.
183
+
184
+ **Two more park defects, fixed on the same branch the same day, so this
185
+ changeset covers SIX fixes and all six are `patch` for the same reasons.**
186
+ The four above are the ones the branch opened with; these are the two the
187
+ tests that pinned them reported.
188
+
189
+ **An answered park is now resolved when the answer arrives across a
190
+ restart.** A run that paused at an iteration checkpoint, was resumed with
191
+ `{action: 'continue'}` and then COMPLETED kept the park outstanding on the
192
+ record forever: `planPendingResume` applies a decision only to a
193
+ `tool_review` or `user_question` park — an `iteration_checkpoint` park leaves
194
+ no unanswered tool call for a decision to reach — so the unpark never ran for
195
+ it. That was observable through two exports. `findPendingCheckpoint` (and
196
+ `CheckpointManager.findPending()`) kept returning a question nobody was
197
+ waiting on, and a second `resumeRun` of the finished run was refused with
198
+ `reason: 'awaiting-decision'` for a decision already taken. With
199
+ `runConfig.pruneKeepLast` set there was a third consequence, and it was the
200
+ worst one: `prune` skips an unresolved park, so the row could no longer be
201
+ collected by anything. Such a park is now resolved the way every other arm
202
+ resolves one — the record stays, the request stays on it, and only its
203
+ `pending` state ends. A `pause` is still not an answer: it holds the park, so
204
+ a resume that answers `pause` leaves it standing, exactly as the live path
205
+ does.
206
+
207
+ **A park whose batch crash recovery answered no longer records the human's
208
+ decision as its answer.** When the parked call's outcome could not be
209
+ established, recovery answered the batch with explicitly unknown outcomes and
210
+ the park was still written down as decided by whatever the human had said —
211
+ `{action: 'continue'}` on a park whose calls were never executed and never
212
+ approved. It is resolved either way, because leaving it outstanding would let
213
+ `findPendingCheckpoint` serve it as the newest park and a resume would then
214
+ rewind the run to the checkpoint the crash happened on. What changed is what
215
+ the record SAYS: it now carries `{action: 'pause'}` with a reason naming what
216
+ ended it, which is the shape `CheckpointManager.expire` already uses for "this
217
+ park ended and no decision was carried out" — `abort` was rejected there for
218
+ reading as somebody having refused it, and the same holds here. A consumer
219
+ that reads `pending.decision` as the audit of who approved what sees the
220
+ difference, so it is stated: a `pause` with a reason about crash recovery
221
+ means the answer you gave was recorded on the park but not applied by it. The
222
+ action the human took is still named in that reason. No export was added or
223
+ removed, no union widened or narrowed, no default changed.
224
+
3
225
  ## 42.0.0
4
226
 
5
227
  ### Major Changes
@@ -42,10 +42,10 @@ export declare const residentOutboxMessageSchema: z.ZodEffects<z.ZodObject<{
42
42
  }, "strip", z.ZodTypeAny, {
43
43
  id: string;
44
44
  phase: "pending" | "cancelled" | "sending" | "acknowledged";
45
- revision: number;
46
- attempts: number;
47
45
  tenantId: string;
48
46
  body: string;
47
+ revision: number;
48
+ attempts: number;
49
49
  agentKey: string;
50
50
  pursuitId: string;
51
51
  claimId: string | null;
@@ -59,10 +59,10 @@ export declare const residentOutboxMessageSchema: z.ZodEffects<z.ZodObject<{
59
59
  }, {
60
60
  id: string;
61
61
  phase: "pending" | "cancelled" | "sending" | "acknowledged";
62
- revision: number;
63
- attempts: number;
64
62
  tenantId: string;
65
63
  body: string;
64
+ revision: number;
65
+ attempts: number;
66
66
  agentKey: string;
67
67
  pursuitId: string;
68
68
  claimId: string | null;
@@ -76,10 +76,10 @@ export declare const residentOutboxMessageSchema: z.ZodEffects<z.ZodObject<{
76
76
  }>, {
77
77
  id: string;
78
78
  phase: "pending" | "cancelled" | "sending" | "acknowledged";
79
- revision: number;
80
- attempts: number;
81
79
  tenantId: string;
82
80
  body: string;
81
+ revision: number;
82
+ attempts: number;
83
83
  agentKey: string;
84
84
  pursuitId: string;
85
85
  claimId: string | null;
@@ -93,10 +93,10 @@ export declare const residentOutboxMessageSchema: z.ZodEffects<z.ZodObject<{
93
93
  }, {
94
94
  id: string;
95
95
  phase: "pending" | "cancelled" | "sending" | "acknowledged";
96
- revision: number;
97
- attempts: number;
98
96
  tenantId: string;
99
97
  body: string;
98
+ revision: number;
99
+ attempts: number;
100
100
  agentKey: string;
101
101
  pursuitId: string;
102
102
  claimId: string | null;
@@ -68,8 +68,8 @@ export declare const residentStateSchema: z.ZodEffects<z.ZodObject<{
68
68
  phase: "running" | "complete" | "blocked" | "waiting";
69
69
  identity: string;
70
70
  reason: string;
71
- revision: number;
72
71
  tenantId: string;
72
+ revision: number;
73
73
  objective: string;
74
74
  wakeAt: number | null;
75
75
  agentKey: string;
@@ -85,8 +85,8 @@ export declare const residentStateSchema: z.ZodEffects<z.ZodObject<{
85
85
  phase: "running" | "complete" | "blocked" | "waiting";
86
86
  identity: string;
87
87
  reason: string;
88
- revision: number;
89
88
  tenantId: string;
89
+ revision: number;
90
90
  objective: string;
91
91
  wakeAt: number | null;
92
92
  agentKey: string;
@@ -102,8 +102,8 @@ export declare const residentStateSchema: z.ZodEffects<z.ZodObject<{
102
102
  phase: "running" | "complete" | "blocked" | "waiting";
103
103
  identity: string;
104
104
  reason: string;
105
- revision: number;
106
105
  tenantId: string;
106
+ revision: number;
107
107
  objective: string;
108
108
  wakeAt: number | null;
109
109
  agentKey: string;
@@ -119,8 +119,8 @@ export declare const residentStateSchema: z.ZodEffects<z.ZodObject<{
119
119
  phase: "running" | "complete" | "blocked" | "waiting";
120
120
  identity: string;
121
121
  reason: string;
122
- revision: number;
123
122
  tenantId: string;
123
+ revision: number;
124
124
  objective: string;
125
125
  wakeAt: number | null;
126
126
  agentKey: string;
@@ -0,0 +1,34 @@
1
+ import type { RunPersistence } from '../../manager/run/persistence.js';
2
+ import type { FencingToken } from '../../types/run/checkpoint-store.js';
3
+ import type { RunEventCursor, RunEventReplay } from '../../types/run/event-cursor.js';
4
+ import type { Run, RunEvent } from '../../types/run/index.js';
5
+ import type { QueryParams } from './index.js';
6
+ import type { PreparedRun } from './prepare-run.js';
7
+ /**
8
+ * The run that was cancelled before it started.
9
+ *
10
+ * Attachment materialization happens before `RunContext` exists, and a
11
+ * cancellation observed there still belongs to a run: it must be recorded,
12
+ * classified and reported like any other, without any of the authority-bearing
13
+ * work — prompt contributions, host callbacks, tools, plugins, sandbox,
14
+ * guardrails, advisors, providers — that a run which is allowed to proceed
15
+ * would do next.
16
+ *
17
+ * An `async function*` rather than a plain async function, and reached with
18
+ * `yield*`, because this path still emits and drains: the events it produces
19
+ * must occupy exactly the positions in the stream they occupied when the code
20
+ * lived inline, and only delegation preserves every yield point.
21
+ */
22
+ export declare function settlePreStartCancellation(params: QueryParams, prepared: PreparedRun): AsyncGenerator<RunEvent, Run>;
23
+ /**
24
+ * Hand a returning consumer what it missed, or tell it why it cannot have it.
25
+ *
26
+ * Yields NOTHING on a refusal. A partial catch-up is the failure this exists to
27
+ * prevent: a consumer that receives some of the gap folds it into its state and
28
+ * cannot tell the state is wrong, where one that receives an explicit
29
+ * `unavailable` re-derives from the transcript and is right. The run continues
30
+ * either way — a stale cursor belongs to the client, and must not be able to
31
+ * stop the work.
32
+ */
33
+ export declare function catchUpFromCursor(runMgr: RunPersistence, cursor: RunEventCursor, onEventReplay: ((replay: RunEventReplay) => void) | undefined, generation: FencingToken | undefined, onReplayObserverError: (error: unknown) => void): AsyncGenerator<RunEvent, void>;
34
+ //# sourceMappingURL=cancelled-before-start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancelled-before-start.d.ts","sourceRoot":"","sources":["../../../src/runtime/query/cancelled-before-start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AAItE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAA;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAErF,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAGnD;;;;;;;;;;;;;;GAcG;AACH,wBAAuB,0BAA0B,CAChD,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,WAAW,GACnB,cAAc,CAAC,QAAQ,EAAE,GAAG,CAAC,CAiH/B;AAED;;;;;;;;;GASG;AACH,wBAAuB,iBAAiB,CACvC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,cAAc,EACtB,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC,GAAG,SAAS,EAC7D,UAAU,EAAE,YAAY,GAAG,SAAS,EACpC,qBAAqB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAC7C,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CA0BhC"}
@@ -0,0 +1,152 @@
1
+ import { GENAI, NAMZU, agentRunSpanName, parentContext } from '../../telemetry/attributes.js';
2
+ import { getTracer } from '../../telemetry/runtime-accessors.js';
3
+ import { createSystemMessage } from '../../types/message/index.js';
4
+ import { resolveRunEventReplay } from '../../types/run/event-cursor.js';
5
+ import { toErrorMessage } from '../../utils/error.js';
6
+ import { ResultAssembler } from './result.js';
7
+ /**
8
+ * The run that was cancelled before it started.
9
+ *
10
+ * Attachment materialization happens before `RunContext` exists, and a
11
+ * cancellation observed there still belongs to a run: it must be recorded,
12
+ * classified and reported like any other, without any of the authority-bearing
13
+ * work — prompt contributions, host callbacks, tools, plugins, sandbox,
14
+ * guardrails, advisors, providers — that a run which is allowed to proceed
15
+ * would do next.
16
+ *
17
+ * An `async function*` rather than a plain async function, and reached with
18
+ * `yield*`, because this path still emits and drains: the events it produces
19
+ * must occupy exactly the positions in the stream they occupied when the code
20
+ * lived inline, and only delegation preserves every yield point.
21
+ */
22
+ export async function* settlePreStartCancellation(params, prepared) {
23
+ const { ctx, runConfig, eventTranslator, executeUserInterruptHooks, selectedResumeState, queuedForThisRun, initialMessages, } = prepared;
24
+ // Attachment materialization happens before RunContext exists. Once it
25
+ // observes cancellation, do only the work required to leave an honest
26
+ // durable run: initialize the record, retain the unresolved references,
27
+ // and settle through the ordinary cancellation classifier. Prompt
28
+ // contributions/cache, host callbacks, tools, plugins, sandbox, guardrails,
29
+ // advisors, and providers are all authority-bearing work and stay out.
30
+ // The dedicated root interrupt notification is the sole plugin exception:
31
+ // it runs after cancellation under its own deadline and cannot regain model
32
+ // or tool authority.
33
+ if (params.resumeFromCheckpoint && !selectedResumeState) {
34
+ // The canonical resume surface hands query the checkpoint state it
35
+ // already selected. A raw resume query has no such snapshot; after
36
+ // cancellation, reading the store again could hang without a signal,
37
+ // while persisting without it would erase the existing transcript.
38
+ // Refuse before binding/persisting rather than choose either failure.
39
+ ctx.abortController.signal.throwIfAborted();
40
+ }
41
+ const cancelledPrompt = params.systemPrompt ?? '';
42
+ const cancelledAssembler = new ResultAssembler({
43
+ runMgr: ctx.runMgr,
44
+ planManager: ctx.planManager,
45
+ activityStore: ctx.activityStore,
46
+ log: ctx.log,
47
+ emitEvent: eventTranslator.emitEvent,
48
+ drainPending: () => eventTranslator.drainPending(),
49
+ signal: ctx.abortController.signal,
50
+ });
51
+ const rootSpan = getTracer().startSpan(agentRunSpanName(params.agentName), {}, parentContext(params.parentSpan ?? selectedResumeState?.traceContext));
52
+ rootSpan.setAttributes({
53
+ [NAMZU.RUN_ID]: ctx.runMgr.id,
54
+ [GENAI.AGENT_NAME]: params.agentName,
55
+ [GENAI.AGENT_ID]: params.agentId,
56
+ [GENAI.REQUEST_MODEL]: runConfig.model,
57
+ [GENAI.SYSTEM]: params.provider.id,
58
+ });
59
+ try {
60
+ await ctx.runMgr.init();
61
+ if (selectedResumeState) {
62
+ ctx.runMgr.restoreUsage(selectedResumeState.tokenUsage, selectedResumeState.costInfo, selectedResumeState.currentIteration);
63
+ for (const message of selectedResumeState.messages)
64
+ ctx.runMgr.pushMessage(message);
65
+ for (const queued of queuedForThisRun)
66
+ ctx.runMgr.pushMessage(queued);
67
+ }
68
+ else if (params.continuationMode) {
69
+ for (const message of initialMessages)
70
+ ctx.runMgr.pushMessage(message);
71
+ }
72
+ else {
73
+ ctx.runMgr.pushMessage(createSystemMessage(cancelledPrompt, 'cache'));
74
+ for (const message of initialMessages)
75
+ ctx.runMgr.pushMessage(message);
76
+ }
77
+ if (params.eventCursor) {
78
+ yield* catchUpFromCursor(ctx.runMgr, params.eventCursor, params.onEventReplay, params.claimFence, (error) => {
79
+ ctx.log.warn('Replay observer failed after attachment cancellation', {
80
+ 'exception.message': toErrorMessage(error),
81
+ });
82
+ });
83
+ }
84
+ if (selectedResumeState) {
85
+ await eventTranslator.emitEvent({
86
+ type: 'run_resuming',
87
+ runId: ctx.runId,
88
+ fromCheckpointId: selectedResumeState.checkpointId,
89
+ });
90
+ yield* eventTranslator.drainPending();
91
+ }
92
+ ctx.runMgr.markRunning();
93
+ await eventTranslator.emitEvent({
94
+ type: 'run_started',
95
+ runId: ctx.runId,
96
+ systemPrompt: cancelledPrompt,
97
+ });
98
+ yield* eventTranslator.drainPending();
99
+ ctx.abortController.signal.throwIfAborted();
100
+ }
101
+ catch (error) {
102
+ // Attachment resolution has already observed the caller's abort. A
103
+ // reconnect callback can still throw while replay is being reported,
104
+ // but it cannot replace that terminal cause or turn a cancelled run
105
+ // into an unpersisted rejection.
106
+ const terminalError = ctx.abortController.signal.aborted
107
+ ? ctx.abortController.signal.reason
108
+ : error;
109
+ await executeUserInterruptHooks(terminalError);
110
+ yield* eventTranslator.drainPending();
111
+ yield* cancelledAssembler.handleError(terminalError, rootSpan);
112
+ }
113
+ finally {
114
+ rootSpan.end();
115
+ }
116
+ return await cancelledAssembler.finalize();
117
+ }
118
+ /**
119
+ * Hand a returning consumer what it missed, or tell it why it cannot have it.
120
+ *
121
+ * Yields NOTHING on a refusal. A partial catch-up is the failure this exists to
122
+ * prevent: a consumer that receives some of the gap folds it into its state and
123
+ * cannot tell the state is wrong, where one that receives an explicit
124
+ * `unavailable` re-derives from the transcript and is right. The run continues
125
+ * either way — a stale cursor belongs to the client, and must not be able to
126
+ * stop the work.
127
+ */
128
+ export async function* catchUpFromCursor(runMgr, cursor, onEventReplay, generation, onReplayObserverError) {
129
+ const missed = await runMgr.getRunStore().readEvents({ sinceSeq: cursor.sinceSeq });
130
+ const replay = resolveRunEventReplay(cursor, {
131
+ lastSeq: runMgr.lastEventSeq,
132
+ ...(generation !== undefined ? { generation } : {}),
133
+ }, missed);
134
+ if (onEventReplay) {
135
+ try {
136
+ // A callback typed `void` may still be implemented with `async` in
137
+ // TypeScript. Observe that runtime Promise so a late rejection cannot
138
+ // become process-wide, but never await host code here: replay delivery
139
+ // and an already-cancelled run must not inherit observer liveness.
140
+ const settlement = onEventReplay(replay);
141
+ void Promise.resolve(settlement).catch(onReplayObserverError);
142
+ }
143
+ catch (error) {
144
+ onReplayObserverError(error);
145
+ }
146
+ }
147
+ if (replay.status !== 'replayed')
148
+ return;
149
+ for (const event of replay.events)
150
+ yield event;
151
+ }
152
+ //# sourceMappingURL=cancelled-before-start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancelled-before-start.js","sourceRoot":"","sources":["../../../src/runtime/query/cancelled-before-start.ts"],"names":[],"mappings":"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"}
@@ -256,6 +256,27 @@ export declare class CheckpointManager {
256
256
  * full checkpoint payload. See ses_005-deterministic-replay design §3.1.
257
257
  */
258
258
  listEntries(): Promise<CheckpointListEntry[]>;
259
+ /**
260
+ * Collect old checkpoints until `keepLast` newer ones remain.
261
+ *
262
+ * Growth control, and growth control stops at a park. A checkpoint with
263
+ * an unresolved `pending` is the durable fact that a human was asked
264
+ * something: it is what `findPendingCheckpoint` serves to an approval
265
+ * queue and what `listExpiredParks` enumerates for a sweep. Collecting
266
+ * one deletes the only record of a question somebody may be in the middle
267
+ * of answering, and their answer then lands nowhere — the store refuses
268
+ * the unpark and the run it belonged to resumes without it.
269
+ *
270
+ * So the candidates are still the oldest `all.length - keepLast`, which
271
+ * is what keeps the newest `keepLast` — the run's resume point — out of
272
+ * reach, and a park among them is skipped rather than counted. Pruning
273
+ * therefore holds a few more rows while a park is outstanding. That is
274
+ * the right side to err on: parks resolve, and the next prune collects
275
+ * them. Expired ones are skipped too — the host's sweep is
276
+ * {@link expire}, which resolves the park by running out of time rather
277
+ * than by deleting the evidence, and `prune` racing it would take the
278
+ * question away before it was read.
279
+ */
259
280
  prune(keepLast: number): Promise<void>;
260
281
  static buildSummary(runMgr: RunPersistence, iteration: number): CheckpointSummary;
261
282
  }
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../../src/runtime/query/checkpoint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../../src/runtime/query/checkpoint.ts"],"names":[],"mappings":"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"}
@@ -498,12 +498,35 @@ export class CheckpointManager {
498
498
  const checkpoints = await this.store.listCheckpoints(this.scope);
499
499
  return checkpoints.map(toCheckpointListEntry);
500
500
  }
501
+ /**
502
+ * Collect old checkpoints until `keepLast` newer ones remain.
503
+ *
504
+ * Growth control, and growth control stops at a park. A checkpoint with
505
+ * an unresolved `pending` is the durable fact that a human was asked
506
+ * something: it is what `findPendingCheckpoint` serves to an approval
507
+ * queue and what `listExpiredParks` enumerates for a sweep. Collecting
508
+ * one deletes the only record of a question somebody may be in the middle
509
+ * of answering, and their answer then lands nowhere — the store refuses
510
+ * the unpark and the run it belonged to resumes without it.
511
+ *
512
+ * So the candidates are still the oldest `all.length - keepLast`, which
513
+ * is what keeps the newest `keepLast` — the run's resume point — out of
514
+ * reach, and a park among them is skipped rather than counted. Pruning
515
+ * therefore holds a few more rows while a park is outstanding. That is
516
+ * the right side to err on: parks resolve, and the next prune collects
517
+ * them. Expired ones are skipped too — the host's sweep is
518
+ * {@link expire}, which resolves the park by running out of time rather
519
+ * than by deleting the evidence, and `prune` racing it would take the
520
+ * question away before it was read.
521
+ */
501
522
  async prune(keepLast) {
502
523
  const all = await this.list();
503
524
  if (all.length <= keepLast)
504
525
  return;
505
526
  const toDelete = all.sort((a, b) => a.createdAt - b.createdAt).slice(0, all.length - keepLast);
506
527
  for (const cp of toDelete) {
528
+ if (cp.pending && cp.pending.resolvedAt === undefined)
529
+ continue;
507
530
  await this.store.deleteCheckpoint(this.scope, cp.id);
508
531
  }
509
532
  }