@statelyai/agent 2.0.0-alpha.28 → 2.0.0-alpha.30

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 (80) hide show
  1. package/dist/ai-sdk.cjs +150 -27
  2. package/dist/ai-sdk.d.cts +59 -36
  3. package/dist/ai-sdk.d.mts +59 -36
  4. package/dist/ai-sdk.mjs +148 -24
  5. package/dist/{decision-RQ0iv0oZ.mjs → decision-BHkvuImD.mjs} +74 -8
  6. package/dist/{decision-CmM8-HHz.cjs → decision-CIb7ddIv.cjs} +113 -30
  7. package/dist/{text-logic-f5F5sCdc.cjs → event-log-BZRfBRd7.cjs} +814 -7
  8. package/dist/{text-logic-CIqHAmBi.mjs → event-log-DJCMHek_.mjs} +680 -4
  9. package/dist/{event-log-store-BIPOz-di.d.mts → event-log-store-CIIJohjj.d.mts} +90 -5
  10. package/dist/{event-log-store-2xzFmgr2.d.cts → event-log-store-CLAC9q2Y.d.cts} +90 -5
  11. package/dist/event-log-store-DZR4IIWe.cjs +95 -0
  12. package/dist/event-log-store-DsP6GCRh.mjs +84 -0
  13. package/dist/index.cjs +576 -58
  14. package/dist/index.d.cts +104 -510
  15. package/dist/index.d.mts +104 -510
  16. package/dist/index.mjs +547 -32
  17. package/dist/log.cjs +77 -20
  18. package/dist/log.d.cts +5 -5
  19. package/dist/log.d.mts +5 -5
  20. package/dist/log.mjs +58 -3
  21. package/dist/machines.cjs +1 -1
  22. package/dist/machines.d.cts +15 -15
  23. package/dist/machines.d.mts +15 -15
  24. package/dist/machines.mjs +1 -1
  25. package/dist/model-source-BCKg4qJ1.cjs +44 -0
  26. package/dist/model-source-BaHwJ1wK.mjs +39 -0
  27. package/dist/openai.cjs +11 -11
  28. package/dist/openai.d.cts +28 -26
  29. package/dist/openai.d.mts +28 -26
  30. package/dist/openai.mjs +3 -3
  31. package/dist/otel.cjs +5 -4
  32. package/dist/otel.d.cts +5 -7
  33. package/dist/otel.d.mts +5 -7
  34. package/dist/otel.mjs +5 -3
  35. package/dist/{run-agent-xNTxpt82.mjs → run-agent-BpHqkaZw.mjs} +181 -44
  36. package/dist/{run-agent-COXXc0RW.d.mts → run-agent-CAVt5R-r.d.mts} +95 -30
  37. package/dist/{run-agent-ByO-Bxyd.d.cts → run-agent-CTlMc3Jb.d.cts} +95 -30
  38. package/dist/{run-agent-Dmf8GV2d.cjs → run-agent-ctLCvNgL.cjs} +230 -88
  39. package/dist/{setup-agent-BuanDXeh.mjs → setup-agent-7rV_cujV.mjs} +15 -9
  40. package/dist/setup-agent-CGELn1qZ.d.mts +577 -0
  41. package/dist/setup-agent-CLPCkXsu.d.cts +577 -0
  42. package/dist/{setup-agent-DV4cTou-.cjs → setup-agent-DoUk7EdC.cjs} +31 -20
  43. package/dist/tanstack-ai.cjs +627 -0
  44. package/dist/tanstack-ai.d.cts +204 -0
  45. package/dist/tanstack-ai.d.mts +204 -0
  46. package/dist/tanstack-ai.mjs +618 -0
  47. package/dist/testing.cjs +204 -985
  48. package/dist/testing.d.cts +132 -347
  49. package/dist/testing.d.mts +132 -347
  50. package/dist/testing.mjs +191 -973
  51. package/dist/{text-logic-IjfYy9DP.d.cts → text-logic-BRYOPWvY.d.mts} +52 -12
  52. package/dist/{text-logic-D-czVPYp.d.mts → text-logic-DmciuVUQ.d.cts} +52 -12
  53. package/dist/{types-BgNbNKnJ.d.mts → types-Dp5_Ru4R.d.cts} +2 -2
  54. package/dist/{types-hR5f5YXa.d.cts → types-Dp5_Ru4R.d.mts} +2 -2
  55. package/dist/usage-BkM3z02Y.d.mts +17 -0
  56. package/dist/usage-Cm_ovz9V.d.cts +17 -0
  57. package/dist/{utils-_q7F-AZu.d.mts → utils-BnXdWih3.d.mts} +1 -2
  58. package/dist/{utils-o4YRdHJX.d.cts → utils-ebVpCYoF.d.cts} +1 -2
  59. package/dist/validate.cjs +239 -8
  60. package/dist/validate.d.cts +110 -3
  61. package/dist/validate.d.mts +110 -3
  62. package/dist/validate.mjs +238 -7
  63. package/dist/verify-COFWyprJ.mjs +1181 -0
  64. package/dist/verify-CVlsTZ-V.cjs +1222 -0
  65. package/dist/verify-Cn86rT8l.d.mts +414 -0
  66. package/dist/verify-Dzwd4Mvk.d.cts +414 -0
  67. package/package.json +44 -31
  68. package/readme.md +40 -28
  69. package/skills/add-evals/SKILL.md +129 -0
  70. package/skills/add-traces/SKILL.md +135 -0
  71. package/skills/generate-machine/SKILL.md +143 -69
  72. package/skills/graph-engineering/SKILL.md +33 -0
  73. package/skills/improve-machine/SKILL.md +241 -0
  74. package/skills/improve-machine/reference.md +101 -0
  75. package/skills/loop-to-machine/SKILL.md +183 -0
  76. package/skills/loop-to-machine/policy.md +158 -0
  77. package/dist/event-log-store-2pAFiWuc.mjs +0 -576
  78. package/dist/event-log-store-C-COhIXP.cjs +0 -702
  79. package/dist/usage-BdEjFuIi.mjs +0 -5
  80. package/dist/usage-efOQPdf_.cjs +0 -10
@@ -1,8 +1,6 @@
1
- const require_text_logic = require("./text-logic-f5F5sCdc.cjs");
2
- const require_decision = require("./decision-CmM8-HHz.cjs");
3
- const require_usage = require("./usage-efOQPdf_.cjs");
4
- const require_event_log_store = require("./event-log-store-C-COhIXP.cjs");
5
- require("./validate.cjs");
1
+ const require_event_log = require("./event-log-BZRfBRd7.cjs");
2
+ const require_decision = require("./decision-CIb7ddIv.cjs");
3
+ const require_event_log_store = require("./event-log-store-DZR4IIWe.cjs");
6
4
  let xstate = require("xstate");
7
5
  let xstate_durable = require("xstate/durable");
8
6
  //#region src/run-agent.ts
@@ -14,7 +12,10 @@ let xstate_durable = require("xstate/durable");
14
12
  * a snapshot mutated out of band), not a recoverable resume: pass the log
15
13
  * alone, or the matching snapshot.
16
14
  */
17
- var AgentSnapshotDivergedError = class extends require_text_logic.AgentError {
15
+ var AgentSnapshotDivergedError = class extends require_event_log.AgentError {
16
+ expected;
17
+ actual;
18
+ logIndex;
18
19
  constructor(expected, actual, logIndex) {
19
20
  super("snapshot-diverged", `createAgentRuntime: the resume snapshot disagrees with the event log at index ${logIndex}: the log replays to state hash '${expected}', the snapshot hashes '${actual}'.`);
20
21
  this.expected = expected;
@@ -27,9 +28,9 @@ function hashResumeSnapshot(snapshot) {
27
28
  if (snapshot !== null && typeof snapshot === "object" && "agentMeta" in snapshot) {
28
29
  const rest = {};
29
30
  for (const [key, value] of Object.entries(snapshot)) if (key !== "agentMeta") rest[key] = value;
30
- return require_event_log_store.getSnapshotStateHash(rest);
31
+ return require_event_log.getSnapshotStateHash(rest);
31
32
  }
32
- return require_event_log_store.getSnapshotStateHash(snapshot);
33
+ return require_event_log.getSnapshotStateHash(snapshot);
33
34
  }
34
35
  function readAgentMeta(snapshot) {
35
36
  const meta = snapshot?.agentMeta;
@@ -146,7 +147,7 @@ let nextRunAgentTraceId = 1;
146
147
  * ]
147
148
  * ```
148
149
  */
149
- var AgentMaxModelCallsExceededError = class extends require_text_logic.AgentError {
150
+ var AgentMaxModelCallsExceededError = class extends require_event_log.AgentError {
150
151
  /** The budget that was exceeded (`options.maxModelCalls`). */
151
152
  maxModelCalls;
152
153
  constructor(maxModelCalls) {
@@ -215,7 +216,7 @@ function assertBindable(machine, effectiveSources, executors) {
215
216
  isChild: false,
216
217
  childPath: "",
217
218
  rebindable: true,
218
- visited: new Set([machine])
219
+ visited: /* @__PURE__ */ new Set([machine])
219
220
  });
220
221
  }
221
222
  function assertMachineBindable(machine, effectiveSources, executors, ctx) {
@@ -228,7 +229,7 @@ function assertMachineBindable(machine, effectiveSources, executors, ctx) {
228
229
  assertChildMachineBindable(src, src, stateName, executors, ctx);
229
230
  continue;
230
231
  }
231
- if ((require_text_logic.isTextLogic(src) || require_decision.isDecisionLogic(src)) && !require_text_logic.executorBoundLogics.has(src)) throw new Error(`createAgentRuntime: ${where} '${stateName}' invokes a direct-object actor logic (kind: '${src.kind}'). Direct-object invoke srcs cannot be rebound by the agent runtime — either call '.withExecutor(...)' on the logic before invoking it, or register it as a string-keyed actor source instead (machine.provide({ actors: { name: logic } })) and invoke it by name.`);
232
+ if ((require_event_log.isTextLogic(src) || require_decision.isDecisionLogic(src)) && !require_event_log.executorBoundLogics.has(src)) throw new Error(`createAgentRuntime: ${where} '${stateName}' invokes a direct-object actor logic (kind: '${src.kind}'). Direct-object invoke srcs cannot be rebound by the agent runtime — either call '.withExecutor(...)' on the logic before invoking it, or register it as a string-keyed actor source instead (machine.provide({ actors: { name: logic } })) and invoke it by name.`);
232
233
  continue;
233
234
  }
234
235
  const logic = effectiveSources[src];
@@ -238,19 +239,19 @@ function assertMachineBindable(machine, effectiveSources, executors, ctx) {
238
239
  continue;
239
240
  }
240
241
  if (require_decision.isDecisionLogic(logic)) {
241
- if (require_text_logic.executorBoundLogics.has(logic)) continue;
242
+ if (require_event_log.executorBoundLogics.has(logic)) continue;
242
243
  if (!ctx.rebindable) throw unrebindableChildRequestError(ctx.childPath, stateName, src, "decision");
243
244
  if (!executors.decide) throw new Error(`createAgentRuntime: ${where} '${stateName}' invokes decision source '${src}' but no 'decide' executor was provided to createAgentRuntime(...).`);
244
245
  continue;
245
246
  }
246
- if (require_text_logic.isTextLogic(logic)) {
247
- if (require_text_logic.executorBoundLogics.has(logic)) continue;
247
+ if (require_event_log.isTextLogic(logic)) {
248
+ if (require_event_log.executorBoundLogics.has(logic)) continue;
248
249
  if (!ctx.rebindable) throw unrebindableChildRequestError(ctx.childPath, stateName, src, logic.mode === "stream" ? "streaming text" : "text");
249
250
  if (logic.mode === "stream" && !executors.streamText) throw new Error(`createAgentRuntime: ${where} '${stateName}' invokes streaming text source '${src}' but no 'streamText' executor was provided to createAgentRuntime(...).`);
250
251
  if (logic.mode !== "stream" && !executors.generateText) throw new Error(`createAgentRuntime: ${where} '${stateName}' invokes text source '${src}' but no 'generateText' executor was provided to createAgentRuntime(...).`);
251
252
  continue;
252
253
  }
253
- if (require_text_logic.isUnboundPlaceholder(logic)) throw new Error(`createAgentRuntime: ${where} '${stateName}' invokes actor source '${src}', which has no host execution. Provide it via machine.provide({ actors: { '${src}': ... } }) or createAgentRuntime(machine, { actors: { '${src}': ... } }).`);
254
+ if (require_event_log.isUnboundPlaceholder(logic)) throw new Error(`createAgentRuntime: ${where} '${stateName}' invokes actor source '${src}', which has no host execution. Provide it via machine.provide({ actors: { '${src}': ... } }) or createAgentRuntime(machine, { actors: { '${src}': ... } }).`);
254
255
  }
255
256
  }
256
257
  /** Descends the bind-time walk into an invoked child state machine, guarding
@@ -264,7 +265,7 @@ function assertChildMachineBindable(childMachine, childSrc, stateName, executors
264
265
  isChild: true,
265
266
  childPath,
266
267
  rebindable: ctx.rebindable && typeof childSrc === "string",
267
- visited: new Set([...ctx.visited, childMachine])
268
+ visited: /* @__PURE__ */ new Set([...ctx.visited, childMachine])
268
269
  });
269
270
  }
270
271
  /** The loud bind-time error for an unbound agent request reached under a
@@ -395,11 +396,11 @@ function bindTextLogic(logic, runCtx) {
395
396
  ...id !== "" ? { requestId: id } : {},
396
397
  ...callKey !== void 0 ? { callKey } : {}
397
398
  });
398
- const output = await require_text_logic.normalizeGeneratorResult(raw, id);
399
+ const output = await require_event_log.normalizeGeneratorResult(raw, id);
399
400
  const rawReasoning = raw?.reasoning;
400
401
  const reasoning = typeof rawReasoning === "string" ? rawReasoning : void 0;
401
- const usage = require_text_logic.getCallUsage(raw);
402
- const finishReason = require_text_logic.getCallFinishReason(raw);
402
+ const usage = require_event_log.getCallUsage(raw);
403
+ const finishReason = require_event_log.getCallFinishReason(raw);
403
404
  if (usage) runCtx.recordUsage?.(usage, {
404
405
  kind: "text",
405
406
  ...id !== "" ? { id } : {},
@@ -418,7 +419,7 @@ function bindTextLogic(logic, runCtx) {
418
419
  }, self);
419
420
  return {
420
421
  result: output,
421
- messages: require_text_logic.responseMessagesOf(raw)
422
+ messages: require_event_log.responseMessagesOf(raw)
422
423
  };
423
424
  } catch (error) {
424
425
  runCtx.emitTrace?.({
@@ -451,8 +452,8 @@ function createCountingDecide(runCtx, self) {
451
452
  ...info?.requestId === void 0 && id !== "" ? { requestId: id } : {},
452
453
  ...info?.callKey === void 0 && callKey !== void 0 ? { callKey } : {}
453
454
  });
454
- const usage = require_text_logic.getCallUsage(result);
455
- const finishReason = require_text_logic.getCallFinishReason(result);
455
+ const usage = require_event_log.getCallUsage(result);
456
+ const finishReason = require_event_log.getCallFinishReason(result);
456
457
  if (usage) {
457
458
  const { src } = selfIdAndSrc(self);
458
459
  runCtx.recordUsage?.(usage, {
@@ -509,17 +510,53 @@ function bindDecisionLogic(logic, runCtx) {
509
510
  eventTypes: declaredEventTypes
510
511
  }) : [];
511
512
  const lowered = logic.request(input);
512
- const chosen = await require_decision.resolveDecision({
513
+ const request = {
513
514
  ...lowered,
514
515
  id,
515
516
  name: lowered.name ?? id,
516
517
  input,
517
518
  events
518
- }, { decide: createCountingDecide(runCtx, self) }, {
519
- maxRetries: logic.maxRetries,
519
+ };
520
+ const withheld = [];
521
+ const options = require_decision.acceptedDecisionOptions(request, (event) => {
522
+ let accepted;
523
+ try {
524
+ accepted = actorRef ? actorRef.getSnapshot().can(event) : true;
525
+ } catch {
526
+ accepted = false;
527
+ }
528
+ if (!accepted) withheld.push(event);
529
+ return accepted;
530
+ });
531
+ if (options) {
532
+ request.options = options;
533
+ request.withheld = withheld;
534
+ }
535
+ if (options?.length === 0) {
536
+ const error = new require_decision.AgentDecisionExhaustedError([]);
537
+ error.message = `Decision '${request.name}' has no offered option the current snapshot accepts; no model call was made.`;
538
+ runCtx.emitTrace?.({
539
+ type: "request.start",
540
+ request
541
+ }, self);
542
+ runCtx.emitTrace?.({
543
+ type: "request.error",
544
+ request,
545
+ error
546
+ }, self);
547
+ throw error;
548
+ }
549
+ const decide = createCountingDecide(runCtx, self);
550
+ let priorAttempts = [];
551
+ const chosen = await require_decision.resolveDecision(request, { decide: (attemptRequest, info) => {
552
+ priorAttempts = attemptRequest.attempts;
553
+ return decide(attemptRequest, info);
554
+ } }, {
555
+ maxRetries: lowered.maxRetries ?? logic.maxRetries,
520
556
  signal,
521
557
  canTake: (event) => actorRef ? actorRef.getSnapshot().can(event) : true
522
558
  });
559
+ if (priorAttempts.length > 0) runCtx.noteDecision?.(chosen, priorAttempts);
523
560
  actorRef?.send(chosen);
524
561
  await Promise.resolve();
525
562
  return chosen;
@@ -560,7 +597,7 @@ function rootTraceState(root) {
560
597
  if (!state) {
561
598
  const logic = root.logic;
562
599
  const machineId = (logic?.config)?.id ?? logic?.id ?? "(machine)";
563
- const machineVersion = logic ? require_text_logic.resolveMachineVersion(logic) : "";
600
+ const machineVersion = logic ? require_event_log.resolveMachineVersion(logic) : "";
564
601
  state = {
565
602
  runId: `run_${nextProvideRunId++}`,
566
603
  seq: 0,
@@ -619,13 +656,13 @@ function provideBindContext(machine, executors, options) {
619
656
  consumeModelCall: () => {},
620
657
  recordUsage: (usage, source, self) => {
621
658
  deliverUsageEvent({
622
- type: require_usage.AGENT_USAGE_EVENT_TYPE,
659
+ type: require_event_log.AGENT_USAGE_EVENT_TYPE,
623
660
  ...source,
624
661
  usage
625
662
  }, () => self?._parent);
626
663
  },
627
664
  actorHolder: { actorRef: void 0 },
628
- schemas: require_text_logic.getRegisteredAgentExecutionOptions(machine).schemas
665
+ schemas: require_event_log.getRegisteredAgentExecutionOptions(machine).schemas
629
666
  };
630
667
  }
631
668
  /**
@@ -702,12 +739,12 @@ function bindChildMachineForProvide(childMachine, executors, options, visited) {
702
739
  */
703
740
  function resolveMachineInput(machine, input) {
704
741
  if (input === void 0) return input;
705
- const schema = require_text_logic.getRegisteredAgentExecutionOptions(machine).schemas?.input;
706
- if (!require_text_logic.isStandardSchema(schema)) return input;
742
+ const schema = require_event_log.getRegisteredAgentExecutionOptions(machine).schemas?.input;
743
+ if (!require_event_log.isStandardSchema(schema)) return input;
707
744
  try {
708
- return require_text_logic.validateSchemaSync(schema, input);
745
+ return require_event_log.validateSchemaSync(schema, input);
709
746
  } catch (error) {
710
- throw new require_text_logic.AgentError("invalid-machine-input", `createAgentRuntime: machine input failed validation against the declared input schema: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
747
+ throw new require_event_log.AgentError("invalid-machine-input", `createAgentRuntime: machine input failed validation against the declared input schema: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
711
748
  }
712
749
  }
713
750
  /**
@@ -726,17 +763,17 @@ function resolveMachineInput(machine, input) {
726
763
  */
727
764
  function rebindChildMachine(childMachine, runCtx, visited, ctxFor) {
728
765
  if (visited.has(childMachine)) return childMachine;
729
- const childVisited = new Set([...visited, childMachine]);
766
+ const childVisited = /* @__PURE__ */ new Set([...visited, childMachine]);
730
767
  runCtx = ctxFor ? ctxFor(childMachine) : runCtx;
731
768
  const sources = childMachine.sources.actors;
732
769
  const wrapped = {};
733
770
  for (const [key, logic] of Object.entries(sources)) {
734
771
  if (require_decision.isDecisionLogic(logic)) {
735
- if (!require_text_logic.executorBoundLogics.has(logic)) wrapped[key] = bindDecisionLogic(logic, runCtx);
772
+ if (!require_event_log.executorBoundLogics.has(logic)) wrapped[key] = bindDecisionLogic(logic, runCtx);
736
773
  continue;
737
774
  }
738
- if (require_text_logic.isTextLogic(logic)) {
739
- if (!require_text_logic.executorBoundLogics.has(logic)) wrapped[key] = bindTextLogic(logic, runCtx);
775
+ if (require_event_log.isTextLogic(logic)) {
776
+ if (!require_event_log.executorBoundLogics.has(logic)) wrapped[key] = bindTextLogic(logic, runCtx);
740
777
  continue;
741
778
  }
742
779
  if (isStateMachineLogic(logic)) {
@@ -747,6 +784,15 @@ function rebindChildMachine(childMachine, runCtx, visited, ctxFor) {
747
784
  }
748
785
  return Object.keys(wrapped).length > 0 ? childMachine.provide({ actors: wrapped }) : childMachine;
749
786
  }
787
+ const timerId = (timer) => JSON.stringify(timer);
788
+ function toTimerInput(event) {
789
+ const id = event.id;
790
+ if (event.type !== "xstate.timer" || typeof id !== "string" || !id.startsWith("{")) return event;
791
+ return {
792
+ type: "xstate.timer",
793
+ ...JSON.parse(id)
794
+ };
795
+ }
750
796
  /**
751
797
  * The blocking host: opens the run, delivers `event` if given, then applies
752
798
  * every event that arrives until the run is quiescent, and returns the
@@ -757,7 +803,7 @@ async function runToQuiescence(runtime, init = {}) {
757
803
  let [state, effects] = await runtime.start(init);
758
804
  await runtime.execute(effects);
759
805
  if (init.event !== void 0 && state.status === "active") {
760
- [state, effects] = runtime.transition(state, init.event);
806
+ [state, effects] = runtime.transition(state, init.event, init.attempts !== void 0 ? { attempts: init.attempts } : void 0);
761
807
  await runtime.execute(effects);
762
808
  }
763
809
  for (let event; event = await runtime.nextEvent();) {
@@ -767,6 +813,52 @@ async function runToQuiescence(runtime, init = {}) {
767
813
  return runtime.finish();
768
814
  }
769
815
  /**
816
+ * Runs `machine` to quiescence in one call: {@link createAgentRuntime} over
817
+ * `options`, then {@link runToQuiescence} with the same object as its init.
818
+ * One options object carries both halves (`executors`, `store`, callbacks,
819
+ * and `input` | `snapshot` + `event`), and the result is the same
820
+ * {@link AgentRunResult}. With {@link AgentRunOptions.onIdle}, idle states are
821
+ * answered in place and the call returns only `done` or `error`.
822
+ *
823
+ * Reach for {@link createAgentRuntime} directly when the host needs the loop
824
+ * itself: a non-blocking durable host, events pushed mid-run, or a custom stop
825
+ * or checkpoint policy.
826
+ *
827
+ * @example
828
+ * ```ts
829
+ * const result = await runAgent(machine, { input: { topic }, executors });
830
+ * if (result.status === "done") console.log(result.output);
831
+ * ```
832
+ *
833
+ * @example
834
+ * ```ts
835
+ * // Resume a run a request handler left idle.
836
+ * const result = await runAgent(machine, { executors, snapshot, event });
837
+ * ```
838
+ */
839
+ async function runAgent(machine, options = {}) {
840
+ const { onIdle, ...rest } = options;
841
+ let result = await runToQuiescence(createAgentRuntime(machine, rest), rest);
842
+ if (!onIdle) return result;
843
+ const maxModelCalls = rest.maxModelCalls ?? 100;
844
+ let modelCalls = result.usage.modelCalls;
845
+ const { input: _input, events: _events, attempts: _attempts, ...resumeOptions } = rest;
846
+ while (result.status === "idle" && result.ignored === void 0) {
847
+ const event = await onIdle(result.snapshot);
848
+ result = await runToQuiescence(createAgentRuntime(machine, {
849
+ ...resumeOptions,
850
+ maxModelCalls: maxModelCalls - modelCalls
851
+ }), {
852
+ ...resumeOptions,
853
+ ...rest.store === void 0 ? { events: result.events } : {},
854
+ snapshot: result.persist(),
855
+ event
856
+ });
857
+ modelCalls += result.usage.modelCalls;
858
+ }
859
+ return result;
860
+ }
861
+ /**
770
862
  * Entry-by-entry check that the caller's `events` IS the store's thread. Equal
771
863
  * lengths prove nothing: a fork, a rolled-back replay, or a concurrent writer
772
864
  * that appended and truncated all produce a divergent log of the same size,
@@ -778,7 +870,7 @@ function assertThreadMatchesEvents(threadId, stored, events) {
778
870
  const givenEntry = events[index];
779
871
  const storedHash = storedEntry.verification?.stateHash;
780
872
  const givenHash = givenEntry.verification?.stateHash;
781
- if (!(storedEntry.id === givenEntry.id && storedEntry.index === givenEntry.index && require_event_log_store.canonicalEventJson(storedEntry.event) === require_event_log_store.canonicalEventJson(givenEntry.event) && (storedHash === void 0 || givenHash === void 0 || storedHash === givenHash))) throw new require_text_logic.AgentError("event-log-conflict", `createAgentRuntime: the given \`events\` diverge from thread "${threadId}" at index ${index} (stored entry '${storedEntry.id}', given '${givenEntry.id}') — the log passed in is not this thread's log.`);
873
+ if (!(storedEntry.id === givenEntry.id && storedEntry.index === givenEntry.index && require_event_log.canonicalEventJson(storedEntry.event) === require_event_log.canonicalEventJson(givenEntry.event) && (storedHash === void 0 || givenHash === void 0 || storedHash === givenHash))) throw new require_event_log.AgentError("event-log-conflict", `createAgentRuntime: the given \`events\` diverge from thread "${threadId}" at index ${index} (stored entry '${storedEntry.id}', given '${givenEntry.id}') — the log passed in is not this thread's log.`);
782
874
  }
783
875
  }
784
876
  const QUIESCENT = Symbol("quiescent");
@@ -805,7 +897,7 @@ const QUIESCENT = Symbol("quiescent");
805
897
  * while (r.status === 'idle') {
806
898
  * const event = await promptUser(getAcceptedEvents(r.snapshot));
807
899
  * r = await runToQuiescence(createAgentRuntime(machine, { executors }), {
808
- * snapshot: r.snapshot,
900
+ * snapshot: r.persist(),
809
901
  * event,
810
902
  * });
811
903
  * }
@@ -825,7 +917,9 @@ function createAgentRuntime(machine, options = {}) {
825
917
  const runId = `run_${nextRunAgentTraceId++}`;
826
918
  let traceSeq = 0;
827
919
  const machineId = machine.config.id ?? machine.id ?? "(machine)";
828
- const machineVersion = require_text_logic.resolveMachineVersion(machine);
920
+ const machineVersion = require_event_log.resolveMachineVersion(machine);
921
+ if (options.metadata !== void 0) require_event_log.assertJsonSerializable(options.metadata, "metadata");
922
+ const initMetadata = options.metadata === void 0 ? void 0 : structuredClone(options.metadata);
829
923
  const onTrace = createTraceDispatch({
830
924
  onTrace: (payload) => {
831
925
  options.onTrace?.({
@@ -853,7 +947,7 @@ function createAgentRuntime(machine, options = {}) {
853
947
  const logEntries = [];
854
948
  const store = options.store;
855
949
  const threadId = options.threadId;
856
- if (store !== void 0 && (threadId === void 0 || threadId === "")) throw new require_text_logic.AgentError("missing-thread-id", "createAgentRuntime: `threadId` is required when `store` is given — it names the log thread to read and append to.");
950
+ if (store !== void 0 && (threadId === void 0 || threadId === "")) throw new require_event_log.AgentError("missing-thread-id", "createAgentRuntime: `threadId` is required when `store` is given — it names the log thread to read and append to.");
857
951
  let journalChain = Promise.resolve();
858
952
  let journalPending = 0;
859
953
  let journalError;
@@ -904,24 +998,32 @@ function createAgentRuntime(machine, options = {}) {
904
998
  let current;
905
999
  let logMachine = machine;
906
1000
  let loggingEnabled = true;
907
- const appendLogEntry = (event, snapshot) => {
1001
+ const attemptsByEvent = /* @__PURE__ */ new WeakMap();
1002
+ let logFold;
1003
+ const appendLogEntry = (event, attempts) => {
908
1004
  if (!loggingEnabled) return;
909
- const entry = require_event_log_store.createReplayEntry(logMachine, logEntries, event, {
1005
+ const entry = require_event_log.createReplayEntry(logMachine, logEntries, event, {
910
1006
  machineVersion,
911
- verification: verificationEnabled,
912
- ...verificationEnabled && snapshot !== void 0 ? { snapshot } : {}
1007
+ verification: false,
1008
+ ...attempts !== void 0 ? { attempts } : {}
913
1009
  });
1010
+ if (verificationEnabled && logFold !== null) try {
1011
+ logFold ??= require_event_log.foldLog(logMachine, logEntries, {
1012
+ machineVersion,
1013
+ verify: false
1014
+ });
1015
+ entry.verification = { stateHash: require_event_log.getSnapshotStateHash(logFold.apply(entry)) };
1016
+ } catch {
1017
+ logFold = null;
1018
+ }
914
1019
  logEntries.push(entry);
915
1020
  journalEntry(entry);
916
1021
  options.onEvent?.(entry);
917
1022
  return entry;
918
1023
  };
919
- const usageEntrySnapshot = () => {
920
- if (current && (current.status !== "active" || !declaresUsageTransition(current))) return current;
921
- };
922
1024
  const recordUsage = (usage, source = {}) => {
923
1025
  const event = {
924
- type: require_usage.AGENT_USAGE_EVENT_TYPE,
1026
+ type: require_event_log.AGENT_USAGE_EVENT_TYPE,
925
1027
  ...source,
926
1028
  usage
927
1029
  };
@@ -935,17 +1037,17 @@ function createAgentRuntime(machine, options = {}) {
935
1037
  });
936
1038
  return true;
937
1039
  });
938
- if (!delivered) appendLogEntry(event, usageEntrySnapshot());
1040
+ if (!delivered) appendLogEntry(event);
939
1041
  };
940
1042
  const runUsage = () => ({
941
- ...require_event_log_store.getUsageFromEvents(logEntries.slice(resumedLogLength)),
1043
+ ...require_event_log.getUsageFromEvents(logEntries.slice(resumedLogLength)),
942
1044
  modelCalls: modelCallCount
943
1045
  });
944
1046
  const warnNonSerializableContext = (snapshot) => {
945
1047
  if (warnedNonSerializable || process.env.NODE_ENV === "production") return;
946
1048
  let offending = [];
947
1049
  try {
948
- offending = require_text_logic.findNonSerializableContextPaths(snapshot.context);
1050
+ offending = require_event_log.findNonSerializableContextPaths(snapshot.context);
949
1051
  } catch {
950
1052
  return;
951
1053
  }
@@ -976,7 +1078,15 @@ function createAgentRuntime(machine, options = {}) {
976
1078
  actorHolder,
977
1079
  awaitJournal,
978
1080
  runId,
979
- schemas: require_text_logic.getRegisteredAgentExecutionOptions(machine).schemas
1081
+ schemas: require_event_log.getRegisteredAgentExecutionOptions(machine).schemas,
1082
+ noteDecision: (event, attempts) => {
1083
+ try {
1084
+ require_event_log.assertJsonSerializable(attempts, "attempts");
1085
+ } catch {
1086
+ return;
1087
+ }
1088
+ attemptsByEvent.set(event, attempts);
1089
+ }
980
1090
  };
981
1091
  const wrappedSources = {};
982
1092
  for (const [key, logic] of Object.entries(effectiveSources)) {
@@ -984,12 +1094,12 @@ function createAgentRuntime(machine, options = {}) {
984
1094
  wrappedSources[key] = bindDecisionLogic(logic, runCtx);
985
1095
  continue;
986
1096
  }
987
- if (require_text_logic.isTextLogic(logic)) {
988
- if (!require_text_logic.executorBoundLogics.has(logic)) wrappedSources[key] = bindTextLogic(logic, runCtx);
1097
+ if (require_event_log.isTextLogic(logic)) {
1098
+ if (!require_event_log.executorBoundLogics.has(logic)) wrappedSources[key] = bindTextLogic(logic, runCtx);
989
1099
  continue;
990
1100
  }
991
1101
  if (isStateMachineLogic(logic)) {
992
- const rebound = rebindChildMachine(logic, runCtx, new Set([machine]));
1102
+ const rebound = rebindChildMachine(logic, runCtx, /* @__PURE__ */ new Set([machine]));
993
1103
  if (rebound !== logic) wrappedSources[key] = rebound;
994
1104
  continue;
995
1105
  }
@@ -1014,7 +1124,8 @@ function createAgentRuntime(machine, options = {}) {
1014
1124
  const inProcessTimers = options.timers === void 0 || options.timers === "in-process";
1015
1125
  const timerHandles = /* @__PURE__ */ new Map();
1016
1126
  const timerKey = (source, id) => `${source?.address ?? "(root)"}::${id}`;
1017
- const armTimer = (source, isRoot, id, delay) => {
1127
+ const armTimer = (source, isRoot, timer, delay) => {
1128
+ const id = timerId(timer);
1018
1129
  if (isRoot && !inProcessTimers) {
1019
1130
  options.timers.schedule({
1020
1131
  id,
@@ -1028,7 +1139,7 @@ function createAgentRuntime(machine, options = {}) {
1028
1139
  timerHandles.delete(key);
1029
1140
  const timerEvent = {
1030
1141
  type: "xstate.timer",
1031
- id
1142
+ ...timer
1032
1143
  };
1033
1144
  if (isRoot) enqueue(timerEvent);
1034
1145
  else source?.send(timerEvent);
@@ -1113,10 +1224,11 @@ function createAgentRuntime(machine, options = {}) {
1113
1224
  if (source.address === execution.rootAddress) emitFromRoot(event);
1114
1225
  else source._emit?.(event);
1115
1226
  },
1116
- scheduleTimer: (source, id, delay) => {
1117
- armTimer(source, source.address === execution.rootAddress, id, delay);
1227
+ scheduleTimer: (source, timer, delay) => {
1228
+ armTimer(source, source.address === execution.rootAddress, timer, delay);
1118
1229
  },
1119
- cancelTimer: (source, id) => {
1230
+ cancelTimer: (source, timer) => {
1231
+ const id = timerId(timer);
1120
1232
  const isRoot = source.address === execution.rootAddress;
1121
1233
  if (isRoot && !inProcessTimers) {
1122
1234
  options.timers.cancel(id);
@@ -1127,7 +1239,8 @@ function createAgentRuntime(machine, options = {}) {
1127
1239
  timerHandles.delete(key);
1128
1240
  },
1129
1241
  cancelAllTimers: (source) => {
1130
- const prefix = timerKey(source.address === execution.rootAddress ? void 0 : source, "");
1242
+ const isRoot = source.address === execution.rootAddress;
1243
+ const prefix = timerKey(isRoot ? void 0 : source, "");
1131
1244
  for (const [key, handle] of timerHandles) if (key.startsWith(prefix)) {
1132
1245
  clearTimeout(handle);
1133
1246
  timerHandles.delete(key);
@@ -1136,9 +1249,11 @@ function createAgentRuntime(machine, options = {}) {
1136
1249
  }, inspect ? { inspect } : void 0);
1137
1250
  const runErrorCause = (error) => budgetExceeded ? "max-model-calls" : wrapsDecisionExhausted(error) ? "decision-exhausted" : "machine";
1138
1251
  const commit = (snapshot, event) => {
1252
+ const from = { value: (current ?? snapshot).value };
1139
1253
  current = snapshot;
1140
1254
  onTrace({
1141
1255
  type: "machine.transition",
1256
+ from,
1142
1257
  snapshot,
1143
1258
  event
1144
1259
  });
@@ -1151,7 +1266,7 @@ function createAgentRuntime(machine, options = {}) {
1151
1266
  };
1152
1267
  return {
1153
1268
  async start(init = {}) {
1154
- if (started) throw new require_text_logic.AgentError("runtime-started", "createAgentRuntime: `start` was already called.");
1269
+ if (started) throw new require_event_log.AgentError("runtime-started", "createAgentRuntime: `start` was already called.");
1155
1270
  started = true;
1156
1271
  let resumeEvents = init.events;
1157
1272
  if (store !== void 0) {
@@ -1180,7 +1295,7 @@ function createAgentRuntime(machine, options = {}) {
1180
1295
  */
1181
1296
  const appendInitEntry = (candidates, metadata) => {
1182
1297
  for (const candidate of candidates) for (const verification of verificationEnabled ? [true, false] : [false]) try {
1183
- const entry = require_event_log_store.initEntry(logMachine, candidate, {
1298
+ const entry = require_event_log.initEntry(logMachine, candidate, {
1184
1299
  machineVersion,
1185
1300
  verification,
1186
1301
  metadata
@@ -1198,10 +1313,10 @@ function createAgentRuntime(machine, options = {}) {
1198
1313
  return [...restored !== void 0 ? [{ snapshot: restored }] : [], { snapshot: init.snapshot }];
1199
1314
  };
1200
1315
  if (resumeEvents !== void 0 && resumeEvents.length > 0) {
1201
- require_event_log_store.validateReplayEntries(resumeEvents);
1316
+ require_event_log.validateReplayEntries(resumeEvents);
1202
1317
  const tail = resumeEvents[resumeEvents.length - 1];
1203
- const inheritedExecutionId = require_event_log_store.getLogExecutionId(resumeEvents);
1204
- if (resumeEvents[0].machineId !== machineId) throw new require_event_log_store.AgentMachineVersionMismatchError(tail.id, tail.index, {
1318
+ const inheritedExecutionId = require_event_log.getLogExecutionId(resumeEvents);
1319
+ if (resumeEvents[0].machineId !== machineId) throw new require_event_log.AgentMachineVersionMismatchError(tail.id, tail.index, {
1205
1320
  machineId,
1206
1321
  machineVersion
1207
1322
  }, {
@@ -1217,20 +1332,22 @@ function createAgentRuntime(machine, options = {}) {
1217
1332
  if (!(init.snapshot !== void 0 && inheritedExecutionId !== void 0 && cachedMeta?.logId === inheritedExecutionId && cachedMeta.logIndex === resumeEvents.length && tailStateHash !== void 0 && hashResumeSnapshot(init.snapshot) === tailStateHash)) {
1218
1333
  const cachedIndex = cachedMeta?.logIndex;
1219
1334
  if (init.snapshot !== void 0 && typeof cachedIndex === "number" && cachedIndex >= 1 && cachedIndex <= resumeEvents.length && resumeEvents[cachedIndex - 1].verification?.stateHash !== void 0) {
1220
- const expected = require_event_log_store.getSnapshotStateHash(require_event_log_store.replay(logMachine, resumeEvents.slice(0, cachedIndex), {
1335
+ const atCache = require_event_log.replay(logMachine, resumeEvents.slice(0, cachedIndex), {
1221
1336
  machineVersion,
1222
1337
  verify: false
1223
- }).persistedSnapshot);
1338
+ });
1339
+ const expected = require_event_log.getSnapshotStateHash(atCache.persistedSnapshot);
1224
1340
  const actual = hashResumeSnapshot(init.snapshot);
1225
1341
  if (expected !== actual) throw new AgentSnapshotDivergedError(expected, actual, cachedIndex);
1226
1342
  }
1227
- effectiveSnapshot = require_event_log_store.replay(logMachine, resumeEvents, {
1343
+ logFold = require_event_log.foldLog(logMachine, resumeEvents, {
1228
1344
  machineVersion,
1229
1345
  verify: true
1230
- }).persistedSnapshot;
1346
+ });
1347
+ effectiveSnapshot = logFold.persistedSnapshot;
1231
1348
  }
1232
1349
  } else {
1233
- if (init.snapshot === void 0) throw new require_event_log_store.AgentMachineVersionMismatchError(tail.id, tail.index, {
1350
+ if (init.snapshot === void 0) throw new require_event_log.AgentMachineVersionMismatchError(tail.id, tail.index, {
1234
1351
  machineId,
1235
1352
  machineVersion
1236
1353
  }, {
@@ -1238,7 +1355,7 @@ function createAgentRuntime(machine, options = {}) {
1238
1355
  machineVersion: tail.machineVersion
1239
1356
  });
1240
1357
  const bridgeMeta = readAgentMeta(init.snapshot);
1241
- if (inheritedExecutionId === void 0 || bridgeMeta?.logId !== inheritedExecutionId) throw new require_event_log_store.AgentMachineVersionMismatchError(tail.id, tail.index, {
1358
+ if (inheritedExecutionId === void 0 || bridgeMeta?.logId !== inheritedExecutionId) throw new require_event_log.AgentMachineVersionMismatchError(tail.id, tail.index, {
1242
1359
  machineId,
1243
1360
  machineVersion
1244
1361
  }, {
@@ -1255,16 +1372,23 @@ function createAgentRuntime(machine, options = {}) {
1255
1372
  logIndex: resumeEvents.length
1256
1373
  };
1257
1374
  seedInitEntry = () => appendInitEntry(snapshotInitCandidates(), {
1375
+ ...initMetadata,
1258
1376
  ...logExecutionId !== void 0 ? { executionId: logExecutionId } : {},
1259
1377
  migratedFrom
1260
1378
  });
1261
1379
  }
1262
1380
  } else if (init.snapshot !== void 0) {
1263
1381
  logExecutionId = crypto.randomUUID();
1264
- seedInitEntry = () => appendInitEntry(snapshotInitCandidates(), { executionId: logExecutionId });
1382
+ seedInitEntry = () => appendInitEntry(snapshotInitCandidates(), {
1383
+ ...initMetadata,
1384
+ executionId: logExecutionId
1385
+ });
1265
1386
  } else {
1266
1387
  logExecutionId = crypto.randomUUID();
1267
- seedInitEntry = () => appendInitEntry([resolvedInput !== void 0 ? { input: resolvedInput } : {}], { executionId: logExecutionId });
1388
+ seedInitEntry = () => appendInitEntry([resolvedInput !== void 0 ? { input: resolvedInput } : {}], {
1389
+ ...initMetadata,
1390
+ executionId: logExecutionId
1391
+ });
1268
1392
  }
1269
1393
  const resumedHistory = [...logEntries];
1270
1394
  const siteCallCounts = /* @__PURE__ */ new Map();
@@ -1275,7 +1399,7 @@ function createAgentRuntime(machine, options = {}) {
1275
1399
  if (memoized !== void 0) return memoized;
1276
1400
  const startedHere = siteCallCounts.get(siteId) ?? 0;
1277
1401
  siteCallCounts.set(siteId, startedHere + 1);
1278
- const key = `${logExecutionId}:${siteId}#${require_event_log_store.agentCallOccurrence(resumedHistory, siteId) + startedHere}`;
1402
+ const key = `${logExecutionId}:${siteId}#${require_event_log.agentCallOccurrence(resumedHistory, siteId) + startedHere}`;
1279
1403
  if (self !== void 0) mintedCallKeys.set(self, key);
1280
1404
  return key;
1281
1405
  };
@@ -1287,11 +1411,13 @@ function createAgentRuntime(machine, options = {}) {
1287
1411
  ...effectiveSnapshot !== void 0 ? { snapshot: effectiveSnapshot } : {},
1288
1412
  ...resumeEvent !== void 0 ? { event: resumeEvent } : {}
1289
1413
  });
1290
- if (options.signal) if (options.signal.aborted) stopReason = {
1291
- cause: "aborted",
1292
- error: options.signal.reason ?? /* @__PURE__ */ new Error("Aborted")
1293
- };
1294
- else options.signal.addEventListener("abort", onAbort);
1414
+ if (options.signal) {
1415
+ if (options.signal.aborted) stopReason = {
1416
+ cause: "aborted",
1417
+ error: options.signal.reason ?? /* @__PURE__ */ new Error("Aborted")
1418
+ };
1419
+ else options.signal.addEventListener("abort", onAbort);
1420
+ }
1295
1421
  let snapshot;
1296
1422
  let effects = [];
1297
1423
  const initEvent = {
@@ -1323,12 +1449,15 @@ function createAgentRuntime(machine, options = {}) {
1323
1449
  commit(snapshot, initEvent);
1324
1450
  return [snapshot, effects];
1325
1451
  },
1326
- transition(state, event) {
1327
- if (finished) throw new require_text_logic.AgentError("runtime-finished", "createAgentRuntime: the run has finished; start a new runtime to continue.");
1452
+ transition(state, event, transitionOptions) {
1453
+ if (finished) throw new require_event_log.AgentError("runtime-finished", "createAgentRuntime: the run has finished; start a new runtime to continue.");
1328
1454
  if (stopReason !== void 0) return [state, []];
1455
+ event = toTimerInput(event);
1456
+ const attempts = transitionOptions?.attempts ?? attemptsByEvent.get(event);
1457
+ if (transitionOptions?.attempts !== void 0) require_event_log.assertJsonSerializable(transitionOptions.attempts, "attempts");
1329
1458
  const [next, effects] = execution.transition(state, event);
1330
1459
  if (!fromMailbox.has(event) && next === state && effects.length === 0) ignoredEvent = event;
1331
- appendLogEntry(event, next);
1460
+ appendLogEntry(event, attempts);
1332
1461
  commit(next, event);
1333
1462
  return [next, effects];
1334
1463
  },
@@ -1354,7 +1483,7 @@ function createAgentRuntime(machine, options = {}) {
1354
1483
  }
1355
1484
  },
1356
1485
  async finish() {
1357
- if (finished) throw new require_text_logic.AgentError("runtime-finished", "createAgentRuntime: `finish` was already called.");
1486
+ if (finished) throw new require_event_log.AgentError("runtime-finished", "createAgentRuntime: `finish` was already called.");
1358
1487
  const snapshot = current;
1359
1488
  let outcome;
1360
1489
  if (stopReason !== void 0) outcome = {
@@ -1460,7 +1589,8 @@ function inspectTransitions(handler) {
1460
1589
  * ```
1461
1590
  *
1462
1591
  * Only ROOT-actor transitions are traced (matching the runtime's
1463
- * `machine.transition`); child-actor transitions are ignored. Attribute the
1592
+ * `machine.transition`); child-actor transitions are ignored. Each event's
1593
+ * `from.value` is the root's previous state value, tracked per root actor. Attribute the
1464
1594
  * event via its envelope `runId`.
1465
1595
  *
1466
1596
  * By design this path has NO `run.start`/`run.end` events: `createActor` has no
@@ -1471,13 +1601,19 @@ function inspectTransitions(handler) {
1471
1601
  * with `actor.on('*', ...)` if you need them.
1472
1602
  */
1473
1603
  function traceTransitions(onTrace) {
1604
+ const lastValue = /* @__PURE__ */ new WeakMap();
1474
1605
  return (inspectionEvent) => {
1475
1606
  if (inspectionEvent.type !== "@xstate.transition") return;
1476
1607
  const actorRef = inspectionEvent.actorRef;
1477
1608
  if (actorRef?._parent) return;
1478
- onTrace(stampRootTrace(actorRef, {
1609
+ const root = actorRef;
1610
+ const snapshot = inspectionEvent.snapshot;
1611
+ const from = { value: lastValue.get(root) ?? snapshot.value };
1612
+ lastValue.set(root, snapshot.value);
1613
+ onTrace(stampRootTrace(root, {
1479
1614
  type: "machine.transition",
1480
- snapshot: inspectionEvent.snapshot,
1615
+ from,
1616
+ snapshot,
1481
1617
  event: inspectionEvent.event
1482
1618
  }));
1483
1619
  };
@@ -1565,6 +1701,12 @@ Object.defineProperty(exports, "isStateMachineLogic", {
1565
1701
  return isStateMachineLogic;
1566
1702
  }
1567
1703
  });
1704
+ Object.defineProperty(exports, "runAgent", {
1705
+ enumerable: true,
1706
+ get: function() {
1707
+ return runAgent;
1708
+ }
1709
+ });
1568
1710
  Object.defineProperty(exports, "runToQuiescence", {
1569
1711
  enumerable: true,
1570
1712
  get: function() {