@statelyai/agent 2.0.0-alpha.17 → 2.0.0-alpha.19

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 (38) hide show
  1. package/dist/ai-sdk.cjs +4 -2
  2. package/dist/ai-sdk.d.cts +1 -1
  3. package/dist/ai-sdk.d.mts +1 -1
  4. package/dist/ai-sdk.mjs +3 -2
  5. package/dist/{decision-C11xuud2.mjs → decision-DsIkEuHz.mjs} +48 -28
  6. package/dist/{decision-DnQCQPew.cjs → decision-t26zsnSR.cjs} +64 -43
  7. package/dist/{event-log-store-CQJq8_v4.d.cts → event-log-store-Bz7HDBkE.d.cts} +11 -12
  8. package/dist/{event-log-store-B-1fcfkT.mjs → event-log-store-DmIDosD6.mjs} +22 -14
  9. package/dist/{event-log-store-yquOV1TX.cjs → event-log-store-a_TKy1gk.cjs} +22 -14
  10. package/dist/{event-log-store-BrC9Q1xW.d.mts → event-log-store-hrA1vqtN.d.mts} +11 -12
  11. package/dist/index.cjs +266 -109
  12. package/dist/index.d.cts +148 -80
  13. package/dist/index.d.mts +148 -80
  14. package/dist/index.mjs +262 -107
  15. package/dist/machines.cjs +13 -17
  16. package/dist/machines.d.cts +14 -17
  17. package/dist/machines.d.mts +14 -17
  18. package/dist/machines.mjs +13 -17
  19. package/dist/otel.cjs +1 -0
  20. package/dist/otel.d.cts +1 -1
  21. package/dist/otel.d.mts +1 -1
  22. package/dist/{run-agent-BxjGaVpL.d.cts → run-agent--4bbms-D.d.cts} +121 -48
  23. package/dist/{run-agent-COHoCgQd.d.mts → run-agent-CwmzAZwj.d.mts} +121 -48
  24. package/dist/{setup-agent-D_EyJ0Ik.cjs → setup-agent-BFA4VKpN.cjs} +51 -33
  25. package/dist/{setup-agent-CTg57Pa4.mjs → setup-agent-CPFPN06s.mjs} +45 -28
  26. package/dist/sqlite.cjs +3 -9
  27. package/dist/sqlite.d.cts +1 -1
  28. package/dist/sqlite.d.mts +1 -1
  29. package/dist/sqlite.mjs +3 -9
  30. package/dist/{text-logic-BFX5q7fM.d.cts → text-logic-Cavva1W6.d.cts} +25 -9
  31. package/dist/{text-logic-DQW8_DWW.d.mts → text-logic-Er5KkTX6.d.mts} +25 -9
  32. package/dist/validate.cjs +436 -0
  33. package/dist/validate.d.cts +31 -0
  34. package/dist/validate.d.mts +31 -0
  35. package/dist/validate.mjs +411 -0
  36. package/package.json +15 -1
  37. package/schemas/agent-workflow.json +2 -2
  38. package/skills/generate-machine/SKILL.md +12 -14
package/dist/index.cjs CHANGED
@@ -1,8 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_errors = require("./errors-DUBBzRLP.cjs");
3
- const require_setup_agent = require("./setup-agent-D_EyJ0Ik.cjs");
4
- const require_decision = require("./decision-DnQCQPew.cjs");
5
- const require_event_log_store = require("./event-log-store-yquOV1TX.cjs");
3
+ const require_setup_agent = require("./setup-agent-BFA4VKpN.cjs");
4
+ const require_decision = require("./decision-t26zsnSR.cjs");
5
+ const require_event_log_store = require("./event-log-store-a_TKy1gk.cjs");
6
+ require("./validate.cjs");
6
7
  let xstate = require("xstate");
7
8
  //#region src/internal/state-request-pass.ts
8
9
  async function runTextPhase(stateRequest, baseMessages, deps) {
@@ -103,7 +104,7 @@ async function runAdvancePhase(plan, deps) {
103
104
  messages: [...deps.messages],
104
105
  events,
105
106
  attempts: []
106
- }, deps.decide, {
107
+ }, { decide: deps.decide }, {
107
108
  signal: deps.signal,
108
109
  canTake: (event) => deps.getSnapshot().can(event)
109
110
  });
@@ -139,8 +140,7 @@ async function runStateRequestPass(requests, deps) {
139
140
  * {@link getAcceptedEvents}). A programmer/integration error, in the same
140
141
  * class as runAgent's bind-time throws — it throws rather than settling an
141
142
  * `error` result. A type-legal event a guard rejects is NOT this error (the
142
- * machine simply takes no transition). Opt out with
143
- * {@link RunAgentOptions.onIllegalResumeEvent} `'ignore'`.
143
+ * machine simply takes no transition). Always enforced; there is no opt-out.
144
144
  */
145
145
  var AgentIllegalResumeEventError = class extends require_errors.AgentError {
146
146
  eventType;
@@ -258,7 +258,7 @@ function toJsonValue(value, ancestors) {
258
258
  * in a JSONL file). Live values are sanitized rather than trusted:
259
259
  *
260
260
  * - Snapshots (`run.start`, `machine.transition`, `run.end`) go through the
261
- * same JSON round-trip as {@link persistSnapshot}, so what lands on disk is
261
+ * same JSON round-trip as `machine.getPersistedSnapshot(...)`, so what lands on disk is
262
262
  * what a resume would see.
263
263
  * - `request.end`'s `raw` (a provider SDK object, frequently cyclic) is DROPPED
264
264
  * unless `includeRaw` is set, in which case it is sanitized like everything
@@ -285,11 +285,92 @@ function serializeTraceEvent(event, options = {}) {
285
285
  }
286
286
  return out;
287
287
  }
288
+ function snapshotNodes(snapshot) {
289
+ return (snapshot._nodes ?? []).map((raw) => {
290
+ const node = raw;
291
+ return {
292
+ id: node.id ?? "",
293
+ key: node.key ?? "",
294
+ ...node.description !== void 0 ? { description: node.description } : {},
295
+ tags: [...node.tags ?? []],
296
+ ...node.meta !== void 0 ? { meta: node.meta } : {},
297
+ ownEvents: [...node.ownEvents ?? []],
298
+ leaf: Object.keys(node.states ?? {}).length === 0
299
+ };
300
+ });
301
+ }
302
+ /**
303
+ * The active state nodes of a snapshot, as plain {@link AgentSnapshotNode}
304
+ * descriptors. The escape hatch under {@link getSnapshotRequests}: use it when
305
+ * your `getRequests` hook needs to build requests some other way, so host code
306
+ * never touches xstate's private `snapshot._nodes`.
307
+ */
308
+ function getSnapshotNodes(snapshot) {
309
+ return snapshotNodes(snapshot);
310
+ }
311
+ /**
312
+ * Builds the {@link AgentStateRequest}s for a snapshot straight from its active
313
+ * state nodes — the prompts-in-descriptions recipe as a function, so a
314
+ * {@link RunAgentOptions.getRequests} hook is one line and never reaches into
315
+ * xstate's private `snapshot._nodes`:
316
+ *
317
+ * ```ts
318
+ * runAgent(machine, {
319
+ * executors,
320
+ * getRequests: (snapshot) => getSnapshotRequests(snapshot, { model: 'writer' }),
321
+ * });
322
+ * ```
323
+ *
324
+ * Each described active node becomes one request: `prompt` from the node's
325
+ * `description`, `kind: 'decision'` when it is tagged `'decision'`, `system`
326
+ * from `meta.role` when present, `allowedEvents` scoped to the node's own
327
+ * events, and an explicit `onDone` when the node has exactly one own event
328
+ * (single-outcome states advance deterministically; anything else falls
329
+ * through to a `decide` call). Nodes tagged `'waiting'` produce nothing, so the
330
+ * run settles idle for a human. Override any of it with `filter`/`map`.
331
+ */
332
+ function getSnapshotRequests(snapshot, options) {
333
+ const filter = options.filter ?? ((node) => !!node.description && !node.tags.includes("waiting"));
334
+ const requests = [];
335
+ for (const node of snapshotNodes(snapshot)) {
336
+ if (!filter(node)) continue;
337
+ const system = node.meta?.role;
338
+ const request = {
339
+ model: options.model,
340
+ prompt: node.description ?? "",
341
+ kind: node.tags.includes("decision") ? "decision" : "text",
342
+ ...system !== void 0 ? { system } : {},
343
+ ...node.ownEvents.length > 0 ? { allowedEvents: node.ownEvents } : {},
344
+ ...node.ownEvents.length === 1 ? { onDone: { type: node.ownEvents[0] } } : {}
345
+ };
346
+ const mapped = options.map ? options.map(request, node) : request;
347
+ if (mapped) requests.push(mapped);
348
+ }
349
+ return requests;
350
+ }
288
351
  let nextRunAgentTraceId = 1;
352
+ /**
353
+ * Thrown into the invoke that would have made the call once
354
+ * {@link RunAgentOptions.maxModelCalls} is spent. It reaches the machine
355
+ * through the normal error channel, so an invoke's `onError` can branch on it
356
+ * (`error.code === 'max-model-calls'`, the same string the settled result's
357
+ * `cause` uses) and route to a degraded/finish state instead of failing the
358
+ * run. Unhandled, it settles `{ status: 'error', cause: 'max-model-calls' }`.
359
+ *
360
+ * ```ts
361
+ * onError: [
362
+ * { guard: ({ event }) => event.error?.code === 'max-model-calls', target: 'budgetSpent' },
363
+ * { target: 'failed' },
364
+ * ]
365
+ * ```
366
+ */
289
367
  var AgentMaxModelCallsExceededError = class extends require_errors.AgentError {
290
- constructor() {
291
- super("max-model-calls-exceeded", "runAgent exceeded maxModelCalls.");
368
+ /** The budget that was exceeded (`options.maxModelCalls`). */
369
+ maxModelCalls;
370
+ constructor(maxModelCalls) {
371
+ super("max-model-calls", `runAgent exceeded maxModelCalls (${maxModelCalls}). Raise the budget, or handle it in the invoke's onError (error.code === 'max-model-calls').`);
292
372
  this.name = "AgentMaxModelCallsExceededError";
373
+ this.maxModelCalls = maxModelCalls;
293
374
  }
294
375
  };
295
376
  function wrapsDecisionExhausted(error) {
@@ -329,7 +410,7 @@ function collectConfiguredInvokeSrcs(stateConfig, stateName, out) {
329
410
  * walk into invoked child machines (their internal agent requests are opaque
330
411
  * to the parent-level source walk otherwise).
331
412
  */
332
- function isStateMachine(logic) {
413
+ function isStateMachineLogic(logic) {
333
414
  return !!logic && typeof logic === "object" && "config" in logic && "root" in logic && typeof logic.provide === "function" && typeof logic.sources === "object" && !!logic.sources?.actors;
334
415
  }
335
416
  /**
@@ -361,7 +442,7 @@ function assertMachineBindable(machine, effectiveSources, executors, ctx) {
361
442
  const where = ctx.isChild ? `child machine '${ctx.childPath}' state` : "state";
362
443
  for (const { stateName, src } of invokes) {
363
444
  if (typeof src !== "string") {
364
- if (isStateMachine(src)) {
445
+ if (isStateMachineLogic(src)) {
365
446
  assertChildMachineBindable(src, src, stateName, executors, ctx);
366
447
  continue;
367
448
  }
@@ -370,7 +451,7 @@ function assertMachineBindable(machine, effectiveSources, executors, ctx) {
370
451
  }
371
452
  const logic = effectiveSources[src];
372
453
  if (logic === void 0) throw new Error(`runAgent: ${where} '${stateName}' invokes unregistered actor source '${src}'. Provide it via machine.provide({ actors: { '${src}': ... } }) or runAgent(machine, { actors: { '${src}': ... } }).`);
373
- if (isStateMachine(logic)) {
454
+ if (isStateMachineLogic(logic)) {
374
455
  assertChildMachineBindable(logic, src, stateName, executors, ctx);
375
456
  continue;
376
457
  }
@@ -416,18 +497,16 @@ function unrebindableChildRequestError(childPath, stateName, requestSrc, kind) {
416
497
  return /* @__PURE__ */ new Error(`runAgent: child machine '${childPath}' (state '${stateName}') invokes ${kind} source '${requestSrc}', which has no host execution and is reached through a direct-object invoke src that runAgent cannot rebind. Requests reached through string-keyed actor sources inherit runAgent's generateText/streamText/decide executors automatically; a direct-object child machine does not. Either bind the request with its own executor (requestLogic.withExecutor(...)), or register the child as a string-keyed actor source (machine.provide({ actors: { <child>: childMachine } })) and invoke it by name.`);
417
498
  }
418
499
  /**
419
- * True when the snapshot's active states declare a transition for the reserved
420
- * `'@agent.usage'` type EXPLICITLY. A catch-all `on: { '*': … }` deliberately
421
- * does not count: a wildcard is a machine's own event vocabulary, not an
422
- * opt-in to a library-reserved event, and `snapshot.can(event)` alone cannot
423
- * tell the two apart (it answers "would this event be taken?", which a
424
- * wildcard makes true for everything). Gating delivery on the explicit
425
- * declaration is what keeps `@agent.usage` opt-in by construction — and keeps
426
- * a wildcard machine's context and event log byte-identical to a run without
427
- * the feature. @internal
500
+ * True when the snapshot's active states declare a transition that would
501
+ * receive the reserved `'@agent.usage'` type an explicit `on: { '@agent.usage'
502
+ * }` OR a catch-all `on: { '*': }`. Plain XState semantics apply unmodified:
503
+ * a wildcard matches every event delivered to the machine, reserved ones
504
+ * included. (The MODEL-facing side stays closed: `getAcceptedEvents` drops
505
+ * `@agent.*` before any `allowedEvents` matching, so a wildcard never offers
506
+ * the reserved event as a decision candidate.) @internal
428
507
  */
429
508
  function declaresUsageTransition(snapshot) {
430
- return (0, xstate.getNextTransitions)(snapshot).some((transition) => transition.eventType === require_setup_agent.AGENT_USAGE_EVENT_TYPE);
509
+ return (0, xstate.getNextTransitions)(snapshot).some((transition) => transition.eventType === "@agent.usage" || transition.eventType === "*");
431
510
  }
432
511
  /**
433
512
  * Builds the ONE place a trace payload is emitted: it hands the payload to the
@@ -494,7 +573,7 @@ function bindTextLogic(logic, runCtx) {
494
573
  const self = selfArg;
495
574
  const { id, src } = selfIdAndSrc(self);
496
575
  const executor = logic.mode === "stream" ? runCtx.streamText : runCtx.generateText;
497
- if (!executor) throw new Error(`runAgent: no '${logic.mode === "stream" ? "streamText" : "generateText"}' executor provided.`);
576
+ if (!executor) throw new Error(`No '${logic.mode === "stream" ? "streamText" : "generateText"}' executor provided.`);
498
577
  const requestWithTools = {
499
578
  ...request,
500
579
  tools: request.tools ?? {}
@@ -566,17 +645,22 @@ function bindTextLogic(logic, runCtx) {
566
645
  });
567
646
  }
568
647
  function createCountingDecide(runCtx, self) {
569
- return async (attemptRequest) => {
648
+ return async (attemptRequest, info) => {
570
649
  runCtx.consumeModelCall();
571
650
  runCtx.emitTrace?.({
572
651
  type: "request.start",
573
652
  request: attemptRequest
574
653
  }, self);
575
654
  try {
655
+ const { id } = selfIdAndSrc(self);
576
656
  const result = await runCtx.decide(runCtx.runId !== void 0 ? {
577
657
  ...attemptRequest,
578
658
  runId: runCtx.runId
579
- } : attemptRequest);
659
+ } : attemptRequest, {
660
+ ...info,
661
+ ...runCtx.runId !== void 0 ? { runId: runCtx.runId } : {},
662
+ ...info?.requestId === void 0 && id !== "" ? { requestId: id } : {}
663
+ });
580
664
  const usage = require_decision.getCallUsage(result);
581
665
  if (usage) {
582
666
  const { src } = selfIdAndSrc(self);
@@ -622,7 +706,7 @@ function createCountingDecide(runCtx, self) {
622
706
  */
623
707
  function bindDecisionLogic(logic, runCtx) {
624
708
  const decisionLogic = (0, xstate.createAsyncLogic)({ run: async ({ input, signal, self: selfArg }) => {
625
- if (!runCtx.decide) throw new Error("runAgent: no 'decide' executor provided.");
709
+ if (!runCtx.decide) throw new Error("No 'decide' executor provided.");
626
710
  const self = selfArg;
627
711
  const { id } = selfIdAndSrc(self);
628
712
  const declaredEventTypes = logic.allowedEventTypes?.(input);
@@ -636,7 +720,7 @@ function bindDecisionLogic(logic, runCtx) {
636
720
  ...logic.request(input),
637
721
  id,
638
722
  events
639
- }, createCountingDecide(runCtx, self), {
723
+ }, { decide: createCountingDecide(runCtx, self) }, {
640
724
  maxRetries: logic.maxRetries,
641
725
  signal,
642
726
  canTake: (event) => actorRef ? actorRef.getSnapshot().can(event) : true
@@ -681,7 +765,7 @@ function rootTraceState(root) {
681
765
  if (!state) {
682
766
  const logic = root.logic;
683
767
  const machineId = (logic?.config)?.id ?? logic?.id ?? "(machine)";
684
- const machineVersion = logic ? require_decision.getMachineStructuralHash(logic) : "";
768
+ const machineVersion = logic ? require_decision.resolveMachineVersion(logic) : "";
685
769
  state = {
686
770
  runId: `run_${nextProvideRunId++}`,
687
771
  seq: 0,
@@ -753,9 +837,9 @@ function provideBindContext(machine, executors, options) {
753
837
  * under a live `createActor` tree) on the `provideExecutors` path.
754
838
  *
755
839
  * Gating is identical on both: the target snapshot must be active, must declare
756
- * an `'@agent.usage'` transition EXPLICITLY (see {@link declaresUsageTransition}
757
- * — a catch-all `on: { '*' }` is not an opt-in), and must be able to take the
758
- * event. `onDropped` is the run path's straggler gate: it returns `true` for a
840
+ * an `'@agent.usage'` transition explicitly, or through a catch-all
841
+ * `on: { '*' }` (see {@link declaresUsageTransition}) and must be able to
842
+ * take the event. `onDropped` is the run path's straggler gate: it returns `true` for a
759
843
  * call that settled after the cycle resolved, which drops the event (traced as
760
844
  * `usage.dropped`) rather than delivering it. Uncontrolled mode has no cycle to
761
845
  * settle, so it passes no gate and has no dropped stragglers.
@@ -797,6 +881,19 @@ function bindDecisionForProvide(machine, logic, executors, options) {
797
881
  return bindDecisionLogic(logic, provideBindContext(machine, executors, options));
798
882
  }
799
883
  /**
884
+ * Recursively binds an invoked child state machine for {@link provideExecutors},
885
+ * with the same semantics `runAgent` applies ({@link rebindChildMachine}):
886
+ * string-keyed text/decision sources at any depth inherit the host executors,
887
+ * a source that carries its own executor is left alone, and a cycle is
888
+ * returned as-is. Each machine in the tree is bound with its own registered
889
+ * `setupAgent` schemas. Returns the original machine when nothing needed
890
+ * wrapping. @internal
891
+ */
892
+ function bindChildMachineForProvide(childMachine, executors, options, visited) {
893
+ const ctxFor = (target) => provideBindContext(target, executors, options);
894
+ return rebindChildMachine(childMachine, ctxFor(childMachine), visited, ctxFor);
895
+ }
896
+ /**
800
897
  * Validates `input` against the machine's registered input schema, returning
801
898
  * the schema's output — so defaults are filled and transforms applied before
802
899
  * the value reaches `createActor` or the replayable event log.
@@ -830,9 +927,10 @@ function resolveMachineInput(machine, input) {
830
927
  * (`executorBoundLogics`) is left as-is: explicit binding shadows inheritance.
831
928
  * Cycle-safe via `visited` (a machine that invokes itself is returned as-is).
832
929
  */
833
- function rebindChildMachine(childMachine, runCtx, visited) {
930
+ function rebindChildMachine(childMachine, runCtx, visited, ctxFor) {
834
931
  if (visited.has(childMachine)) return childMachine;
835
932
  const childVisited = new Set([...visited, childMachine]);
933
+ runCtx = ctxFor ? ctxFor(childMachine) : runCtx;
836
934
  const sources = childMachine.sources.actors;
837
935
  const wrapped = {};
838
936
  for (const [key, logic] of Object.entries(sources)) {
@@ -844,8 +942,8 @@ function rebindChildMachine(childMachine, runCtx, visited) {
844
942
  if (!require_decision.executorBoundLogics.has(logic)) wrapped[key] = bindTextLogic(logic, runCtx);
845
943
  continue;
846
944
  }
847
- if (isStateMachine(logic)) {
848
- const rebound = rebindChildMachine(logic, runCtx, childVisited);
945
+ if (isStateMachineLogic(logic)) {
946
+ const rebound = rebindChildMachine(logic, runCtx, childVisited, ctxFor);
849
947
  if (rebound !== logic) wrapped[key] = rebound;
850
948
  continue;
851
949
  }
@@ -928,7 +1026,7 @@ function createAgentSession(machine, options, lifecycle) {
928
1026
  let traceSeq = 0;
929
1027
  const resolvedInput = resolveMachineInput(machine, options.input);
930
1028
  const machineId = machine.config.id ?? machine.id ?? "(machine)";
931
- const machineVersion = options.machineVersion ?? machine.version ?? require_decision.getMachineStructuralHash(machine);
1029
+ const machineVersion = require_decision.resolveMachineVersion(machine);
932
1030
  const agentMeta = {
933
1031
  machineId,
934
1032
  version: machineVersion
@@ -950,10 +1048,10 @@ function createAgentSession(machine, options, lifecycle) {
950
1048
  onTransition: options.onTransition
951
1049
  });
952
1050
  const consumeModelCall = () => {
953
- if (budgetExceeded) throw new AgentMaxModelCallsExceededError();
1051
+ if (budgetExceeded) throw new AgentMaxModelCallsExceededError(maxModelCalls);
954
1052
  if (modelCallCount + 1 > maxModelCalls) {
955
1053
  budgetExceeded = true;
956
- throw new AgentMaxModelCallsExceededError();
1054
+ throw new AgentMaxModelCallsExceededError(maxModelCalls);
957
1055
  }
958
1056
  modelCallCount += 1;
959
1057
  };
@@ -1027,19 +1125,20 @@ function createAgentSession(machine, options, lifecycle) {
1027
1125
  if (!require_decision.executorBoundLogics.has(logic)) wrappedSources[key] = bindTextLogic(logic, runCtx);
1028
1126
  continue;
1029
1127
  }
1030
- if (isStateMachine(logic)) {
1128
+ if (isStateMachineLogic(logic)) {
1031
1129
  const rebound = rebindChildMachine(logic, runCtx, new Set([machine]));
1032
1130
  if (rebound !== logic) wrappedSources[key] = rebound;
1033
1131
  continue;
1034
1132
  }
1035
1133
  }
1036
1134
  const boundMachine = provided.provide({ actors: wrappedSources });
1037
- const declaredSuspensionPredicate = options.isSuspended ?? require_decision.getMachineSuspensionPredicate(machine);
1038
- const isSuspended = declaredSuspensionPredicate ?? (() => false);
1135
+ const declaredIdlePredicate = options.isIdle ?? require_decision.getMachineIdlePredicate(machine);
1136
+ const isIdle = declaredIdlePredicate ?? (() => false);
1137
+ const machineDeclaresMigrate = typeof machine.config.migrate === "function";
1039
1138
  let effectiveSnapshot = options.snapshot;
1040
1139
  if (effectiveSnapshot !== void 0) {
1041
1140
  const from = effectiveSnapshot.agentMeta?.version ?? effectiveSnapshot.version;
1042
- if (from !== void 0 && from !== machineVersion) {
1141
+ if (from !== void 0 && from !== machineVersion && !(machineDeclaresMigrate && !options.migrateSnapshot)) {
1043
1142
  const info = {
1044
1143
  from,
1045
1144
  to: machineVersion
@@ -1058,7 +1157,7 @@ function createAgentSession(machine, options, lifecycle) {
1058
1157
  effectiveSnapshot = machine.getPersistedSnapshot(replayedSnapshot);
1059
1158
  }
1060
1159
  const machineOwnVersion = machine.version;
1061
- if (effectiveSnapshot !== void 0 && effectiveSnapshot.version !== machineOwnVersion) {
1160
+ if (!machineDeclaresMigrate && effectiveSnapshot !== void 0 && effectiveSnapshot.version !== machineOwnVersion) {
1062
1161
  const aligned = Object.assign(Object.create(Object.getPrototypeOf(effectiveSnapshot)), effectiveSnapshot);
1063
1162
  if (machineOwnVersion === void 0) delete aligned.version;
1064
1163
  else aligned.version = machineOwnVersion;
@@ -1072,7 +1171,7 @@ function createAgentSession(machine, options, lifecycle) {
1072
1171
  if (!options.getRequests && !options.messages && messages.length === 0) return;
1073
1172
  snapshot.messages = [...messages];
1074
1173
  };
1075
- if (effectiveSnapshot !== void 0 && options.event !== void 0 && (options.onIllegalResumeEvent ?? "throw") === "throw") {
1174
+ if (effectiveSnapshot !== void 0 && options.event !== void 0) {
1076
1175
  const acceptedTypes = require_decision.getAcceptedEvents((0, xstate.createActor)(boundMachine, { snapshot: effectiveSnapshot }).getSnapshot(), { schemas: runCtx.schemas }).map((descriptor) => descriptor.type);
1077
1176
  const eventType = options.event.type;
1078
1177
  if (!acceptedTypes.includes(eventType)) throw new AgentIllegalResumeEventError(eventType, acceptedTypes);
@@ -1218,9 +1317,9 @@ function createAgentSession(machine, options, lifecycle) {
1218
1317
  const current = actor.getSnapshot();
1219
1318
  if (isIdleSnapshot(current, { ignoreUserInputChildren: userInputIsPlaceholder })) {
1220
1319
  if (!maybeInterpret(current)) {
1221
- if (!declaredSuspensionPredicate && current.status === "active" && !warnedHeuristicIdle && process.env.NODE_ENV !== "production") {
1320
+ if (!declaredIdlePredicate && current.status === "active" && !warnedHeuristicIdle && process.env.NODE_ENV !== "production") {
1222
1321
  warnedHeuristicIdle = true;
1223
- console.warn("[@statelyai/agent] runAgent settled idle via the timing heuristic (no suspension predicate declared). This is best-effort; for deterministic idle detection, declare setupAgent({ isSuspended }) or pass runAgent(machine, { isSuspended }), e.g. (s) => s.hasTag('waiting').");
1322
+ console.warn("[@statelyai/agent] runAgent settled idle via the timing heuristic (no idle predicate declared). This is best-effort; for deterministic idle detection, declare setupAgent({ isIdle }) or pass runAgent(machine, { isIdle }), e.g. (s) => s.hasTag('waiting').");
1224
1323
  }
1225
1324
  settleIdle(current);
1226
1325
  }
@@ -1275,11 +1374,11 @@ function createAgentSession(machine, options, lifecycle) {
1275
1374
  });
1276
1375
  return;
1277
1376
  }
1278
- if (!deliveringResumeEvent && isSuspended(snapshot) && isIdleSnapshot(snapshot, { ignoreUserInputChildren: userInputIsPlaceholder })) {
1377
+ if (!deliveringResumeEvent && isIdle(snapshot) && isIdleSnapshot(snapshot, { ignoreUserInputChildren: userInputIsPlaceholder })) {
1279
1378
  queueMicrotask(() => {
1280
1379
  if (settled) return;
1281
1380
  const current = actor.getSnapshot();
1282
- if (isSuspended(current) && isIdleSnapshot(current, { ignoreUserInputChildren: userInputIsPlaceholder })) {
1381
+ if (isIdle(current) && isIdleSnapshot(current, { ignoreUserInputChildren: userInputIsPlaceholder })) {
1283
1382
  if (!maybeInterpret(current)) settleIdle(current);
1284
1383
  } else scheduleIdleCheck();
1285
1384
  });
@@ -1576,9 +1675,12 @@ function createAgentRun(machine, options) {
1576
1675
  * Throws at bind time if a source needs an executor kind that `executors` does
1577
1676
  * not provide.
1578
1677
  *
1579
- * `provideExecutors` does not descend into invoked child state machines: a string-keyed child
1580
- * machine source is left untouched, so a child with its own agent invokes needs
1581
- * its own `provideExecutors(...)` (or `runAgent`, which does rebind children).
1678
+ * Executor inheritance is RECURSIVE, exactly as in `runAgent`: a string-keyed
1679
+ * invoked child machine is rebound too, so its own text/decision requests — at
1680
+ * any depth reach the same host executors. A direct-object invoke `src`
1681
+ * cannot be swapped via `.provide`, so nothing under one inherits; bind those
1682
+ * with `.withExecutor(...)` or register the child as a string-keyed source. A
1683
+ * source that already carries its own executor is never overwritten.
1582
1684
  */
1583
1685
  function provideExecutors(machine, executors, options = {}) {
1584
1686
  const bindOptions = {
@@ -1592,21 +1694,18 @@ function provideExecutors(machine, executors, options = {}) {
1592
1694
  const invokedSrcs = getConfiguredInvokeSrcs(provided);
1593
1695
  for (const [key, logic] of Object.entries(effectiveSources)) {
1594
1696
  if (key === "agent.userInput") continue;
1595
- let binding;
1596
- if (require_decision.isDecisionLogic(logic)) binding = {
1597
- executorKey: "decide",
1598
- kind: "decision",
1599
- bind: () => bindDecisionForProvide(provided, logic, executors, bindOptions)
1600
- };
1601
- else if (require_decision.isTextLogic(logic)) {
1602
- const streaming = logic.mode === "stream";
1603
- binding = {
1604
- executorKey: streaming ? "streamText" : "generateText",
1605
- kind: streaming ? "streaming text" : "text",
1606
- bind: () => bindTextForProvide(provided, logic, executors, bindOptions)
1607
- };
1697
+ if (isStateMachineLogic(logic)) {
1698
+ if (invokedSrcs.has(key)) assertChildBindable(logic, executors, key, new Set([provided]));
1699
+ const rebound = bindChildMachineForProvide(logic, executors, bindOptions, new Set([provided]));
1700
+ if (rebound !== logic) wrappedSources[key] = rebound;
1701
+ continue;
1608
1702
  }
1609
- if (!binding) continue;
1703
+ const requirement = executorRequirementOf(logic);
1704
+ if (!requirement) continue;
1705
+ const binding = {
1706
+ ...requirement,
1707
+ bind: () => require_decision.isDecisionLogic(logic) ? bindDecisionForProvide(provided, logic, executors, bindOptions) : bindTextForProvide(provided, logic, executors, bindOptions)
1708
+ };
1610
1709
  if (require_decision.executorBoundLogics.has(logic)) continue;
1611
1710
  if (!executors[binding.executorKey]) {
1612
1711
  if (invokedSrcs.has(key)) throw missingExecutorError(key, binding.kind, binding.executorKey);
@@ -1616,12 +1715,50 @@ function provideExecutors(machine, executors, options = {}) {
1616
1715
  }
1617
1716
  return withActors(provided, wrappedSources);
1618
1717
  }
1718
+ /** The executor slot + label an agent logic needs, or `undefined` for a non-agent actor. */
1719
+ function executorRequirementOf(logic) {
1720
+ if (require_decision.isDecisionLogic(logic)) return {
1721
+ executorKey: "decide",
1722
+ kind: "decision"
1723
+ };
1724
+ if (require_decision.isTextLogic(logic)) return logic.mode === "stream" ? {
1725
+ executorKey: "streamText",
1726
+ kind: "streaming text"
1727
+ } : {
1728
+ executorKey: "generateText",
1729
+ kind: "text"
1730
+ };
1731
+ }
1732
+ /**
1733
+ * Walks an invoked child machine's own invoked sources (recursively, at any
1734
+ * depth) and throws the same missing-executor error `provideExecutors` throws
1735
+ * for the top-level machine — before any actor starts. Mirrors runAgent's
1736
+ * `assertBindable` for the uncontrolled path. Cycle-safe via `visited`.
1737
+ */
1738
+ function assertChildBindable(childMachine, executors, path, visited) {
1739
+ if (visited.has(childMachine)) return;
1740
+ const nextVisited = new Set([...visited, childMachine]);
1741
+ const sources = childMachine.sources.actors;
1742
+ for (const src of getConfiguredInvokeSrcs(childMachine)) {
1743
+ if (src === "agent.userInput") continue;
1744
+ const logic = sources[src];
1745
+ if (!logic) continue;
1746
+ if (isStateMachineLogic(logic)) {
1747
+ assertChildBindable(logic, executors, `${path} > ${src}`, nextVisited);
1748
+ continue;
1749
+ }
1750
+ const requirement = executorRequirementOf(logic);
1751
+ if (!requirement || require_decision.executorBoundLogics.has(logic)) continue;
1752
+ if (!executors[requirement.executorKey]) throw missingExecutorError(`${path} > ${src}`, requirement.kind, requirement.executorKey);
1753
+ }
1754
+ }
1619
1755
  function missingExecutorError(src, kind, executor) {
1620
1756
  return /* @__PURE__ */ new Error(`provideExecutors: actor source '${src}' is a ${kind} source but no '${executor}' executor was provided. Add it to the executors object, or bind the source with its own executor (logic.withExecutor(...)) before calling provideExecutors.`);
1621
1757
  }
1622
1758
  //#endregion
1623
1759
  //#region src/verify.ts
1624
1760
  const DECIDE_SRC = "agent.decide";
1761
+ const USER_INPUT_SRC = "agent.userInput";
1625
1762
  function normalizeInvokes(invoke) {
1626
1763
  if (invoke === void 0 || invoke === null) return [];
1627
1764
  return Array.isArray(invoke) ? invoke : [invoke];
@@ -1908,11 +2045,23 @@ const LINT_CHECKS = [
1908
2045
  * call this to catch dead states, undeliverable decisions, un-rebindable
1909
2046
  * invoke srcs, and output-contract gaps before ever running it.
1910
2047
  *
2048
+ * Pass `{ throw: true }` for the one-liner form used in tests and generation
2049
+ * loops: it returns silently when the machine is clean and throws
2050
+ * {@link AgentLintError} (findings on `.diagnostics`) on error-severity
2051
+ * findings, or on warnings too with `{ throw: true, warnings: true }`.
2052
+ *
1911
2053
  * @example
1912
2054
  * ```ts
1913
2055
  * const errors = lintAgentMachine(machine).filter((d) => d.severity === 'error');
1914
2056
  * if (errors.length) throw new Error(errors.map((e) => `${e.path}: ${e.message}`).join('\n'));
1915
2057
  * ```
2058
+ *
2059
+ * @example Throwing form
2060
+ * ```ts
2061
+ * test('agent machine is structurally sound', () => {
2062
+ * lintAgentMachine(machine, { throw: true });
2063
+ * });
2064
+ * ```
1916
2065
  */
1917
2066
  function lintAgentMachine(machine, options = {}) {
1918
2067
  const config = machine.config ?? {};
@@ -1927,10 +2076,16 @@ function lintAgentMachine(machine, options = {}) {
1927
2076
  actors: registered.actors ?? machine.sources?.actors ?? {}
1928
2077
  };
1929
2078
  const disabled = new Set(options.disable ?? []);
1930
- return LINT_CHECKS.flatMap((check) => check(ctx)).filter((d) => !disabled.has(d.code));
2079
+ const diagnostics = LINT_CHECKS.flatMap((check) => check(ctx)).filter((d) => !disabled.has(d.code));
2080
+ if (options.throw) {
2081
+ const failing = options.warnings ? diagnostics : diagnostics.filter((d) => d.severity === "error");
2082
+ if (failing.length > 0) throw new AgentLintError(machine.id ?? "(machine)", failing);
2083
+ }
2084
+ return diagnostics;
1931
2085
  }
1932
2086
  /**
1933
- * Thrown by {@link assertAgentMachine} when lint finds failing diagnostics.
2087
+ * Thrown by `lintAgentMachine(machine, { throw: true })` when lint finds
2088
+ * failing diagnostics.
1934
2089
  * `diagnostics` holds the findings; the message lists them one per finding,
1935
2090
  * so a test runner's failure output reads like the CLI's lint report.
1936
2091
  */
@@ -1943,24 +2098,6 @@ var AgentLintError = class extends require_errors.AgentError {
1943
2098
  this.diagnostics = diagnostics;
1944
2099
  }
1945
2100
  };
1946
- /**
1947
- * Asserts a machine passes {@link lintAgentMachine}: returns silently when
1948
- * clean, throws {@link AgentLintError} (with the findings on `.diagnostics`)
1949
- * otherwise. Fails on error-severity findings; set `warnings: true` to fail on
1950
- * warnings too. The one-liner for tests and generation loops:
1951
- *
1952
- * @example
1953
- * ```ts
1954
- * test('agent machine is structurally sound', () => {
1955
- * assertAgentMachine(machine);
1956
- * });
1957
- * ```
1958
- */
1959
- function assertAgentMachine(machine, options = {}) {
1960
- const diagnostics = lintAgentMachine(machine, options);
1961
- const failing = options.warnings ? diagnostics : diagnostics.filter((d) => d.severity === "error");
1962
- if (failing.length > 0) throw new AgentLintError(machine.id ?? "(machine)", failing);
1963
- }
1964
2101
  function pendingInvokes(step) {
1965
2102
  const out = [];
1966
2103
  for (const action of step.actions) {
@@ -2006,6 +2143,7 @@ async function simulateAgent(machine, options) {
2006
2143
  decisions: mapValues(options.script.decisions ?? {}, (arr) => [...arr]),
2007
2144
  invokes: mapValues(options.script.invokes ?? {}, (arr) => [...arr])
2008
2145
  };
2146
+ if (options.script.userInput?.length) script.invokes[USER_INPUT_SRC] = [...options.script.userInput, ...script.invokes[USER_INPUT_SRC] ?? []];
2009
2147
  let step = require_setup_agent.initialAgentStep(machine, options.input);
2010
2148
  const trail = [];
2011
2149
  for (let i = 0; i < maxSteps; i++) {
@@ -2072,13 +2210,16 @@ function mapValues(obj, fn) {
2072
2210
  }
2073
2211
  function scriptDryError(kind, src, id, request) {
2074
2212
  const events = request?.kind === "decision" ? ` Candidate events: ${request.events.map((e) => e.type).join(", ") || "(none)"}.` : "";
2075
- return /* @__PURE__ */ new Error(`simulateAgent: script ran dry on a pending ${kind} request for src '${src}' (id '${id}'). Add a '${kind}' entry for '${src}' to the script.${events}`);
2213
+ const key = kind === "text" ? `text['${src}']` : kind === "decision" ? `decisions['${src}']` : src === USER_INPUT_SRC ? "userInput" : `invokes['${src}']`;
2214
+ return /* @__PURE__ */ new Error(`simulateAgent: script ran dry on a pending ${kind} request for src '${src}' (id '${id}'). Add an entry to the script's \`${key}\` queue.${events}`);
2076
2215
  }
2077
2216
  const MAX_ADVANCE_STEPS = 1e3;
2078
2217
  async function explore(machine, options, stopWhen) {
2079
2218
  const maxDepth = options.maxDepth ?? 8;
2080
2219
  const maxPaths = options.maxPaths ?? 200;
2081
- const textOutputs = options.textOutputs ?? {};
2220
+ const textScript = options.text ?? {};
2221
+ const invokeOutputs = { ...options.invokes ?? {} };
2222
+ if ("userInput" in options) invokeOutputs[USER_INPUT_SRC] = options.userInput;
2082
2223
  const reachedStates = /* @__PURE__ */ new Set();
2083
2224
  const reachedValues = [];
2084
2225
  const terminals = [];
@@ -2103,22 +2244,22 @@ async function explore(machine, options, stopWhen) {
2103
2244
  if (current.done) return { step: current };
2104
2245
  const request = current.requests[0];
2105
2246
  if (request && request.kind === "text") {
2106
- if (!(request.src in textOutputs)) return {
2247
+ if (!(request.src in textScript)) return {
2107
2248
  step: current,
2108
2249
  blockedSrc: request.src
2109
2250
  };
2110
- current = require_setup_agent.resolveAgentStep(machine, current, request, textOutputs[request.src]);
2251
+ current = require_setup_agent.resolveAgentStep(machine, current, request, textScript[request.src]);
2111
2252
  recordState(current.snapshot);
2112
2253
  continue;
2113
2254
  }
2114
2255
  if (request && request.kind === "decision") return { step: current };
2115
2256
  const [invoke] = pendingInvokes(current);
2116
2257
  if (invoke) {
2117
- if (!(invoke.src in textOutputs)) return {
2258
+ if (!(invoke.src in invokeOutputs)) return {
2118
2259
  step: current,
2119
2260
  blockedSrc: invoke.src
2120
2261
  };
2121
- current = require_setup_agent.resolveAgentStep(machine, current, invoke.id, textOutputs[invoke.src]);
2262
+ current = require_setup_agent.resolveAgentStep(machine, current, invoke.id, invokeOutputs[invoke.src]);
2122
2263
  recordState(current.snapshot);
2123
2264
  continue;
2124
2265
  }
@@ -2210,9 +2351,10 @@ async function explore(machine, options, stopWhen) {
2210
2351
  * depth, model-free, and reports which states are reached and how each path
2211
2352
  * terminates. At each decision request it forks one branch per candidate event
2212
2353
  * (guard-rejected candidates are counted in `prunedByGuard`, not explored); at
2213
- * an idle wait it forks per externally-accepted event. Text/`userInput` invokes
2214
- * are resolved from `textOutputs` (a by-src canned-output map) — a missing src
2215
- * halts that branch with a `needs-output` terminal rather than throwing.
2354
+ * an idle wait it forks per externally-accepted event. Text requests resolve
2355
+ * from `text`, other invokes from `invokes` (or `userInput` for
2356
+ * `agent.userInput`) all by-src canned-output maps, and a missing src halts
2357
+ * that branch with a `needs-output` terminal rather than throwing.
2216
2358
  *
2217
2359
  * Combinatorics are bounded by `maxDepth` (default 8) and `maxPaths` (default
2218
2360
  * 200, reported via `hitPathCap`).
@@ -2228,13 +2370,14 @@ async function explorePaths(machine, options = {}) {
2228
2370
  }
2229
2371
  /**
2230
2372
  * Answers "can the machine reach `statePath`?" by exploring its branches (a
2231
- * thin wrapper over {@link explorePaths}). Returns `{ canReach: true, witness }`
2232
- * with the event sequence that reaches it, or `{ canReach: false }`.
2373
+ * thin wrapper over {@link explorePaths}). Returns
2374
+ * `{ reachable: true, witness }` with the event sequence that reaches it, or
2375
+ * `{ reachable: false }`.
2233
2376
  *
2234
2377
  * @example
2235
2378
  * ```ts
2236
- * const { canReach, witness } = await canReach(refundMachine, 'denied', { input: { request: 'x', amount: 5000 } });
2237
- * // canReach → true; witness → [{ type: 'NEEDS_REVIEW' }, { type: 'DENY' }]
2379
+ * const { reachable, witness } = await canReach(refundMachine, 'denied', { input: { request: 'x', amount: 5000 } });
2380
+ * // reachable → true; witness → [{ type: 'NEEDS_REVIEW' }, { type: 'DENY' }]
2238
2381
  * ```
2239
2382
  */
2240
2383
  async function canReach(machine, statePath, options = {}) {
@@ -2246,9 +2389,9 @@ async function canReach(machine, statePath, options = {}) {
2246
2389
  }
2247
2390
  });
2248
2391
  return witness !== void 0 ? {
2249
- canReach: true,
2392
+ reachable: true,
2250
2393
  witness
2251
- } : { canReach: false };
2394
+ } : { reachable: false };
2252
2395
  }
2253
2396
  //#endregion
2254
2397
  //#region src/internal/is-record.ts
@@ -2409,7 +2552,8 @@ function matchesTrajectory(actual, expected, options = {}) {
2409
2552
  * Scripted executors — a keyless, deterministic stand-in for a model host.
2410
2553
  *
2411
2554
  * `createScriptedExecutors` builds a full `{ generateText, streamText, decide }`
2412
- * set that plays back canned answers from FIFO queues, so `runAgent` (or
2555
+ * set (plus a `userInput` handler) that plays back canned answers from FIFO
2556
+ * queues, so `runAgent` (or
2413
2557
  * `provideExecutors`, or a bare `TextLogic.execute`) runs with no API key and no
2414
2558
  * network. It is the fastest way to see a machine run, and the least ceremonial
2415
2559
  * way to test one: same machine, same executor contract, scripted answers.
@@ -2485,15 +2629,27 @@ function emitScriptedChunk(result, info) {
2485
2629
  * decisions: [(request) => ({ type: request.events[0]!.type })],
2486
2630
  * });
2487
2631
  * ```
2632
+ *
2633
+ * @example Scripted human input
2634
+ * ```ts
2635
+ * const scripted = createScriptedExecutors({ userInput: ['ship it'] });
2636
+ * await runAgent(machine, { executors: scripted, userInput: scripted.userInput });
2637
+ * ```
2488
2638
  */
2489
2639
  function createScriptedExecutors(script = {}) {
2490
2640
  const decisions = [...script.decisions ?? []];
2491
2641
  const text = [...script.text ?? []];
2642
+ const userInput = [...script.userInput ?? []];
2492
2643
  const nextText = async (request, info) => {
2493
2644
  if (text.length === 0) throw new require_errors.AgentError("scripted-executors-exhausted", `createScriptedExecutors: script ran dry on a pending text request ${describeText(request)}. Add another entry to the script's \`text\` queue.`);
2494
2645
  return resolveScriptedTextEntry(text.shift(), request, info);
2495
2646
  };
2496
2647
  return {
2648
+ userInput: async (input) => {
2649
+ if (userInput.length === 0) throw new require_errors.AgentError("scripted-executors-exhausted", `createScriptedExecutors: script ran dry on a pending userInput request (prompt: ${input.prompt ? `'${input.prompt}'` : "(none)"}). Add another entry to the script's \`userInput\` queue.`);
2650
+ const entry = userInput.shift();
2651
+ return typeof entry === "function" ? await entry(input) : entry;
2652
+ },
2497
2653
  generateText: nextText,
2498
2654
  streamText: async (request, info) => {
2499
2655
  const result = await nextText(request, info);
@@ -2567,22 +2723,22 @@ async function runSeam(machine, options) {
2567
2723
  const queueKeyOf = (request) => request.name !== void 0 && queues.has(request.name) ? request.name : request.model;
2568
2724
  /**
2569
2725
  * Consumes this request's slot in the call plan, or resolves `undefined` when
2570
- * its queue is dry. The LAST entry repeats: a live seam that branches further
2571
- * still finds an answer instead of running dry.
2726
+ * its queue is dry. With `repeatLast`, the last entry is replayed instead of
2727
+ * running dry.
2572
2728
  */
2573
2729
  const takeScriptedSlot = async (request, info) => {
2574
2730
  const queue = queues.get(queueKeyOf(request));
2575
2731
  if (!queue?.length) return;
2576
- return resolveScriptedTextEntry(queue.length === 1 ? queue[0] : queue.shift(), request, info);
2732
+ return resolveScriptedTextEntry(options.repeatLast && queue.length === 1 ? queue[0] : queue.shift(), request, info);
2577
2733
  };
2578
2734
  const scriptedAnswer = async (request, info) => {
2579
2735
  const scripted = await takeScriptedSlot(request, info);
2580
- if (!scripted) throw new require_errors.AgentError("seam-script-exhausted", `runSeam: no scripted answer left for request ${describeText(request)}. Add an entry to \`scripts.${queueKeyOf(request)}\` its last entry repeats, so one extra answer covers a longer branch.`);
2736
+ if (!scripted) throw new require_errors.AgentError("seam-script-exhausted", `runSeam: no scripted answer left for request ${describeText(request)}. Add an entry to \`scripts.${queueKeyOf(request)}\`, or pass \`repeatLast: true\` to replay its last entry down a longer branch.`);
2581
2737
  return scripted;
2582
2738
  };
2583
2739
  const route = async (request, info) => {
2584
2740
  const callIndex = calls++;
2585
- const isSeam = (seam.request !== void 0 ? request.name === seam.request : request.model === seam.model) && seamMatches++ === (seam.occurrence ?? 0);
2741
+ const isSeam = request.name === seam.request && seamMatches++ === (seam.occurrence ?? 0);
2586
2742
  if (isSeam && candidate) {
2587
2743
  await takeScriptedSlot(request, info);
2588
2744
  seamReached = true;
@@ -2620,7 +2776,7 @@ async function runSeam(machine, options) {
2620
2776
  result = await runAgent(machine, {
2621
2777
  ...snapshot ? { snapshot } : { input: options.input },
2622
2778
  ...event ? { event } : {},
2623
- ...options.isSuspended ? { isSuspended: options.isSuspended } : {},
2779
+ ...options.isIdle ? { isIdle: options.isIdle } : {},
2624
2780
  ...options.actors ? { actors: options.actors } : {},
2625
2781
  events,
2626
2782
  executors,
@@ -2683,13 +2839,13 @@ exports.AgentEventLogConflictError = require_event_log_store.AgentEventLogConfli
2683
2839
  exports.AgentIdleError = AgentIdleError;
2684
2840
  exports.AgentIllegalResumeEventError = AgentIllegalResumeEventError;
2685
2841
  exports.AgentLintError = AgentLintError;
2842
+ exports.AgentMaxModelCallsExceededError = AgentMaxModelCallsExceededError;
2686
2843
  exports.AgentReplayDivergenceError = require_setup_agent.AgentReplayDivergenceError;
2687
2844
  exports.AgentReplayMachineMismatchError = require_setup_agent.AgentReplayMachineMismatchError;
2688
2845
  exports.AgentSnapshotVersionMismatchError = AgentSnapshotVersionMismatchError;
2689
2846
  exports.NonSerializableAgentEventError = require_event_log_store.NonSerializableAgentEventError;
2690
2847
  exports.appendMessages = require_setup_agent.appendMessages;
2691
2848
  exports.assertAgentLogEntry = require_event_log_store.assertAgentLogEntry;
2692
- exports.assertAgentMachine = assertAgentMachine;
2693
2849
  exports.assertEventLogStoreConformance = require_event_log_store.assertEventLogStoreConformance;
2694
2850
  exports.assertJsonSerializable = require_event_log_store.assertJsonSerializable;
2695
2851
  exports.assistantMessage = require_decision.assistantMessage;
@@ -2711,10 +2867,13 @@ exports.getAcceptedEvents = require_decision.getAcceptedEvents;
2711
2867
  exports.getAgentEffects = require_setup_agent.getAgentEffects;
2712
2868
  exports.getAgentMessages = require_decision.getAgentMessages;
2713
2869
  exports.getAgentOutputMode = require_decision.getAgentOutputMode;
2870
+ exports.getAgentSchemas = require_setup_agent.getAgentSchemas;
2714
2871
  exports.getCallUsage = require_decision.getCallUsage;
2715
2872
  exports.getJsonSchema = require_decision.getJsonSchema;
2716
2873
  exports.getJsonSchemaSync = require_decision.getJsonSchemaSync;
2717
2874
  exports.getMachineStructuralHash = require_decision.getMachineStructuralHash;
2875
+ exports.getSnapshotNodes = getSnapshotNodes;
2876
+ exports.getSnapshotRequests = getSnapshotRequests;
2718
2877
  exports.getStateMeta = require_decision.getStateMeta;
2719
2878
  exports.initEntry = require_setup_agent.initEntry;
2720
2879
  exports.inspectTransitions = inspectTransitions;
@@ -2726,7 +2885,6 @@ exports.parseAgentEvent = require_decision.parseAgentEvent;
2726
2885
  exports.parseModelRef = require_decision.parseModelRef;
2727
2886
  exports.parseOutput = require_decision.parseOutput;
2728
2887
  exports.parseStructuredEnvelope = require_decision.parseStructuredEnvelope;
2729
- exports.persistSnapshot = require_decision.persistSnapshot;
2730
2888
  exports.provideExecutors = provideExecutors;
2731
2889
  exports.renderDecisionAttempts = require_decision.renderDecisionAttempts;
2732
2890
  exports.replay = require_setup_agent.replay;
@@ -2745,4 +2903,3 @@ exports.systemMessage = require_decision.systemMessage;
2745
2903
  exports.toolMessage = require_decision.toolMessage;
2746
2904
  exports.traceTransitions = traceTransitions;
2747
2905
  exports.userMessage = require_decision.userMessage;
2748
- exports.verifyReplay = require_setup_agent.verifyReplay;