@statelyai/agent 2.0.0-alpha.14 → 2.0.0-alpha.16

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 (35) hide show
  1. package/dist/ai-sdk.cjs +1 -1
  2. package/dist/ai-sdk.d.cts +2 -2
  3. package/dist/ai-sdk.d.mts +2 -2
  4. package/dist/ai-sdk.mjs +1 -1
  5. package/dist/{decision-C0cUKvNt.cjs → decision-Ba8qrT8r.cjs} +42 -28
  6. package/dist/{decision-D9Zi7Xi5.mjs → decision-Bt2HYYRo.mjs} +31 -23
  7. package/dist/{event-log-store-D7pWtIhb.mjs → event-log-store-B-1fcfkT.mjs} +149 -141
  8. package/dist/{event-log-store-BkUNtyOF.d.mts → event-log-store-BrC9Q1xW.d.mts} +14 -12
  9. package/dist/{event-log-store-CVd2eyRy.d.cts → event-log-store-CQJq8_v4.d.cts} +14 -12
  10. package/dist/{event-log-store-CNT_7F0V.cjs → event-log-store-yquOV1TX.cjs} +148 -140
  11. package/dist/index.cjs +520 -521
  12. package/dist/index.d.cts +128 -106
  13. package/dist/index.d.mts +128 -106
  14. package/dist/index.mjs +519 -520
  15. package/dist/machines.cjs +1 -1
  16. package/dist/machines.d.cts +1 -1
  17. package/dist/machines.d.mts +1 -1
  18. package/dist/machines.mjs +1 -1
  19. package/dist/otel.d.cts +1 -1
  20. package/dist/otel.d.mts +1 -1
  21. package/dist/{run-agent-BlqKwHIF.d.cts → run-agent-BxjGaVpL.d.cts} +72 -111
  22. package/dist/{run-agent-2MnlQTkB.d.mts → run-agent-COHoCgQd.d.mts} +72 -111
  23. package/dist/{setup-agent-CpK0ZRWV.cjs → setup-agent-BLU77gqr.cjs} +141 -172
  24. package/dist/{setup-agent-DeHRW-qX.mjs → setup-agent-SbiiSbAU.mjs} +136 -167
  25. package/dist/sqlite.cjs +1 -1
  26. package/dist/sqlite.d.cts +2 -2
  27. package/dist/sqlite.d.mts +2 -2
  28. package/dist/sqlite.mjs +1 -1
  29. package/dist/{text-logic-Jkilp1Ie.d.cts → text-logic-BFX5q7fM.d.cts} +26 -3
  30. package/dist/{text-logic-C5kbjaDz.d.mts → text-logic-DQW8_DWW.d.mts} +26 -3
  31. package/dist/{types-rMe7x6NR.d.cts → types-DYpK3QF4.d.mts} +35 -7
  32. package/dist/{types-9Bqg5rZB.d.mts → types-pJ5Hn8fv.d.cts} +35 -7
  33. package/package.json +28 -28
  34. package/readme.md +6 -19
  35. package/schemas/agent-workflow.json +1 -4
@@ -1,6 +1,6 @@
1
1
  const require_errors = require("./errors-DUBBzRLP.cjs");
2
- const require_decision = require("./decision-C0cUKvNt.cjs");
3
- const require_event_log_store = require("./event-log-store-CNT_7F0V.cjs");
2
+ const require_decision = require("./decision-Ba8qrT8r.cjs");
3
+ const require_event_log_store = require("./event-log-store-yquOV1TX.cjs");
4
4
  let xstate = require("xstate");
5
5
  //#region src/messages.ts
6
6
  function addMessages(resolve) {
@@ -85,7 +85,7 @@ const messagesSchema = { "~standard": {
85
85
  * The step envelope: an INTERNAL, per-model-call-checkpoint view of an agent
86
86
  * machine (`AgentStep` = snapshot + actions + discovered requests + done). It
87
87
  * once backed a public step API; the public step path is now the thin
88
- * effect/replay loop in `./effects.ts` (re-exported from `@statelyai/agent/steps`).
88
+ * effect/replay loop in `./effects.ts` (re-exported from `@statelyai/agent`).
89
89
  * These helpers survive as internals that `runAgent`, `verify.ts`, and the
90
90
  * effect path build on — the only symbol still on the public surface is
91
91
  * {@link executeAgentRequest} (the `text`-effect resolver).
@@ -106,17 +106,20 @@ function getInvokeEffectMetadata(action) {
106
106
  /**
107
107
  * Scans a set of executable actions (as returned by xstate's `transition`/
108
108
  * `initialTransition`) for spawned `TextLogic`/`DecisionLogic` invokes and
109
- * lowers each into an {@link AgentStepRequest}. The hand-passed-schemas
110
- * implementation detail behind the public {@link getAgentRequests} — it needs
111
- * `schemas`/`actors` passed explicitly, whereas `getAgentRequests`
112
- * pre-fills them from the machine's registered `setupAgent` options.
109
+ * lowers each into an {@link AgentStepRequest}. Pass `options.machine` to
110
+ * pre-fill `schemas`/`actors` from the machine's registered `setupAgent`
111
+ * options instead of passing them by hand.
113
112
  * `options.snapshot` is required to resolve a decision's candidate events
114
113
  * (intersecting declared `allowedEvents` with what's currently legal) — omit
115
114
  * it and decision requests report an empty `events` list.
116
115
  *
117
116
  * @internal
118
117
  */
119
- function getAgentRequestsWith(actions, options = {}) {
118
+ function getAgentRequests(actions, { machine, ...options } = {}) {
119
+ if (machine) options = {
120
+ ...require_decision.getRegisteredAgentExecutionOptions(machine),
121
+ ...options
122
+ };
120
123
  return actions.flatMap((action) => {
121
124
  const params = getInvokeEffectMetadata(action);
122
125
  if (!params || typeof params.src !== "string") return [];
@@ -217,7 +220,7 @@ function resolveAgentStep(machine, step, request, output, options) {
217
220
  const [snapshot, actions] = transitionResult(machine, step.snapshot, request, output);
218
221
  return createAgentStep(machine, snapshot, actions, require_decision.getRegisteredAgentExecutionOptions(machine, options));
219
222
  }
220
- async function executeAgentRequest(requestOrEffect, executors, options) {
223
+ async function executeAgentRequest(requestOrEffect, executors) {
221
224
  if (requestOrEffect.kind === "decision") throw new Error("executeAgentRequest(...) is text-only. Resolve a 'decision' request with resolveDecision(request, executors.decide, ...) instead.");
222
225
  const request = "requestId" in requestOrEffect ? {
223
226
  kind: "text",
@@ -230,11 +233,10 @@ async function executeAgentRequest(requestOrEffect, executors, options) {
230
233
  } : requestOrEffect;
231
234
  assertTextExecutor(request, executors);
232
235
  const { output, raw } = await require_decision.executeAgentTextRequest(request.mode ?? "generate", request.id, request.input, executors, request.tools);
233
- const normalizedOutput = request.input.outputSchema ? require_decision.validateSchemaSync(request.input.outputSchema, output) : output;
234
- return options?.verbose ? {
235
- output: normalizedOutput,
236
+ return {
237
+ output: request.input.outputSchema ? require_decision.validateSchemaSync(request.input.outputSchema, output) : output,
236
238
  raw
237
- } : normalizedOutput;
239
+ };
238
240
  }
239
241
  function assertTextExecutor(request, executors) {
240
242
  const mode = request.mode ?? "generate";
@@ -246,7 +248,7 @@ function createAgentStep(machine, snapshot, actions, options) {
246
248
  return {
247
249
  snapshot,
248
250
  actions,
249
- requests: getAgentRequestsWith(actions, {
251
+ requests: getAgentRequests(actions, {
250
252
  ...options,
251
253
  snapshot
252
254
  }),
@@ -327,26 +329,6 @@ const AGENT_INIT_EVENT_TYPE = "@agent.init";
327
329
  */
328
330
  const AGENT_USAGE_EVENT_TYPE = "@agent.usage";
329
331
  /**
330
- * Reads a settled call's token usage off a RAW executor result — the same
331
- * normalization `runAgent` applies before it delivers
332
- * {@link AGENT_USAGE_EVENT_TYPE}. Returns `undefined` when the executor
333
- * reported none.
334
- *
335
- * The seam for the step-loop path, where the host holds the raw result itself:
336
- *
337
- * ```ts
338
- * const { output, raw } = await executeAgentRequest(effect, executors, { verbose: true });
339
- * const usage = getCallUsage(raw);
340
- * if (usage) append({ type: AGENT_USAGE_EVENT_TYPE, usage }); // journal + transition, like any event
341
- * append(effect.toDoneEvent(output));
342
- * ```
343
- *
344
- * See "Token usage on this path" in docs/steps.md for the full loop.
345
- */
346
- function getCallUsage(raw) {
347
- return require_decision.extractCallUsage(raw);
348
- }
349
- /**
350
332
  * Creates a JSON-safe, self-describing entry and records the state/effect
351
333
  * hashes produced after replaying it. `entries` must be the complete prefix.
352
334
  */
@@ -374,7 +356,6 @@ function createReplayEntry(machine, entries, event, options = {}) {
374
356
  });
375
357
  entry.verification = replayVerification(result.snapshot, result.effects);
376
358
  }
377
- require_event_log_store.assertAgentLogEntry(entry);
378
359
  return entry;
379
360
  }
380
361
  /** Reserved first replay entry carrying machine input and verification hashes. */
@@ -527,14 +508,15 @@ function buildInvokeEffect(meta, mapped, events, snapshot, options) {
527
508
  function getAgentEffects(machine, snapshot, actions, options = {}) {
528
509
  const resolved = require_decision.getRegisteredAgentExecutionOptions(machine, options);
529
510
  const events = toEvents(options.history);
530
- const requests = getAgentRequestsWith(actions, {
511
+ const rawActions = actions;
512
+ const requests = getAgentRequests(rawActions, {
531
513
  ...resolved,
532
514
  snapshot
533
515
  });
534
516
  const requestById = new Map(requests.map((request) => [request.id, request]));
535
517
  const effects = [];
536
518
  const emitted = /* @__PURE__ */ new Set();
537
- for (const rawAction of actions) {
519
+ for (const rawAction of rawActions) {
538
520
  const meta = getInvokeEffectMetadata(rawAction);
539
521
  if (meta) {
540
522
  const effect = buildInvokeEffect(meta, typeof meta.id === "string" ? requestById.get(meta.id) : void 0, events, snapshot, resolved);
@@ -626,45 +608,48 @@ var AgentReplayDivergenceError = class extends require_errors.AgentError {
626
608
  * Raised/internal events are never in the journal — replay re-derives them
627
609
  * deterministically from the machine's own logic.
628
610
  */
629
- function replay(machine, entries, options = {}) {
630
- const machineId = machine.config.id ?? machine.id ?? "(machine)";
631
- const machineVersion = options.machineVersion ?? require_decision.getMachineStructuralHash(machine);
611
+ /**
612
+ * Validates a replay entry sequence: envelope shape, contiguity from index 0,
613
+ * unique event ids, and machine identity.
614
+ *
615
+ * @internal
616
+ */
617
+ function validateReplayEntries(entries, expected, label) {
632
618
  const eventIds = /* @__PURE__ */ new Set();
633
619
  for (let index = 0; index < entries.length; index++) {
634
620
  const entry = entries[index];
635
621
  require_event_log_store.assertAgentLogEntry(entry);
636
- if (entry.index !== index) throw new Error(`Replay entries must be contiguous from index 0; found entry.index ${entry.index} at position ${index}.`);
637
- if (eventIds.has(entry.id)) throw new Error(`Replay entries contain duplicate event id '${entry.id}'.`);
622
+ if (entry.index !== index) throw new Error(`${label} must be contiguous from index 0; found entry.index ${entry.index} at position ${index}.`);
623
+ if (eventIds.has(entry.id)) throw new Error(`${label} contain duplicate event id '${entry.id}'.`);
638
624
  eventIds.add(entry.id);
639
- if (entry.machineId !== machineId || entry.machineVersion !== machineVersion) throw new AgentReplayMachineMismatchError(entry.id, entry.index, {
640
- machineId,
641
- machineVersion
642
- }, {
625
+ if (entry.machineId !== expected.machineId || entry.machineVersion !== expected.machineVersion) throw new AgentReplayMachineMismatchError(entry.id, entry.index, expected, {
643
626
  machineId: entry.machineId,
644
627
  machineVersion: entry.machineVersion
645
628
  });
646
629
  }
630
+ }
631
+ function replay(machine, entries, options = {}) {
632
+ validateReplayEntries(entries, {
633
+ machineId: machine.config.id ?? machine.id ?? "(machine)",
634
+ machineVersion: options.machineVersion ?? require_decision.getMachineStructuralHash(machine)
635
+ }, "Replay entries");
647
636
  const events = toEvents(entries);
648
- let input = options.input;
649
- let journal = events;
650
- let journalEntries = entries;
651
- if (events[0]?.type === "@agent.init") {
652
- input = events[0].input;
653
- journal = events.slice(1);
654
- journalEntries = entries.slice(1);
655
- }
637
+ const initOffset = events[0]?.type === "@agent.init" ? 1 : 0;
638
+ const input = initOffset ? events[0].input : options.input;
639
+ const journal = events.slice(initOffset);
640
+ const journalEntries = entries.slice(initOffset);
656
641
  let [snapshot, actions] = (0, xstate.initialTransition)(machine, input);
657
642
  let effects = getAgentEffects(machine, snapshot, actions, {
658
643
  ...options,
659
- history: entries.slice(0, events[0]?.type === "@agent.init" ? 1 : 0)
644
+ history: entries.slice(0, initOffset)
660
645
  });
661
- if (events[0]?.type === "@agent.init") verifyEntry(entries[0], snapshot, effects, options.verify);
646
+ if (initOffset) verifyEntry(entries[0], snapshot, effects, options.verify);
662
647
  const sessions = /* @__PURE__ */ new Map();
663
648
  for (let index = 0; index < journal.length; index++) {
664
649
  const event = journal[index];
665
650
  const reboundEvent = rebindActorSession(event, snapshot, sessions);
666
651
  [snapshot, actions] = (0, xstate.transition)(machine, snapshot, reboundEvent);
667
- const consumed = entries.slice(0, entries.length - journalEntries.length + index + 1);
652
+ const consumed = entries.slice(0, initOffset + index + 1);
668
653
  effects = getAgentEffects(machine, snapshot, actions, {
669
654
  ...options,
670
655
  history: consumed
@@ -816,10 +801,7 @@ function sortJson(value) {
816
801
  return value;
817
802
  }
818
803
  function hashStableJson(value) {
819
- const input = stableJson(value);
820
- let hash = 5381;
821
- for (let index = 0; index < input.length; index++) hash = (hash << 5) + hash + input.charCodeAt(index) | 0;
822
- return (hash >>> 0).toString(16).padStart(8, "0");
804
+ return require_decision.djb2Hex(stableJson(value));
823
805
  }
824
806
  function diffJson(before, after, path = "") {
825
807
  if (stableJson(before) === stableJson(after)) return [];
@@ -893,6 +875,9 @@ const DECIDE_SRC = "agent.decide";
893
875
  const workflowConfigWholeExpressionPattern = /^\{\{\s*([\s\S]*?)\s*\}\}$/;
894
876
  const workflowConfigTemplateExpressionPattern = /\{\{\s*([\s\S]*?)\s*\}\}/g;
895
877
  const workflowConfigHasTemplatePattern = /\{\{[\s\S]*?\}\}/;
878
+ function toArray(value) {
879
+ return Array.isArray(value) ? value : [value];
880
+ }
896
881
  function evaluateWorkflowConfigPath(expression, scope) {
897
882
  const parts = expression.trim().split(".").filter(Boolean);
898
883
  let current = scope;
@@ -926,6 +911,7 @@ function createSchemasFromWorkflowConfig(config, compileSchema) {
926
911
  });
927
912
  }
928
913
  function createRequestsFromWorkflowConfig(config, compileSchema) {
914
+ const resolver = (value) => value === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(value, { input });
929
915
  return Object.fromEntries(Object.entries(config.requests ?? {}).map(([key, request]) => [key, {
930
916
  mode: request.mode,
931
917
  description: request.description,
@@ -934,19 +920,19 @@ function createRequestsFromWorkflowConfig(config, compileSchema) {
934
920
  output: compileSchema(request.output, `${key}.output`)
935
921
  },
936
922
  model: ({ input }) => String(evaluateWorkflowConfigValue(request.model, { input }) ?? ""),
937
- system: request.system === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(request.system, { input }),
938
- prompt: request.prompt === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(request.prompt, { input }),
939
- messages: request.messages === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(request.messages, { input }),
923
+ system: resolver(request.system),
924
+ prompt: resolver(request.prompt),
925
+ messages: resolver(request.messages),
940
926
  tools: request.tools,
941
927
  toolChoice: request.toolChoice,
942
928
  reasoning: request.reasoning,
943
- temperature: request.temperature === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(request.temperature, { input }),
944
- maxOutputTokens: request.maxOutputTokens === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(request.maxOutputTokens, { input }),
945
- topP: request.topP === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(request.topP, { input }),
946
- topK: request.topK === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(request.topK, { input }),
947
- seed: request.seed === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(request.seed, { input }),
948
- stopSequences: request.stopSequences === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(request.stopSequences, { input }),
949
- metadata: request.metadata === void 0 ? void 0 : ({ input }) => evaluateWorkflowConfigValue(request.metadata, { input })
929
+ temperature: resolver(request.temperature),
930
+ maxOutputTokens: resolver(request.maxOutputTokens),
931
+ topP: resolver(request.topP),
932
+ topK: resolver(request.topK),
933
+ seed: resolver(request.seed),
934
+ stopSequences: resolver(request.stopSequences),
935
+ metadata: resolver(request.metadata)
950
936
  }]));
951
937
  }
952
938
  function createActorPlaceholdersFromWorkflowConfig(config) {
@@ -1012,7 +998,7 @@ function translateWorkflowAction(action, translation, location) {
1012
998
  throw new Error(`setupAgent.fromConfig: ${location} action must declare 'assign', 'emit', or 'type'.`);
1013
999
  }
1014
1000
  function translateWorkflowTransition(transitionConfig, translation, location) {
1015
- const actionConfigs = transitionConfig.actions ? Array.isArray(transitionConfig.actions) ? transitionConfig.actions : [transitionConfig.actions] : [];
1001
+ const actionConfigs = transitionConfig.actions ? toArray(transitionConfig.actions) : [];
1016
1002
  const assignConfigs = [...transitionConfig.assign !== void 0 ? [transitionConfig.assign] : [], ...actionConfigs.filter((action) => action.assign !== void 0).map((action) => action.assign)];
1017
1003
  const contextPatch = assignConfigs.length ? toWorkflowExpression(Object.assign({}, ...assignConfigs)) : void 0;
1018
1004
  const actions = actionConfigs.filter((action) => action.assign === void 0).map((action) => translateWorkflowAction(action, translation, location));
@@ -1054,9 +1040,8 @@ function translateWorkflowInvoke(invokeConfig, translation, stateKey) {
1054
1040
  }
1055
1041
  function assertValidTransitionTargets(stateKey, location, transitionConfig, siblingKeys, declaredTargets) {
1056
1042
  if (!transitionConfig) return;
1057
- const transitions = Array.isArray(transitionConfig) ? transitionConfig : [transitionConfig];
1058
- for (const transition of transitions) {
1059
- const targets = transition.target === void 0 ? [] : Array.isArray(transition.target) ? transition.target : [transition.target];
1043
+ for (const transition of toArray(transitionConfig)) {
1044
+ const targets = transition.target === void 0 ? [] : toArray(transition.target);
1060
1045
  for (const target of targets) {
1061
1046
  if (typeof target !== "string") continue;
1062
1047
  declaredTargets.push(target);
@@ -1068,16 +1053,16 @@ function assertValidTransitionTargets(stateKey, location, transitionConfig, sibl
1068
1053
  }
1069
1054
  function assertStateTransitionTargets(stateKey, stateConfig, siblingKeys) {
1070
1055
  const declaredTargets = [];
1071
- for (const [eventType, transition] of Object.entries(stateConfig.on ?? {})) assertValidTransitionTargets(stateKey, `'on.${eventType}'`, transition, siblingKeys, declaredTargets);
1072
- for (const [delay, transition] of Object.entries(stateConfig.after ?? {})) assertValidTransitionTargets(stateKey, `'after.${delay}'`, transition, siblingKeys, declaredTargets);
1073
- assertValidTransitionTargets(stateKey, "'always'", stateConfig.always, siblingKeys, declaredTargets);
1074
- assertValidTransitionTargets(stateKey, "'onDone'", stateConfig.onDone, siblingKeys, declaredTargets);
1075
- assertValidTransitionTargets(stateKey, "'choice'", stateConfig.choice, siblingKeys, declaredTargets);
1076
- const invokes = stateConfig.invoke ? Array.isArray(stateConfig.invoke) ? stateConfig.invoke : [stateConfig.invoke] : [];
1077
- for (const invoke of invokes) {
1078
- assertValidTransitionTargets(stateKey, "invoke 'onDone'", invoke.onDone, siblingKeys, declaredTargets);
1079
- assertValidTransitionTargets(stateKey, "invoke 'onError'", invoke.onError, siblingKeys, declaredTargets);
1080
- }
1056
+ const invokes = stateConfig.invoke ? toArray(stateConfig.invoke) : [];
1057
+ const sources = [
1058
+ ...Object.entries(stateConfig.on ?? {}).map(([eventType, transition]) => [`'on.${eventType}'`, transition]),
1059
+ ...Object.entries(stateConfig.after ?? {}).map(([delay, transition]) => [`'after.${delay}'`, transition]),
1060
+ ["'always'", stateConfig.always],
1061
+ ["'onDone'", stateConfig.onDone],
1062
+ ["'choice'", stateConfig.choice],
1063
+ ...invokes.flatMap((invoke) => [["invoke 'onDone'", invoke.onDone], ["invoke 'onError'", invoke.onError]])
1064
+ ];
1065
+ for (const [location, transition] of sources) assertValidTransitionTargets(stateKey, location, transition, siblingKeys, declaredTargets);
1081
1066
  return declaredTargets;
1082
1067
  }
1083
1068
  function translateWorkflowState(stateKey, stateConfig, siblingKeys, path, translation) {
@@ -1097,7 +1082,7 @@ function translateWorkflowState(stateKey, stateConfig, siblingKeys, path, transl
1097
1082
  ...doneStateId ? { id: doneStateId } : {},
1098
1083
  ...stateConfig.initial !== void 0 ? { initial: stateConfig.initial } : {},
1099
1084
  ...stateConfig.states !== void 0 ? { states: Object.fromEntries(Object.entries(stateConfig.states).map(([key, child]) => [key, translateWorkflowState(key, child, childKeys, childPath, translation)])) } : {},
1100
- ...stateConfig.choice !== void 0 ? { choice: (Array.isArray(stateConfig.choice) ? stateConfig.choice : [stateConfig.choice]).map((branch) => {
1085
+ ...stateConfig.choice !== void 0 ? { choice: toArray(stateConfig.choice).map((branch) => {
1101
1086
  if (branch.actions !== void 0) throw new Error(`setupAgent.fromConfig: state '${stateKey}' has a 'choice' branch with 'actions', which is not supported. Use 'assign' on the branch, or move the actions to the target state's 'entry'.`);
1102
1087
  const when = translateWorkflowGuard(branch.guard, translation, location);
1103
1088
  return {
@@ -1113,8 +1098,8 @@ function translateWorkflowState(stateKey, stateConfig, siblingKeys, path, transl
1113
1098
  ...Object.keys(translatedOn).length ? { on: translatedOn } : {},
1114
1099
  ...stateConfig.always !== void 0 ? { always: translateWorkflowTransitions(stateConfig.always, translation, location) } : {},
1115
1100
  ...stateConfig.after !== void 0 ? { after: Object.fromEntries(Object.entries(stateConfig.after).map(([delay, transitionConfig]) => [delay, translateWorkflowTransitions(transitionConfig, translation, location)])) } : {},
1116
- ...stateConfig.entry !== void 0 ? { entry: (Array.isArray(stateConfig.entry) ? stateConfig.entry : [stateConfig.entry]).map((action) => translateWorkflowAction(action, translation, location)) } : {},
1117
- ...stateConfig.exit !== void 0 ? { exit: (Array.isArray(stateConfig.exit) ? stateConfig.exit : [stateConfig.exit]).map((action) => translateWorkflowAction(action, translation, location)) } : {},
1101
+ ...stateConfig.entry !== void 0 ? { entry: toArray(stateConfig.entry).map((action) => translateWorkflowAction(action, translation, location)) } : {},
1102
+ ...stateConfig.exit !== void 0 ? { exit: toArray(stateConfig.exit).map((action) => translateWorkflowAction(action, translation, location)) } : {},
1118
1103
  ...stateConfig.tags !== void 0 ? { tags: stateConfig.tags } : {},
1119
1104
  ...stateConfig.output !== void 0 ? { output: toWorkflowExpression(stateConfig.output) } : {},
1120
1105
  ...stateConfig.meta !== void 0 ? { meta: stateConfig.meta } : {}
@@ -1226,7 +1211,7 @@ const agentUsageEventSchema = { "~standard": {
1226
1211
  path: ["usage", field]
1227
1212
  });
1228
1213
  }
1229
- if (event.kind !== void 0 && !USAGE_KINDS.includes(event.kind)) issues.push({
1214
+ if (event.kind !== void 0 && !USAGE_KINDS.some((kind) => kind === event.kind)) issues.push({
1230
1215
  message: `Expected one of ${USAGE_KINDS.join(", ")}`,
1231
1216
  path: ["kind"]
1232
1217
  });
@@ -1356,7 +1341,47 @@ function resolveAgentStateSchemas(contextSchema, states) {
1356
1341
  * ```
1357
1342
  */
1358
1343
  function setupAgent(config) {
1359
- return createSetupAgent(config);
1344
+ const schemas = normalizeAgentSchemas(config);
1345
+ const requestActors = createRequestActors(config.requests ?? {});
1346
+ const actors = createAgentActors(config.actors, requestActors);
1347
+ const base = (0, xstate.setup)({
1348
+ schemas: {
1349
+ context: schemas.context,
1350
+ events: schemas.events,
1351
+ input: schemas.input,
1352
+ output: schemas.output,
1353
+ meta: schemas.meta,
1354
+ ...schemas.emitted && Object.keys(schemas.emitted).length > 0 ? { emitted: schemas.emitted } : {}
1355
+ },
1356
+ ...config.states ? { states: resolveAgentStateSchemas(schemas.context, config.states) } : {},
1357
+ actors,
1358
+ actions: config.actions,
1359
+ guards: config.guards,
1360
+ delays: config.delays
1361
+ });
1362
+ const createBaseMachine = base.createMachine.bind(base);
1363
+ const models = config.models ?? {};
1364
+ const machineOptions = {
1365
+ schemas,
1366
+ actors,
1367
+ models
1368
+ };
1369
+ return Object.assign(base, {
1370
+ createMachine(machineConfig) {
1371
+ assertStateSchemaKeysExist(config.states, machineConfig?.states);
1372
+ const machine = createBaseMachine(withRootOutputFromSingleFinal(machineConfig));
1373
+ require_decision.agentExecutionOptions.set(machine, machineOptions);
1374
+ if (config.isSuspended) {
1375
+ const rootConfig = machine.config;
1376
+ if (rootConfig) require_decision.machineSuspensionPredicates.set(rootConfig, config.isSuspended);
1377
+ }
1378
+ return machine;
1379
+ },
1380
+ schemas,
1381
+ models,
1382
+ requests: requestActors,
1383
+ appendMessages
1384
+ });
1360
1385
  }
1361
1386
  function collectFinalStateOutputs(states, outputs = []) {
1362
1387
  for (const state of Object.values(states ?? {})) {
@@ -1400,24 +1425,6 @@ function normalizeAgentSchemas(config) {
1400
1425
  context: loose.context
1401
1426
  });
1402
1427
  }
1403
- function normalizeAgentRequestInput(requests) {
1404
- return requests ?? {};
1405
- }
1406
- /**
1407
- * Runtime guard: a key appearing in both `actors`/`requests` is almost
1408
- * certainly a mistake (whichever spread applies last would silently win) —
1409
- * fail fast with a clear message rather than let one implementation shadow
1410
- * another.
1411
- */
1412
- function assertNoActorKeyCollisions(actors, requests) {
1413
- const seenIn = /* @__PURE__ */ new Map();
1414
- const groups = [["actors", actors], ["requests", requests]];
1415
- for (const [groupName, group] of groups) for (const key of Object.keys(group ?? {})) {
1416
- const existingGroup = seenIn.get(key);
1417
- if (existingGroup) throw new Error(`setupAgent: key '${key}' is defined in both '${existingGroup}' and '${groupName}'. Each actor source key must be unique across 'actors' and 'requests'.`);
1418
- seenIn.set(key, groupName);
1419
- }
1420
- }
1421
1428
  /**
1422
1429
  * Runtime guard: every key of the `setupAgent({ states })` narrowing map must
1423
1430
  * name a real state node in the machine config. A typo'd key is otherwise a
@@ -1443,20 +1450,30 @@ const RESERVED_AGENT_ACTOR_KEYS = [
1443
1450
  require_decision.DECIDE_ACTOR
1444
1451
  ];
1445
1452
  /**
1446
- * Rejects a user-supplied `actors`/`requests` key in the reserved
1447
- * `agent.*` builtin namespace. Without this, the builtins-first spread in
1448
- * {@link createAgentActors} lets such a key overwrite the builtin
1449
- * (`agent.decide`, …) silently. Deliberate override of a builtin
1450
- * is still possible after the machine is created, via
1451
- * `machine.provide({ actors: { 'agent.decide': ... } })`.
1453
+ * Runtime guards over the user-supplied `actors`/`requests` keys, in one walk
1454
+ * of both groups:
1455
+ *
1456
+ * 1. A key in the reserved `agent.*` builtin namespace is rejected. Without
1457
+ * this, the builtins-first spread in {@link createAgentActors} lets such a
1458
+ * key overwrite the builtin (`agent.decide`, …) silently. Deliberate
1459
+ * override of a builtin is still possible after the machine is created, via
1460
+ * `machine.provide({ actors: { 'agent.decide': ... } })`.
1461
+ * 2. A key appearing in BOTH groups is almost certainly a mistake (whichever
1462
+ * spread applies last would silently win) — fail fast with a clear message
1463
+ * rather than let one implementation shadow another.
1452
1464
  */
1453
- function assertNoReservedAgentKeys(actors, requests) {
1465
+ function assertActorKeys(actors, requests) {
1466
+ const seenIn = /* @__PURE__ */ new Map();
1454
1467
  const groups = [["actors", actors], ["requests", requests]];
1455
- for (const [groupName, group] of groups) for (const key of Object.keys(group ?? {})) if (RESERVED_AGENT_ACTOR_KEYS.includes(key)) throw new Error(`setupAgent: '${groupName}' key '${key}' is a reserved builtin agent actor and cannot be redefined here (it would silently clobber the builtin). Reserved keys: ${RESERVED_AGENT_ACTOR_KEYS.join(", ")}. To deliberately override a builtin, do it on the created machine instead: machine.provide({ actors: { '${key}': ... } }).`);
1468
+ for (const [groupName, group] of groups) for (const key of Object.keys(group ?? {})) {
1469
+ if (RESERVED_AGENT_ACTOR_KEYS.some((reserved) => reserved === key)) throw new Error(`setupAgent: '${groupName}' key '${key}' is a reserved builtin agent actor and cannot be redefined here (it would silently clobber the builtin). Reserved keys: ${RESERVED_AGENT_ACTOR_KEYS.join(", ")}. To deliberately override a builtin, do it on the created machine instead: machine.provide({ actors: { '${key}': ... } }).`);
1470
+ const existingGroup = seenIn.get(key);
1471
+ if (existingGroup) throw new Error(`setupAgent: key '${key}' is defined in both '${existingGroup}' and '${groupName}'. Each actor source key must be unique across 'actors' and 'requests'.`);
1472
+ seenIn.set(key, groupName);
1473
+ }
1456
1474
  }
1457
1475
  function createAgentActors(actors, requestActors) {
1458
- assertNoActorKeyCollisions(actors, requestActors);
1459
- assertNoReservedAgentKeys(actors, requestActors);
1476
+ assertActorKeys(actors, requestActors);
1460
1477
  return {
1461
1478
  ...require_decision.builtinTextActors,
1462
1479
  [require_decision.USER_INPUT_ACTOR]: require_decision.userInputActor,
@@ -1465,54 +1482,6 @@ function createAgentActors(actors, requestActors) {
1465
1482
  ...requestActors
1466
1483
  };
1467
1484
  }
1468
- function createAgentSetupConfig(schemas, actors, config) {
1469
- return {
1470
- schemas: {
1471
- context: schemas.context,
1472
- events: schemas.events,
1473
- input: schemas.input,
1474
- output: schemas.output,
1475
- meta: schemas.meta,
1476
- ...schemas.emitted && Object.keys(schemas.emitted).length > 0 ? { emitted: schemas.emitted } : {}
1477
- },
1478
- ...config.states ? { states: resolveAgentStateSchemas(schemas.context, config.states) } : {},
1479
- actors,
1480
- actions: config.actions,
1481
- guards: config.guards,
1482
- delays: config.delays
1483
- };
1484
- }
1485
- function createSetupAgent(config) {
1486
- const schemas = normalizeAgentSchemas(config);
1487
- const requestActors = createRequestActors(normalizeAgentRequestInput(config.requests));
1488
- const actors = createAgentActors(config.actors, requestActors);
1489
- const base = (0, xstate.setup)(createAgentSetupConfig(schemas, actors, config));
1490
- const createBaseMachine = base.createMachine.bind(base);
1491
- const models = config.models ?? {};
1492
- const machineOptions = {
1493
- schemas,
1494
- actors,
1495
- models
1496
- };
1497
- return Object.assign(base, {
1498
- createMachine(machineConfig) {
1499
- assertStateSchemaKeysExist(config.states, machineConfig?.states);
1500
- const machine = createBaseMachine(withRootOutputFromSingleFinal(machineConfig));
1501
- require_decision.agentExecutionOptions.set(machine, machineOptions);
1502
- if (config.isSuspended) {
1503
- const rootConfig = machine.config;
1504
- if (rootConfig) require_decision.machineSuspensionPredicates.set(rootConfig, config.isSuspended);
1505
- }
1506
- return machine;
1507
- },
1508
- schemas,
1509
- models,
1510
- requests: requestActors,
1511
- appendMessages(resolve) {
1512
- return appendMessages(resolve);
1513
- }
1514
- });
1515
- }
1516
1485
  //#endregion
1517
1486
  Object.defineProperty(exports, "AGENT_INIT_EVENT_TYPE", {
1518
1487
  enumerable: true,
@@ -1574,12 +1543,6 @@ Object.defineProperty(exports, "getAgentEffects", {
1574
1543
  return getAgentEffects;
1575
1544
  }
1576
1545
  });
1577
- Object.defineProperty(exports, "getCallUsage", {
1578
- enumerable: true,
1579
- get: function() {
1580
- return getCallUsage;
1581
- }
1582
- });
1583
1546
  Object.defineProperty(exports, "getInvokeEffectMetadata", {
1584
1547
  enumerable: true,
1585
1548
  get: function() {
@@ -1628,6 +1591,12 @@ Object.defineProperty(exports, "transitionAgentStep", {
1628
1591
  return transitionAgentStep;
1629
1592
  }
1630
1593
  });
1594
+ Object.defineProperty(exports, "validateReplayEntries", {
1595
+ enumerable: true,
1596
+ get: function() {
1597
+ return validateReplayEntries;
1598
+ }
1599
+ });
1631
1600
  Object.defineProperty(exports, "verifyReplay", {
1632
1601
  enumerable: true,
1633
1602
  get: function() {