@warlock.js/ai 4.5.0 → 4.6.1

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 (159) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/cjs/index.cjs +20 -1
  3. package/cjs/{src-DFibP2FQ.cjs → src-Bmajk4Qg.cjs} +1 -1
  4. package/cjs/{src-C02yzsLs.cjs → src-OZyDYHxm.cjs} +2789 -691
  5. package/cjs/src-OZyDYHxm.cjs.map +1 -0
  6. package/esm/agent/agent-config.type.d.mts +29 -0
  7. package/esm/agent/agent-config.type.d.mts.map +1 -1
  8. package/esm/agent/agent.d.mts.map +1 -1
  9. package/esm/agent/agent.mjs +126 -7
  10. package/esm/agent/agent.mjs.map +1 -1
  11. package/esm/agent/signature.mjs +57 -0
  12. package/esm/agent/signature.mjs.map +1 -0
  13. package/esm/agent/snapshot.mjs +101 -0
  14. package/esm/agent/snapshot.mjs.map +1 -0
  15. package/esm/ai-openai/src/image.mjs +5 -0
  16. package/esm/ai-openai/src/index.mjs +3 -0
  17. package/esm/ai-openai/src/sdk.mjs +3 -0
  18. package/esm/ai-openai/src/speech.mjs +5 -0
  19. package/esm/ai-openai/src/transcription.mjs +6 -0
  20. package/esm/ai-openai/src/utils/index.mjs +1 -0
  21. package/esm/ai-openai/src/utils/to-openai-messages.mjs +3 -0
  22. package/esm/ai.d.mts +45 -0
  23. package/esm/ai.d.mts.map +1 -1
  24. package/esm/ai.mjs +37 -1
  25. package/esm/ai.mjs.map +1 -1
  26. package/esm/contracts/agent/agent-options.type.d.mts +22 -2
  27. package/esm/contracts/agent/agent-options.type.d.mts.map +1 -1
  28. package/esm/contracts/agent/agent-snapshot.type.d.mts +90 -0
  29. package/esm/contracts/agent/agent-snapshot.type.d.mts.map +1 -0
  30. package/esm/contracts/agent/agent.contract.d.mts +29 -1
  31. package/esm/contracts/agent/agent.contract.d.mts.map +1 -1
  32. package/esm/contracts/agent/index.d.mts +2 -1
  33. package/esm/contracts/image-model.contract.d.mts +156 -0
  34. package/esm/contracts/image-model.contract.d.mts.map +1 -0
  35. package/esm/contracts/index.d.mts +8 -3
  36. package/esm/contracts/planner/index.d.mts +3 -2
  37. package/esm/contracts/planner/planner-config.type.d.mts +30 -0
  38. package/esm/contracts/planner/planner-config.type.d.mts.map +1 -1
  39. package/esm/contracts/planner/planner-execute-options.type.d.mts +13 -1
  40. package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -1
  41. package/esm/contracts/planner/planner-snapshot.type.d.mts +77 -0
  42. package/esm/contracts/planner/planner-snapshot.type.d.mts.map +1 -0
  43. package/esm/contracts/planner/planner.contract.d.mts +21 -1
  44. package/esm/contracts/planner/planner.contract.d.mts.map +1 -1
  45. package/esm/contracts/result/base-report.type.d.mts +1 -1
  46. package/esm/contracts/result/base-report.type.d.mts.map +1 -1
  47. package/esm/contracts/result/base-report.type.mjs.map +1 -1
  48. package/esm/contracts/sdk-adapter.contract.d.mts +37 -0
  49. package/esm/contracts/sdk-adapter.contract.d.mts.map +1 -1
  50. package/esm/contracts/speech-model.contract.d.mts +97 -0
  51. package/esm/contracts/speech-model.contract.d.mts.map +1 -0
  52. package/esm/contracts/transcription-model.contract.d.mts +101 -0
  53. package/esm/contracts/transcription-model.contract.d.mts.map +1 -0
  54. package/esm/errors/agent-drift-error.d.mts +32 -0
  55. package/esm/errors/agent-drift-error.d.mts.map +1 -0
  56. package/esm/errors/agent-drift-error.mjs +31 -0
  57. package/esm/errors/agent-drift-error.mjs.map +1 -0
  58. package/esm/errors/error-code.type.d.mts +1 -1
  59. package/esm/errors/index.d.mts +2 -0
  60. package/esm/errors/index.mjs +2 -0
  61. package/esm/errors/planner-drift-error.d.mts +34 -0
  62. package/esm/errors/planner-drift-error.d.mts.map +1 -0
  63. package/esm/errors/planner-drift-error.mjs +33 -0
  64. package/esm/errors/planner-drift-error.mjs.map +1 -0
  65. package/esm/image/image-cost.d.mts +32 -0
  66. package/esm/image/image-cost.d.mts.map +1 -0
  67. package/esm/image/image-cost.mjs +55 -0
  68. package/esm/image/image-cost.mjs.map +1 -0
  69. package/esm/image/image.d.mts +92 -0
  70. package/esm/image/image.d.mts.map +1 -0
  71. package/esm/image/image.mjs +113 -0
  72. package/esm/image/image.mjs.map +1 -0
  73. package/esm/image/index.mjs +4 -0
  74. package/esm/index.d.mts +26 -4
  75. package/esm/index.mjs +20 -1
  76. package/esm/mock/index.d.mts +3 -0
  77. package/esm/mock/index.mjs +3 -0
  78. package/esm/mock/mock-config.type.d.mts +22 -0
  79. package/esm/mock/mock-config.type.d.mts.map +1 -1
  80. package/esm/mock/mock-image-model.d.mts +41 -0
  81. package/esm/mock/mock-image-model.d.mts.map +1 -0
  82. package/esm/mock/mock-image-model.mjs +52 -0
  83. package/esm/mock/mock-image-model.mjs.map +1 -0
  84. package/esm/mock/mock-sdk.d.mts +7 -1
  85. package/esm/mock/mock-sdk.d.mts.map +1 -1
  86. package/esm/mock/mock-sdk.mjs +27 -0
  87. package/esm/mock/mock-sdk.mjs.map +1 -1
  88. package/esm/mock/mock-speech-model.d.mts +31 -0
  89. package/esm/mock/mock-speech-model.d.mts.map +1 -0
  90. package/esm/mock/mock-speech-model.mjs +39 -0
  91. package/esm/mock/mock-speech-model.mjs.map +1 -0
  92. package/esm/mock/mock-transcription-model.d.mts +32 -0
  93. package/esm/mock/mock-transcription-model.d.mts.map +1 -0
  94. package/esm/mock/mock-transcription-model.mjs +36 -0
  95. package/esm/mock/mock-transcription-model.mjs.map +1 -0
  96. package/esm/planner/planner-run.d.mts +8 -0
  97. package/esm/planner/planner-run.d.mts.map +1 -1
  98. package/esm/planner/planner-run.mjs +161 -6
  99. package/esm/planner/planner-run.mjs.map +1 -1
  100. package/esm/planner/planner.d.mts.map +1 -1
  101. package/esm/planner/planner.mjs +25 -1
  102. package/esm/planner/planner.mjs.map +1 -1
  103. package/esm/planner/snapshot.mjs +95 -0
  104. package/esm/planner/snapshot.mjs.map +1 -0
  105. package/esm/rag/index.d.mts +7 -0
  106. package/esm/rag/index.mjs +7 -0
  107. package/esm/rag/loaders/errors.d.mts +19 -0
  108. package/esm/rag/loaders/errors.d.mts.map +1 -0
  109. package/esm/rag/loaders/errors.mjs +25 -0
  110. package/esm/rag/loaders/errors.mjs.map +1 -0
  111. package/esm/rag/loaders/index.mjs +7 -0
  112. package/esm/rag/loaders/load-html.d.mts +26 -0
  113. package/esm/rag/loaders/load-html.d.mts.map +1 -0
  114. package/esm/rag/loaders/load-html.mjs +138 -0
  115. package/esm/rag/loaders/load-html.mjs.map +1 -0
  116. package/esm/rag/loaders/load-pdf.d.mts +38 -0
  117. package/esm/rag/loaders/load-pdf.d.mts.map +1 -0
  118. package/esm/rag/loaders/load-pdf.mjs +150 -0
  119. package/esm/rag/loaders/load-pdf.mjs.map +1 -0
  120. package/esm/rag/loaders/load-text.d.mts +47 -0
  121. package/esm/rag/loaders/load-text.d.mts.map +1 -0
  122. package/esm/rag/loaders/load-text.mjs +60 -0
  123. package/esm/rag/loaders/load-text.mjs.map +1 -0
  124. package/esm/rag/loaders/load-web.d.mts +42 -0
  125. package/esm/rag/loaders/load-web.d.mts.map +1 -0
  126. package/esm/rag/loaders/load-web.mjs +89 -0
  127. package/esm/rag/loaders/load-web.mjs.map +1 -0
  128. package/esm/rag/loaders/loader.type.d.mts +89 -0
  129. package/esm/rag/loaders/loader.type.d.mts.map +1 -0
  130. package/esm/rag/store/pg-vector-store.d.mts +139 -0
  131. package/esm/rag/store/pg-vector-store.d.mts.map +1 -0
  132. package/esm/rag/store/pg-vector-store.mjs +328 -0
  133. package/esm/rag/store/pg-vector-store.mjs.map +1 -0
  134. package/esm/speech/index.mjs +3 -0
  135. package/esm/speech/speech.d.mts +65 -0
  136. package/esm/speech/speech.d.mts.map +1 -0
  137. package/esm/speech/speech.mjs +123 -0
  138. package/esm/speech/speech.mjs.map +1 -0
  139. package/esm/supervisor/entries.mjs +2 -2
  140. package/esm/supervisor/entries.mjs.map +1 -1
  141. package/esm/transcribe/audio-input.d.mts +47 -0
  142. package/esm/transcribe/audio-input.d.mts.map +1 -0
  143. package/esm/transcribe/audio-input.mjs +84 -0
  144. package/esm/transcribe/audio-input.mjs.map +1 -0
  145. package/esm/transcribe/index.mjs +4 -0
  146. package/esm/transcribe/transcribe.d.mts +64 -0
  147. package/esm/transcribe/transcribe.d.mts.map +1 -0
  148. package/esm/transcribe/transcribe.mjs +128 -0
  149. package/esm/transcribe/transcribe.mjs.map +1 -0
  150. package/llms-full.txt +753 -0
  151. package/llms.txt +5 -0
  152. package/package.json +3 -3
  153. package/skills/README.md +4 -0
  154. package/skills/durable-agent-runs/SKILL.md +135 -0
  155. package/skills/generate-images/SKILL.md +138 -0
  156. package/skills/generate-speech/SKILL.md +139 -0
  157. package/skills/rag-loaders-and-stores/SKILL.md +164 -0
  158. package/skills/transcribe-audio/SKILL.md +157 -0
  159. package/cjs/src-C02yzsLs.cjs.map +0 -1
@@ -1,5 +1,6 @@
1
1
  import { AttachmentPolicy } from "../contracts/attachment-policy.type.mjs";
2
2
  import { FlowObserveOption } from "../observe/resolve-observers.mjs";
3
+ import { SnapshotStore } from "../contracts/orchestrator/snapshot-store.contract.mjs";
3
4
  import { AgentToolEntry } from "../tool/executable-as-tool.mjs";
4
5
  import { ModelCallOptions, ModelContract } from "../contracts/model.contract.mjs";
5
6
  import { AgentMiddleware } from "../contracts/middleware/middleware.contract.mjs";
@@ -7,6 +8,7 @@ import { Placeholders } from "../contracts/placeholders.type.mjs";
7
8
  import { SystemPromptContract } from "../contracts/system-prompt.contract.mjs";
8
9
  import { AgentEventMap } from "../contracts/events/event-map.type.mjs";
9
10
  import { StreamingToolGuardConfig } from "../contracts/streaming-tool-guard-config.type.mjs";
11
+ import { AgentSnapshot } from "../contracts/agent/agent-snapshot.type.mjs";
10
12
  import { CompleteEvent } from "../contracts/events/complete-event.type.mjs";
11
13
  import { UsageEvent } from "../contracts/events/usage-event.type.mjs";
12
14
  import { SkillsConfig } from "../skills/contracts/skills-config.type.mjs";
@@ -256,6 +258,33 @@ type AgentConfig<TOutput = unknown> = {
256
258
  * Observer errors are swallowed — they never break the run.
257
259
  */
258
260
  observe?: FlowObserveOption;
261
+ /**
262
+ * Opt-in durable mid-run crash-resume. When set, the agent checkpoints
263
+ * its state to a {@link SnapshotStore} after every settled trip, so a
264
+ * `agent.resume(runId)` after a crash re-hydrates the completed trips +
265
+ * tool calls + usage and continues the trip loop from the next trip —
266
+ * never re-issuing a completed trip's model call or re-invoking its
267
+ * tools.
268
+ *
269
+ * Absent ⇒ no persistence, zero behavior change: the trip loop starts
270
+ * at trip 0, never writes a snapshot, and runs byte-for-byte as today.
271
+ *
272
+ * - `store` — the snapshot store to persist to. Optional; falls back to
273
+ * `ai.config({ defaultSnapshotStore })` when omitted. When neither is
274
+ * set, snapshot writes silently skip and `resume()` throws.
275
+ * - `deleteOnComplete` — drop the snapshot once the run terminates
276
+ * successfully. Default `false` (keep it, so a completed-run resume
277
+ * short-circuits to the stored result and the snapshot stays for audit).
278
+ *
279
+ * **Idempotency caveat.** A crash mid-trip re-runs that trip's tools on
280
+ * resume; side-effectful tools (charging a card, sending an email) must
281
+ * be idempotent — the same caller-responsibility boundary the supervisor
282
+ * and workflow primitives already document.
283
+ */
284
+ durable?: {
285
+ /** Snapshot store to persist to. Falls back to the global default. */store?: SnapshotStore<AgentSnapshot>; /** Drop the snapshot on successful completion. Default `false`. */
286
+ deleteOnComplete?: boolean;
287
+ };
259
288
  };
260
289
  //#endregion
261
290
  export { AgentConfig, AgentEventHandlers };
@@ -1 +1 @@
1
- {"version":3,"file":"agent-config.type.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/agent/agent-config.type.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqBA;;KAAY,kBAAA,GAAqB,OAAA,eACnB,aAAA,IAAiB,OAAA,EAAS,aAAA,CAAc,CAAA;;;;;;;;;;;;AAAE;AA0BxD;;;;;;;;;;;KAAY,WAAA;EA+FD;;;;;;;;;;;;EAlFT,IAAA;EAbsB;;;;;;;EAqBtB,WAAA;EAkCA;;;;;;;;;;;;EArBA,OAAA,WA6DS;EA3DT,KAAA,EAAO,aAAA;EA8FP;;;;EAzFA,YAAA,GAAe,oBAAA;EA2GF;;;;;;;;;;;;;EA7Fb,KAAA,GAAQ,cAAA;EA+JE;;AAAiB;;;;;;EAtJ3B,gBAAA,GAAmB,gBAAA;;;;;;;;;;;;;EAanB,MAAA,GAAS,cAAA,GAAiB,YAAA;EAE1B,YAAA,GAAe,YAAA;;;;;EAKf,QAAA;EAEA,YAAA,GAAe,gBAAA;;;;;;;;;EASf,MAAA,GAAS,gBAAA,CAAiB,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmC1B,KAAA,aAAkB,WAAA;;;;;;EAMlB,EAAA,GAAK,kBAAA;;;;;;;;;;;;EAYL,UAAA,GAAa,eAAA;;;;;;;;;;;EAWb,kBAAA,GAAqB,wBAAA;;;;;;;;;;;;;;;EAerB,OAAA,IAAW,KAAA,EAAO,UAAA,YAAsB,OAAA;;;;;;;;;;;;;EAaxC,UAAA,IAAc,KAAA,EAAO,aAAA,CAAc,OAAA,aAAoB,OAAA;;;;;;;;;EASvD,eAAA;;;;;;;;;;;;;;;;;;EAkBA,OAAA,GAAU,iBAAA;AAAA"}
1
+ {"version":3,"file":"agent-config.type.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/agent/agent-config.type.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA;;KAAY,kBAAA,GAAqB,OAAA,eACnB,aAAA,IAAiB,OAAA,EAAS,aAAA,CAAc,CAAA;;;;;;;;;;;;AAAE;AA0BxD;;;;;;;;;;;KAAY,WAAA;EA+FD;;;;;;;;;;;;EAlFT,IAAA;EAmOuB;;;;;;;EA3NvB,WAAA;EAoBA;;;;;;;;;;;;EAPA,OAAA,WAoDe;EAlDf,KAAA,EAAO,aAAA;EA2DE;;;;EAtDT,YAAA,GAAe,oBAAA;EA+FV;;;;;;;;;;;;;EAjFL,KAAA,GAAQ,cAAA;EA6IR;;;;;;;;EApIA,gBAAA,GAAmB,gBAAA;EAkLD;;;;;;;;;;;;EArKlB,MAAA,GAAS,cAAA,GAAiB,YAAA;EAE1B,YAAA,GAAe,YAAA;;;;;EAKf,QAAA;EAEA,YAAA,GAAe,gBAAA;;;;;;;;;EASf,MAAA,GAAS,gBAAA,CAAiB,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmC1B,KAAA,aAAkB,WAAA;;;;;;EAMlB,EAAA,GAAK,kBAAA;;;;;;;;;;;;EAYL,UAAA,GAAa,eAAA;;;;;;;;;;;EAWb,kBAAA,GAAqB,wBAAA;;;;;;;;;;;;;;;EAerB,OAAA,IAAW,KAAA,EAAO,UAAA,YAAsB,OAAA;;;;;;;;;;;;;EAaxC,UAAA,IAAc,KAAA,EAAO,aAAA,CAAc,OAAA,aAAoB,OAAA;;;;;;;;;EASvD,eAAA;;;;;;;;;;;;;;;;;;EAkBA,OAAA,GAAU,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;EAwBV,OAAA;0EAEE,KAAA,GAAQ,aAAA,CAAc,aAAA;IAEtB,gBAAA;EAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/agent/agent.ts"],"mappings":";;;;;;;;AA6OA;;;;;;;;;;;;;;;;AAA6F;;;;;;AAsI7F;;;;;iBAtIgB,KAAA,oBAAyB,MAAA,EAAQ,WAAA,CAAY,OAAA,IAAW,aAAA,CAAc,OAAA;AAAA,kBAAtE,KAAA;EAAA,kBAAK,UAAA;AAAA;;;;;AAsIqD;KAA9D,gBAAA,sBAAsC,IAAA,CAAK,WAAA,CAAY,OAAA;;;;;;;;;;;;;;;;;;;AAiC3C;;;;;;;;;;iBAHf,UAAA,oBACP,MAAA,EAAQ,gBAAA,CAAiB,OAAA,GACzB,KAAA,GAAO,WAAA,aACN,aAAA,CAAc,OAAA"}
1
+ {"version":3,"file":"agent.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/agent/agent.ts"],"mappings":";;;;;;;;AA6PA;;;;;;;;;;;;;;;;AAA6F;;;;;;AAqL7F;;;;;iBArLgB,KAAA,oBAAyB,MAAA,EAAQ,WAAA,CAAY,OAAA,IAAW,aAAA,CAAc,OAAA;AAAA,kBAAtE,KAAA;EAAA,kBAAK,UAAA;AAAA;;;;;AAqLqD;KAA9D,gBAAA,sBAAsC,IAAA,CAAK,WAAA,CAAY,OAAA;;;;;;;;;;;;;;;;;;;AAiC3C;;;;;;;;;;iBAHf,UAAA,oBACP,MAAA,EAAQ,gBAAA,CAAiB,OAAA,GACzB,KAAA,GAAO,WAAA,aACN,aAAA,CAAc,OAAA"}
@@ -25,6 +25,8 @@ import { logAgentEvent } from "./agent-log-event.mjs";
25
25
  import { createAgentStream } from "./agent-stream.mjs";
26
26
  import { agentEventToStreamEvent } from "./agent-to-stream-event.mjs";
27
27
  import { JsonStreamGuard } from "./json-stream-guard.mjs";
28
+ import { computeAgentSignature } from "./signature.mjs";
29
+ import { deleteAgentSnapshot, loadAgentSnapshotForResume, persistAgentSnapshot } from "./snapshot.mjs";
28
30
  import { log } from "@warlock.js/logger";
29
31
 
30
32
  //#region ../@warlock.js/ai/src/agent/agent.ts
@@ -155,11 +157,23 @@ function agent(config) {
155
157
  tools
156
158
  }) : config.name;
157
159
  const skillsLib = config.skills ? isSkillsContract(config.skills) ? config.skills : skills(config.skills) : void 0;
160
+ const signature = computeAgentSignature({
161
+ name: isAnonymous ? void 0 : name,
162
+ version: config.version,
163
+ model: {
164
+ name: config.model?.name,
165
+ provider: config.model?.provider
166
+ },
167
+ tools,
168
+ maxTrips: config.maxTrips,
169
+ output: config.output
170
+ });
158
171
  const resolvedConfig = {
159
172
  ...config,
160
173
  name,
161
174
  tools,
162
- skillsLib
175
+ skillsLib,
176
+ signature
163
177
  };
164
178
  const instanceHandlers = /* @__PURE__ */ new Map();
165
179
  function on(event, handler) {
@@ -179,6 +193,7 @@ function agent(config) {
179
193
  name,
180
194
  isAnonymous,
181
195
  description: config.description,
196
+ signature,
182
197
  async execute(input, options) {
183
198
  return new Execution(resolvedConfig, input, options, void 0, instanceHandlers).run();
184
199
  },
@@ -187,6 +202,19 @@ function agent(config) {
187
202
  new Execution(resolvedConfig, input, options, controller, instanceHandlers).run();
188
203
  return stream;
189
204
  },
205
+ async resume(runId, options) {
206
+ const snapshot = await loadAgentSnapshotForResume({
207
+ durable: resolvedConfig.durable,
208
+ agentName: name,
209
+ signature,
210
+ runId,
211
+ options
212
+ });
213
+ return new Execution(resolvedConfig, snapshot.input, {
214
+ ...options,
215
+ runId
216
+ }, void 0, instanceHandlers, snapshot).run();
217
+ },
190
218
  on,
191
219
  off,
192
220
  eval(options) {
@@ -273,12 +301,13 @@ agent.judge = judgeAgent;
273
301
  * return stream;
274
302
  */
275
303
  var Execution = class {
276
- constructor(config, input, options, streamController, instanceHandlers) {
304
+ constructor(config, input, options, streamController, instanceHandlers, resumeFrom) {
277
305
  this.config = config;
278
306
  this.input = input;
279
307
  this.options = options;
280
308
  this.streamController = streamController;
281
309
  this.instanceHandlers = instanceHandlers;
310
+ this.resumeFrom = resumeFrom;
282
311
  this.trips = [];
283
312
  this.toolCalls = [];
284
313
  this.usage = {
@@ -287,15 +316,25 @@ var Execution = class {
287
316
  total: 0
288
317
  };
289
318
  this.messages = [];
290
- this.startedAt = /* @__PURE__ */ new Date();
291
319
  this.start = performance.now();
292
- this.runId = generateRunId("agent");
293
320
  this.logger = log;
294
321
  this.warnedHandlerEvents = /* @__PURE__ */ new Set();
295
322
  this.middlewareState = /* @__PURE__ */ new Map();
296
323
  this.maxTrips = config.maxTrips ?? 10;
297
324
  this.middleware = config.middleware ?? [];
298
325
  this.judgeConfig = resolveJudgeConfig(config.judge);
326
+ this.runId = resumeFrom?.runId ?? options?.runId ?? generateRunId("agent");
327
+ this.startedAt = resumeFrom ? new Date(resumeFrom.startedAt) : /* @__PURE__ */ new Date();
328
+ if (resumeFrom) {
329
+ this.messages.push(...resumeFrom.messages);
330
+ this.trips.push(...resumeFrom.trips);
331
+ this.toolCalls.push(...resumeFrom.toolCalls);
332
+ mergeUsage(this.usage, resumeFrom.usage);
333
+ this.systemPrompt = resumeFrom.systemPrompt;
334
+ this.responseSchema = resumeFrom.responseSchema;
335
+ this.promptName = resumeFrom.promptName;
336
+ this.promptVersion = resumeFrom.promptVersion;
337
+ }
299
338
  const skillTools = config.skillsLib ? normalizeAgentTools(config.skillsLib.tools(this.runId)) ?? [] : [];
300
339
  this.effectiveTools = [...config.tools ?? [], ...skillTools];
301
340
  }
@@ -359,14 +398,28 @@ var Execution = class {
359
398
  * with `error` populated when things went wrong.
360
399
  */
361
400
  async runCore() {
401
+ if (this.resumeFrom && this.resumeFrom.status === "completed") return this.rebuildResumedResult(this.resumeFrom);
362
402
  try {
363
- await this.buildInitialMessages();
364
- this.emit("agent.starting", { input: this.input });
403
+ if (!this.resumeFrom) {
404
+ await this.buildInitialMessages();
405
+ this.emit("agent.starting", { input: this.input });
406
+ }
365
407
  await this.runTripLoop();
366
408
  if (await this.parseOutput() === "failed" && this.resolveRepairAttempts() > 0) await this.runRepairLoop();
367
409
  } catch (thrown) {
368
410
  this.error = this.toAIError(thrown);
369
411
  }
412
+ await this.checkpoint(this.resolveSnapshotStatus());
413
+ if (!this.error && this.config.durable?.deleteOnComplete) {
414
+ const outcome = await deleteAgentSnapshot({
415
+ durable: this.config.durable,
416
+ runId: this.runId
417
+ });
418
+ if (!outcome.ok) this.logger.warn(LOG_MODULE, "snapshot.delete.failed", "durable snapshot delete failed", {
419
+ runId: this.runId,
420
+ error: outcome.error instanceof Error ? outcome.error.message : String(outcome.error)
421
+ });
422
+ }
370
423
  return this.buildResult();
371
424
  }
372
425
  /**
@@ -431,7 +484,7 @@ var Execution = class {
431
484
  * error so the caller can distinguish runaway tool loops from a real result.
432
485
  */
433
486
  async runTripLoop() {
434
- for (let tripIndex = 0; tripIndex < this.maxTrips; tripIndex++) {
487
+ for (let tripIndex = this.trips.length; tripIndex < this.maxTrips; tripIndex++) {
435
488
  if (this.options?.signal?.aborted) {
436
489
  this.error = this.makeCancelledError();
437
490
  return;
@@ -479,6 +532,7 @@ var Execution = class {
479
532
  this.trips.push(failedTrip);
480
533
  this.emit("agent.trip.completed", { trip: failedTrip });
481
534
  this.emit("agent.error", { error: this.error });
535
+ await this.checkpoint("failed");
482
536
  return "error";
483
537
  }
484
538
  if (response.usage.cost === void 0) response.usage.cost = computeCost(response.usage, this.config.model.pricing);
@@ -510,6 +564,7 @@ var Execution = class {
510
564
  };
511
565
  this.trips.push(trip);
512
566
  this.emit("agent.trip.completed", { trip });
567
+ await this.checkpoint("running");
513
568
  if (!isToolCallTrip) return "stop";
514
569
  return response.toolCalls.every((request) => {
515
570
  return this.effectiveTools.find((tool) => tool.name === request.name)?.mode === "silent";
@@ -920,6 +975,70 @@ var Execution = class {
920
975
  };
921
976
  }
922
977
  /**
978
+ * Map the run's terminal outcome to the persisted snapshot status.
979
+ * A cancelled error reads as `"cancelled"`, any other error as
980
+ * `"failed"`, otherwise `"completed"`. Mirrors the report-status
981
+ * mapping in {@link buildResult}.
982
+ */
983
+ resolveSnapshotStatus() {
984
+ if (!this.error) return "completed";
985
+ return this.error instanceof AgentCancelledError ? "cancelled" : "failed";
986
+ }
987
+ /**
988
+ * Build and persist an {@link AgentSnapshot} from the current
989
+ * accumulators. The per-trip and terminal checkpoints both route
990
+ * through here. Reuses {@link captureMessages} to normalize the live
991
+ * `Message[]` into JSON-safe form so the snapshot round-trips through
992
+ * any store backend.
993
+ *
994
+ * No-op (returns immediately) when `durable` is absent — the common
995
+ * non-durable path stays free. A failed persist is logged and
996
+ * swallowed (never aborts the run), matching the supervisor / workflow
997
+ * checkpoint policy.
998
+ */
999
+ async checkpoint(status) {
1000
+ if (!this.config.durable) return;
1001
+ const outcome = await persistAgentSnapshot({
1002
+ durable: this.config.durable,
1003
+ runId: this.runId,
1004
+ agentName: this.config.name ?? this.config.model.name,
1005
+ signature: this.config.signature,
1006
+ version: this.config.version,
1007
+ input: this.input,
1008
+ systemPrompt: this.systemPrompt,
1009
+ responseSchema: this.responseSchema,
1010
+ promptName: this.promptName,
1011
+ promptVersion: this.promptVersion,
1012
+ messages: this.captureMessages(),
1013
+ trips: this.trips,
1014
+ toolCalls: this.toolCalls,
1015
+ usage: this.usage,
1016
+ status,
1017
+ startedAt: this.startedAt.toISOString()
1018
+ });
1019
+ if (!outcome.ok) this.logger.warn(LOG_MODULE, "snapshot.persist.failed", "durable snapshot persist failed", {
1020
+ runId: this.runId,
1021
+ status,
1022
+ error: outcome.error instanceof Error ? outcome.error.message : String(outcome.error)
1023
+ });
1024
+ }
1025
+ /**
1026
+ * Rebuild the final {@link AgentResult} from a COMPLETED snapshot
1027
+ * WITHOUT re-running anything. Used by the completed-run resume
1028
+ * short-circuit: the persisted trips / tool calls / usage are the
1029
+ * authoritative outcome, so a resume of a settled run re-returns that
1030
+ * outcome idempotently. Re-derives `this.data` from the final trip
1031
+ * output against the schema (cheap, no model call) so the rebuilt
1032
+ * result carries the same structured payload the original produced.
1033
+ *
1034
+ * Only reached for a `completed` snapshot — `failed` / `cancelled`
1035
+ * snapshots re-enter the trip loop to retry the remaining work instead.
1036
+ */
1037
+ async rebuildResumedResult(_snapshot) {
1038
+ await this.parseOutput();
1039
+ return this.buildResult();
1040
+ }
1041
+ /**
923
1042
  * Normalize the accumulated runtime `Message[]` into the JSON-safe
924
1043
  * {@link CapturedMessage}[] persisted on `AgentReport.messages` (F2).
925
1044
  * Flattens `ContentPart[]` content to a string, and forwards