@statelyai/agent 2.0.0-alpha.18 → 2.0.0-alpha.20

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-BfhSgCc6.mjs} +48 -28
  6. package/dist/{decision-DnQCQPew.cjs → decision-DhsKLYAI.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 +458 -109
  12. package/dist/index.d.cts +209 -81
  13. package/dist/index.d.mts +209 -81
  14. package/dist/index.mjs +455 -108
  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-r9OD4z8F.d.cts → run-agent--4bbms-D.d.cts} +121 -48
  23. package/dist/{run-agent-DQIDikfd.d.mts → run-agent-CwmzAZwj.d.mts} +121 -48
  24. package/dist/{setup-agent-BrE2zFDy.mjs → setup-agent-BOcSpsIq.mjs} +38 -28
  25. package/dist/{setup-agent-C3ETi_HZ.cjs → setup-agent-gISRLxRe.cjs} +44 -33
  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-VcWqO-Cl.d.cts → text-logic-Cavva1W6.d.cts} +24 -8
  31. package/dist/{text-logic-RvnlD-An.d.mts → text-logic-Er5KkTX6.d.mts} +24 -8
  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 +17 -3
  37. package/schemas/agent-workflow.json +2 -2
  38. package/skills/generate-machine/SKILL.md +12 -14
package/dist/ai-sdk.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_decision = require("./decision-DnQCQPew.cjs");
2
+ const require_decision = require("./decision-DhsKLYAI.cjs");
3
+ require("./validate.cjs");
3
4
  let ai = require("ai");
4
5
  //#region src/ai-sdk/mappers.ts
5
6
  /**
@@ -142,7 +143,8 @@ function toDecisionMessages(request) {
142
143
  //#endregion
143
144
  //#region src/ai-sdk/index.ts
144
145
  function maxStepsSetting(request) {
145
- return typeof request.metadata?.maxSteps === "number" ? { stopWhen: (0, ai.stepCountIs)(request.metadata.maxSteps) } : {};
146
+ const maxSteps = typeof request.maxSteps === "number" ? request.maxSteps : request.metadata?.maxSteps;
147
+ return typeof maxSteps === "number" ? { stopWhen: (0, ai.stepCountIs)(maxSteps) } : {};
146
148
  }
147
149
  /**
148
150
  * Identity helper for a `models` map whose value is exported. Returns the map
package/dist/ai-sdk.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { d as ChosenEvent } from "./types-pJ5Hn8fv.cjs";
2
- import { A as AgentDecisionExecutor, l as AgentRequestExecutors, o as AgentRequestExecutor } from "./text-logic-VcWqO-Cl.cjs";
2
+ import { A as AgentDecisionExecutor, l as AgentRequestExecutors, o as AgentRequestExecutor } from "./text-logic-Cavva1W6.cjs";
3
3
  import { FinishReason, LanguageModel, LanguageModelUsage, ToolSet, TypedToolCall, TypedToolResult } from "ai";
4
4
 
5
5
  //#region src/ai-sdk/index.d.ts
package/dist/ai-sdk.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { d as ChosenEvent } from "./types-DYpK3QF4.mjs";
2
- import { A as AgentDecisionExecutor, l as AgentRequestExecutors, o as AgentRequestExecutor } from "./text-logic-RvnlD-An.mjs";
2
+ import { A as AgentDecisionExecutor, l as AgentRequestExecutors, o as AgentRequestExecutor } from "./text-logic-Er5KkTX6.mjs";
3
3
  import { FinishReason, LanguageModel, LanguageModelUsage, ToolSet, TypedToolCall, TypedToolResult } from "ai";
4
4
 
5
5
  //#region src/ai-sdk/index.d.ts
package/dist/ai-sdk.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { H as isStandardSchema, _ as getAgentOutputMode, i as renderDecisionAttempts, p as buildEnvelopeSchema } from "./decision-C11xuud2.mjs";
1
+ import { H as isStandardSchema, _ as getAgentOutputMode, i as renderDecisionAttempts, p as buildEnvelopeSchema } from "./decision-BfhSgCc6.mjs";
2
2
  import { NoObjectGeneratedError, Output, generateText, stepCountIs, streamText, tool } from "ai";
3
3
  //#region src/ai-sdk/mappers.ts
4
4
  /**
@@ -141,7 +141,8 @@ function toDecisionMessages(request) {
141
141
  //#endregion
142
142
  //#region src/ai-sdk/index.ts
143
143
  function maxStepsSetting(request) {
144
- return typeof request.metadata?.maxSteps === "number" ? { stopWhen: stepCountIs(request.metadata.maxSteps) } : {};
144
+ const maxSteps = typeof request.maxSteps === "number" ? request.maxSteps : request.metadata?.maxSteps;
145
+ return typeof maxSteps === "number" ? { stopWhen: stepCountIs(maxSteps) } : {};
145
146
  }
146
147
  /**
147
148
  * Identity helper for a `models` map whose value is exported. Returns the map
@@ -2,18 +2,9 @@ import { t as AgentError } from "./errors-CeSXQx0v.mjs";
2
2
  import { createAsyncLogic, getNextTransitions } from "xstate";
3
3
  //#region src/utils.ts
4
4
  /**
5
- * Deep-clones a snapshot to a plain-JSON value via a `JSON` round-trip, the
6
- * shape you persist and later feed back to `runAgent({ snapshot })`. Asserts
7
- * JSON-serializability: functions, `undefined`, and other non-JSON values are
8
- * dropped or throw exactly as `JSON.stringify`/`JSON.parse` would. Returns a
9
- * plain-JSON deep clone, not a live snapshot.
10
- */
11
- function persistSnapshot(snapshot) {
12
- return JSON.parse(JSON.stringify(snapshot));
13
- }
14
- /**
15
5
  * Walks a context value and returns the dot-paths of the first few values that
16
- * would NOT survive a JSON persist/resume round-trip (see {@link persistSnapshot}):
6
+ * would NOT survive a JSON persist/resume round-trip (persist with XState's
7
+ * `actor.getPersistedSnapshot()`, resume with `createActor(machine, { snapshot })`):
17
8
  * `Date`, `Map`, `Set`, `RegExp`, functions, `undefined`, `bigint`, class
18
9
  * instances (non-plain objects), and circular references. Plain objects,
19
10
  * arrays, and JSON primitives are walked/allowed. Returns `[]` for a
@@ -68,11 +59,22 @@ function findNonSerializableContextPaths(context, limit = 5) {
68
59
  * Used by {@link runAgent} to stamp settled snapshots with a `version` and to
69
60
  * detect a structurally-edited machine on resume. It is a change detector, not
70
61
  * a cryptographic digest — collisions are possible but unlikely for real
71
- * configs. Pass an explicit `machineVersion` to `runAgent` to override it.
62
+ * configs. Declare `createMachine({ version })` to pin an explicit version instead.
72
63
  */
73
64
  function getMachineStructuralHash(machine) {
74
65
  return djb2Hex(stableStructuralString(machine.config));
75
66
  }
67
+ /**
68
+ * The version a machine is stamped with everywhere: an explicitly declared
69
+ * `createMachine({ version })` when present, else its
70
+ * {@link getMachineStructuralHash}. Single source of truth so `runAgent`,
71
+ * `provideExecutors`/`traceTransitions` trace envelopes, and the event-log
72
+ * helpers (`initEntry`, `createReplayEntry`, `replay`) never disagree.
73
+ * @internal
74
+ */
75
+ function resolveMachineVersion(machine) {
76
+ return machine.version ?? getMachineStructuralHash(machine);
77
+ }
76
78
  function stableStructuralString(value, seen = /* @__PURE__ */ new WeakSet()) {
77
79
  if (value === null) return "null";
78
80
  const type = typeof value;
@@ -143,8 +145,15 @@ function toolMessage(content) {
143
145
  *
144
146
  * `snapshot.getMeta()` is keyed by state id; a leaf machine has one active
145
147
  * state, but parallel/nested machines can have several. This shallow-merges
146
- * every active state's meta into one object (later/deeper entries win) and
147
- * returns `{}` when no active state declares meta.
148
+ * every active state's meta into one object and returns `{}` when no active
149
+ * state declares meta.
150
+ *
151
+ * Merge order is fixed and does not depend on XState's internal node order:
152
+ * entries are sorted by structural depth (the state node's distance from the
153
+ * root, regardless of custom `id` strings), then by state id lexicographically,
154
+ * and merged in that order. So a deeper state's key wins over an ancestor's,
155
+ * and between equal-depth parallel siblings the later state id alphabetically
156
+ * wins.
148
157
  *
149
158
  * The return type is recovered from the snapshot's own `getMeta()` type, so a
150
159
  * schema-typed machine (`setupAgent({ meta })`) yields the meta schema's
@@ -158,7 +167,11 @@ function toolMessage(content) {
158
167
  * ```
159
168
  */
160
169
  function getStateMeta(snapshot) {
161
- return Object.assign({}, ...Object.values(snapshot.getMeta()).filter((meta) => meta != null));
170
+ const nodes = snapshot.nodes;
171
+ const depthById = new Map(nodes?.map((node) => [node.id, node.path.length]));
172
+ const depth = (id) => depthById.get(id) ?? id.split(".").length;
173
+ const entries = Object.entries(snapshot.getMeta()).filter((entry) => entry[1] != null).sort(([a], [b]) => depth(a) - depth(b) || (a < b ? -1 : a > b ? 1 : 0));
174
+ return Object.assign({}, ...entries.map(([, meta]) => meta));
162
175
  }
163
176
  /**
164
177
  * Reads the run-owned message log off a snapshot settled by a `runAgent` call
@@ -232,16 +245,16 @@ const agentExecutionOptions = /* @__PURE__ */ new WeakMap();
232
245
  * object. `config` is shared by reference across `machine.provide(...)` (unlike
233
246
  * the machine object itself), so a predicate registered here travels with the
234
247
  * machine through `.provide` — which is why it is keyed on `config`, not the
235
- * machine. Set by `setupAgent({ isSuspended })` in `createMachine` and by
236
- * `setupAgent.fromConfig` (its `isSuspended` option or the config's
237
- * `suspendedTags`), read by `runAgent` (below the host `options.isSuspended`
248
+ * machine. Set by `setupAgent({ isIdle })` in `createMachine` and by
249
+ * `setupAgent.fromConfig` (its `isIdle` option or the config's
250
+ * `idleTags`), read by `runAgent` (below the host `options.isIdle`
238
251
  * override, above the timing heuristic).
239
252
  */
240
- const machineSuspensionPredicates = /* @__PURE__ */ new WeakMap();
241
- /** Reads the {@link machineSuspensionPredicates} predicate carried by `machine` (via its root `config`), if any. */
242
- function getMachineSuspensionPredicate(machine) {
253
+ const machineIdlePredicates = /* @__PURE__ */ new WeakMap();
254
+ /** Reads the {@link machineIdlePredicates} predicate carried by `machine` (via its root `config`), if any. */
255
+ function getMachineIdlePredicate(machine) {
243
256
  const config = machine.config;
244
- return config ? machineSuspensionPredicates.get(config) : void 0;
257
+ return config ? machineIdlePredicates.get(config) : void 0;
245
258
  }
246
259
  /**
247
260
  * Lint-reachability sidecar for `fromConfig` machines.
@@ -253,7 +266,7 @@ function getMachineSuspensionPredicate(machine) {
253
266
  * context patch into an opaque resolver function, erasing its target from
254
267
  * `machine.config` — so `lintAgentMachine`'s reachability walk reads the
255
268
  * targets from here instead. Keyed on the machine's root `config` object (like
256
- * {@link machineSuspensionPredicates}) so it survives `machine.provide(...)`.
269
+ * {@link machineIdlePredicates}) so it survives `machine.provide(...)`.
257
270
  */
258
271
  const machineStaticTransitionTargets = /* @__PURE__ */ new WeakMap();
259
272
  /** Reads the {@link machineStaticTransitionTargets} map carried by `machine` (via its root `config`), if any. */
@@ -417,6 +430,7 @@ function createBuiltinTextActor(src, mode, outputSchema) {
417
430
  topK: ({ input }) => input.topK,
418
431
  seed: ({ input }) => input.seed,
419
432
  stopSequences: ({ input }) => input.stopSequences,
433
+ maxSteps: ({ input }) => input.maxSteps,
420
434
  metadata: ({ input }) => input.metadata
421
435
  }, execute);
422
436
  }
@@ -488,6 +502,7 @@ function createTextLogic(config, execute) {
488
502
  topK: resolveTextLogicValue(config.topK, args),
489
503
  seed: resolveTextLogicValue(config.seed, args),
490
504
  stopSequences: resolveTextLogicValue(config.stopSequences, args),
505
+ maxSteps: resolveTextLogicValue(config.maxSteps, args),
491
506
  metadata: resolveTextLogicValue(config.metadata, args)
492
507
  };
493
508
  };
@@ -874,7 +889,7 @@ function decideActorWithExecutor(execute) {
874
889
  const resolvedEventTypes = resolveAllowedEventTypes(input.allowedEvents, input);
875
890
  if (resolvedEventTypes === void 0) throw new Error(`'${DECIDE_ACTOR}' input has omitted \`allowedEvents\`, which means "all currently-legal events" — but that requires a snapshot-aware host (runAgent or the step path) to resolve. Under a bare createActor(...), declare \`allowedEvents\` explicitly to use this actor here.`);
876
891
  if (resolvedEventTypes.some(isEventPattern)) throw new Error(`'${DECIDE_ACTOR}' input uses wildcard \`allowedEvents\` patterns, which expand against the live snapshot — that requires a snapshot-aware host (runAgent or the step path). Under a bare createActor(...), list event types explicitly.`);
877
- return resolveDecision(decideRequestFromInput(input), execute, {
892
+ return resolveDecision(decideRequestFromInput(input), { decide: execute }, {
878
893
  maxRetries: input.maxRetries ?? 2,
879
894
  signal
880
895
  });
@@ -934,7 +949,7 @@ function renderDecisionAttempts(request) {
934
949
  }
935
950
  /**
936
951
  * Validation + retry core for decisions. No provider mechanics — the
937
- * `executor` is responsible for making the model choose an event; this
952
+ * `executors.decide` is responsible for making the model choose an event; this
938
953
  * function only validates the choice and retries on failure, up to
939
954
  * `options.maxRetries` (default 2, i.e. up to 3 attempts total).
940
955
  *
@@ -952,12 +967,14 @@ function renderDecisionAttempts(request) {
952
967
  *
953
968
  * @example
954
969
  * ```ts
955
- * const event = await resolveDecision(request, decide, {
970
+ * const event = await resolveDecision(request, executors, {
956
971
  * canTake: (e) => snapshot.can(e),
957
972
  * });
958
973
  * ```
959
974
  */
960
- async function resolveDecision(request, executor, options = {}) {
975
+ async function resolveDecision(request, executors, options = {}) {
976
+ const executor = executors?.decide;
977
+ if (typeof executor !== "function") throw new AgentError("missing-decide-executor", "resolveDecision(request, executors, ...) takes the EXECUTOR SET (the same object executeAgentRequest takes), and this one has no 'decide' function. Build one with createAiSdkExecutors({ models }), or pass { decide }.");
961
978
  const maxRetries = options.maxRetries ?? 2;
962
979
  const attempts = [];
963
980
  const eventsByType = new Map(request.events.map((event) => [event.type, event]));
@@ -967,6 +984,9 @@ async function resolveDecision(request, executor, options = {}) {
967
984
  ...request,
968
985
  attempts: [...attempts],
969
986
  signal: options.signal
987
+ }, {
988
+ ...options.signal !== void 0 ? { signal: options.signal } : {},
989
+ ...request.id ? { requestId: request.id } : {}
970
990
  });
971
991
  if (!result || typeof result !== "object" || typeof result.event !== "object" || result.event === null || typeof result.event.type !== "string") throw new Error(`decide executor must return { event: { type: string, ... } }; got ${JSON.stringify(result)}. Wrap the chosen event: return { event: { type: 'SAFE' } }.`);
972
992
  const { event } = result;
@@ -1009,4 +1029,4 @@ async function resolveDecision(request, executor, options = {}) {
1009
1029
  throw new AgentDecisionExhaustedError(attempts);
1010
1030
  }
1011
1031
  //#endregion
1012
- export { isUnboundPlaceholder as A, getMachineStructuralHash as B, parseStructuredEnvelope as C, getMachineStaticTransitionTargets as D, executorBoundLogics as E, djb2Hex as F, toolMessage as G, isStandardSchema as H, findNonSerializableContextPaths as I, userMessage as K, getAgentMessages as L, machineSuspensionPredicates as M, missingActor as N, getMachineSuspensionPredicate as O, assistantMessage as P, getJsonSchema as R, parseOutput as S, agentExecutionOptions as T, persistSnapshot as U, getStateMeta as V, systemMessage as W, getAgentOutputMode as _, resolveDecision as a, normalizeGeneratorResult as b, AGENT_USAGE_TOKEN_FIELDS as c, USER_INPUT_ACTOR as d, bindRequestExecutor as f, executeAgentTextRequest as g, createTextLogic as h, renderDecisionAttempts as i, machineStaticTransitionTargets as j, getRegisteredAgentExecutionOptions as k, DECIDE_ACTOR as l, builtinTextActors as m, createDecideActor as n, getAcceptedEvents as o, buildEnvelopeSchema as p, validateSchemaSync as q, isDecisionLogic as r, parseAgentEvent as s, AgentDecisionExhaustedError as t, INTERPRET_SOURCE as u, getCallUsage as v, userInputActor as w, parseModelRef as x, isTextLogic as y, getJsonSchemaSync as z };
1032
+ export { isUnboundPlaceholder as A, getMachineStructuralHash as B, parseStructuredEnvelope as C, getMachineIdlePredicate as D, executorBoundLogics as E, djb2Hex as F, toolMessage as G, isStandardSchema as H, findNonSerializableContextPaths as I, userMessage as K, getAgentMessages as L, machineStaticTransitionTargets as M, missingActor as N, getMachineStaticTransitionTargets as O, assistantMessage as P, getJsonSchema as R, parseOutput as S, agentExecutionOptions as T, resolveMachineVersion as U, getStateMeta as V, systemMessage as W, getAgentOutputMode as _, resolveDecision as a, normalizeGeneratorResult as b, AGENT_USAGE_TOKEN_FIELDS as c, USER_INPUT_ACTOR as d, bindRequestExecutor as f, executeAgentTextRequest as g, createTextLogic as h, renderDecisionAttempts as i, machineIdlePredicates as j, getRegisteredAgentExecutionOptions as k, DECIDE_ACTOR as l, builtinTextActors as m, createDecideActor as n, getAcceptedEvents as o, buildEnvelopeSchema as p, validateSchemaSync as q, isDecisionLogic as r, parseAgentEvent as s, AgentDecisionExhaustedError as t, INTERPRET_SOURCE as u, getCallUsage as v, userInputActor as w, parseModelRef as x, isTextLogic as y, getJsonSchemaSync as z };
@@ -1,19 +1,11 @@
1
1
  const require_errors = require("./errors-DUBBzRLP.cjs");
2
+ require("./validate.cjs");
2
3
  let xstate = require("xstate");
3
4
  //#region src/utils.ts
4
5
  /**
5
- * Deep-clones a snapshot to a plain-JSON value via a `JSON` round-trip, the
6
- * shape you persist and later feed back to `runAgent({ snapshot })`. Asserts
7
- * JSON-serializability: functions, `undefined`, and other non-JSON values are
8
- * dropped or throw exactly as `JSON.stringify`/`JSON.parse` would. Returns a
9
- * plain-JSON deep clone, not a live snapshot.
10
- */
11
- function persistSnapshot(snapshot) {
12
- return JSON.parse(JSON.stringify(snapshot));
13
- }
14
- /**
15
6
  * Walks a context value and returns the dot-paths of the first few values that
16
- * would NOT survive a JSON persist/resume round-trip (see {@link persistSnapshot}):
7
+ * would NOT survive a JSON persist/resume round-trip (persist with XState's
8
+ * `actor.getPersistedSnapshot()`, resume with `createActor(machine, { snapshot })`):
17
9
  * `Date`, `Map`, `Set`, `RegExp`, functions, `undefined`, `bigint`, class
18
10
  * instances (non-plain objects), and circular references. Plain objects,
19
11
  * arrays, and JSON primitives are walked/allowed. Returns `[]` for a
@@ -68,11 +60,22 @@ function findNonSerializableContextPaths(context, limit = 5) {
68
60
  * Used by {@link runAgent} to stamp settled snapshots with a `version` and to
69
61
  * detect a structurally-edited machine on resume. It is a change detector, not
70
62
  * a cryptographic digest — collisions are possible but unlikely for real
71
- * configs. Pass an explicit `machineVersion` to `runAgent` to override it.
63
+ * configs. Declare `createMachine({ version })` to pin an explicit version instead.
72
64
  */
73
65
  function getMachineStructuralHash(machine) {
74
66
  return djb2Hex(stableStructuralString(machine.config));
75
67
  }
68
+ /**
69
+ * The version a machine is stamped with everywhere: an explicitly declared
70
+ * `createMachine({ version })` when present, else its
71
+ * {@link getMachineStructuralHash}. Single source of truth so `runAgent`,
72
+ * `provideExecutors`/`traceTransitions` trace envelopes, and the event-log
73
+ * helpers (`initEntry`, `createReplayEntry`, `replay`) never disagree.
74
+ * @internal
75
+ */
76
+ function resolveMachineVersion(machine) {
77
+ return machine.version ?? getMachineStructuralHash(machine);
78
+ }
76
79
  function stableStructuralString(value, seen = /* @__PURE__ */ new WeakSet()) {
77
80
  if (value === null) return "null";
78
81
  const type = typeof value;
@@ -143,8 +146,15 @@ function toolMessage(content) {
143
146
  *
144
147
  * `snapshot.getMeta()` is keyed by state id; a leaf machine has one active
145
148
  * state, but parallel/nested machines can have several. This shallow-merges
146
- * every active state's meta into one object (later/deeper entries win) and
147
- * returns `{}` when no active state declares meta.
149
+ * every active state's meta into one object and returns `{}` when no active
150
+ * state declares meta.
151
+ *
152
+ * Merge order is fixed and does not depend on XState's internal node order:
153
+ * entries are sorted by structural depth (the state node's distance from the
154
+ * root, regardless of custom `id` strings), then by state id lexicographically,
155
+ * and merged in that order. So a deeper state's key wins over an ancestor's,
156
+ * and between equal-depth parallel siblings the later state id alphabetically
157
+ * wins.
148
158
  *
149
159
  * The return type is recovered from the snapshot's own `getMeta()` type, so a
150
160
  * schema-typed machine (`setupAgent({ meta })`) yields the meta schema's
@@ -158,7 +168,11 @@ function toolMessage(content) {
158
168
  * ```
159
169
  */
160
170
  function getStateMeta(snapshot) {
161
- return Object.assign({}, ...Object.values(snapshot.getMeta()).filter((meta) => meta != null));
171
+ const nodes = snapshot.nodes;
172
+ const depthById = new Map(nodes?.map((node) => [node.id, node.path.length]));
173
+ const depth = (id) => depthById.get(id) ?? id.split(".").length;
174
+ const entries = Object.entries(snapshot.getMeta()).filter((entry) => entry[1] != null).sort(([a], [b]) => depth(a) - depth(b) || (a < b ? -1 : a > b ? 1 : 0));
175
+ return Object.assign({}, ...entries.map(([, meta]) => meta));
162
176
  }
163
177
  /**
164
178
  * Reads the run-owned message log off a snapshot settled by a `runAgent` call
@@ -232,16 +246,16 @@ const agentExecutionOptions = /* @__PURE__ */ new WeakMap();
232
246
  * object. `config` is shared by reference across `machine.provide(...)` (unlike
233
247
  * the machine object itself), so a predicate registered here travels with the
234
248
  * machine through `.provide` — which is why it is keyed on `config`, not the
235
- * machine. Set by `setupAgent({ isSuspended })` in `createMachine` and by
236
- * `setupAgent.fromConfig` (its `isSuspended` option or the config's
237
- * `suspendedTags`), read by `runAgent` (below the host `options.isSuspended`
249
+ * machine. Set by `setupAgent({ isIdle })` in `createMachine` and by
250
+ * `setupAgent.fromConfig` (its `isIdle` option or the config's
251
+ * `idleTags`), read by `runAgent` (below the host `options.isIdle`
238
252
  * override, above the timing heuristic).
239
253
  */
240
- const machineSuspensionPredicates = /* @__PURE__ */ new WeakMap();
241
- /** Reads the {@link machineSuspensionPredicates} predicate carried by `machine` (via its root `config`), if any. */
242
- function getMachineSuspensionPredicate(machine) {
254
+ const machineIdlePredicates = /* @__PURE__ */ new WeakMap();
255
+ /** Reads the {@link machineIdlePredicates} predicate carried by `machine` (via its root `config`), if any. */
256
+ function getMachineIdlePredicate(machine) {
243
257
  const config = machine.config;
244
- return config ? machineSuspensionPredicates.get(config) : void 0;
258
+ return config ? machineIdlePredicates.get(config) : void 0;
245
259
  }
246
260
  /**
247
261
  * Lint-reachability sidecar for `fromConfig` machines.
@@ -253,7 +267,7 @@ function getMachineSuspensionPredicate(machine) {
253
267
  * context patch into an opaque resolver function, erasing its target from
254
268
  * `machine.config` — so `lintAgentMachine`'s reachability walk reads the
255
269
  * targets from here instead. Keyed on the machine's root `config` object (like
256
- * {@link machineSuspensionPredicates}) so it survives `machine.provide(...)`.
270
+ * {@link machineIdlePredicates}) so it survives `machine.provide(...)`.
257
271
  */
258
272
  const machineStaticTransitionTargets = /* @__PURE__ */ new WeakMap();
259
273
  /** Reads the {@link machineStaticTransitionTargets} map carried by `machine` (via its root `config`), if any. */
@@ -417,6 +431,7 @@ function createBuiltinTextActor(src, mode, outputSchema) {
417
431
  topK: ({ input }) => input.topK,
418
432
  seed: ({ input }) => input.seed,
419
433
  stopSequences: ({ input }) => input.stopSequences,
434
+ maxSteps: ({ input }) => input.maxSteps,
420
435
  metadata: ({ input }) => input.metadata
421
436
  }, execute);
422
437
  }
@@ -488,6 +503,7 @@ function createTextLogic(config, execute) {
488
503
  topK: resolveTextLogicValue(config.topK, args),
489
504
  seed: resolveTextLogicValue(config.seed, args),
490
505
  stopSequences: resolveTextLogicValue(config.stopSequences, args),
506
+ maxSteps: resolveTextLogicValue(config.maxSteps, args),
491
507
  metadata: resolveTextLogicValue(config.metadata, args)
492
508
  };
493
509
  };
@@ -874,7 +890,7 @@ function decideActorWithExecutor(execute) {
874
890
  const resolvedEventTypes = resolveAllowedEventTypes(input.allowedEvents, input);
875
891
  if (resolvedEventTypes === void 0) throw new Error(`'${DECIDE_ACTOR}' input has omitted \`allowedEvents\`, which means "all currently-legal events" — but that requires a snapshot-aware host (runAgent or the step path) to resolve. Under a bare createActor(...), declare \`allowedEvents\` explicitly to use this actor here.`);
876
892
  if (resolvedEventTypes.some(isEventPattern)) throw new Error(`'${DECIDE_ACTOR}' input uses wildcard \`allowedEvents\` patterns, which expand against the live snapshot — that requires a snapshot-aware host (runAgent or the step path). Under a bare createActor(...), list event types explicitly.`);
877
- return resolveDecision(decideRequestFromInput(input), execute, {
893
+ return resolveDecision(decideRequestFromInput(input), { decide: execute }, {
878
894
  maxRetries: input.maxRetries ?? 2,
879
895
  signal
880
896
  });
@@ -934,7 +950,7 @@ function renderDecisionAttempts(request) {
934
950
  }
935
951
  /**
936
952
  * Validation + retry core for decisions. No provider mechanics — the
937
- * `executor` is responsible for making the model choose an event; this
953
+ * `executors.decide` is responsible for making the model choose an event; this
938
954
  * function only validates the choice and retries on failure, up to
939
955
  * `options.maxRetries` (default 2, i.e. up to 3 attempts total).
940
956
  *
@@ -952,12 +968,14 @@ function renderDecisionAttempts(request) {
952
968
  *
953
969
  * @example
954
970
  * ```ts
955
- * const event = await resolveDecision(request, decide, {
971
+ * const event = await resolveDecision(request, executors, {
956
972
  * canTake: (e) => snapshot.can(e),
957
973
  * });
958
974
  * ```
959
975
  */
960
- async function resolveDecision(request, executor, options = {}) {
976
+ async function resolveDecision(request, executors, options = {}) {
977
+ const executor = executors?.decide;
978
+ if (typeof executor !== "function") throw new require_errors.AgentError("missing-decide-executor", "resolveDecision(request, executors, ...) takes the EXECUTOR SET (the same object executeAgentRequest takes), and this one has no 'decide' function. Build one with createAiSdkExecutors({ models }), or pass { decide }.");
961
979
  const maxRetries = options.maxRetries ?? 2;
962
980
  const attempts = [];
963
981
  const eventsByType = new Map(request.events.map((event) => [event.type, event]));
@@ -967,6 +985,9 @@ async function resolveDecision(request, executor, options = {}) {
967
985
  ...request,
968
986
  attempts: [...attempts],
969
987
  signal: options.signal
988
+ }, {
989
+ ...options.signal !== void 0 ? { signal: options.signal } : {},
990
+ ...request.id ? { requestId: request.id } : {}
970
991
  });
971
992
  if (!result || typeof result !== "object" || typeof result.event !== "object" || result.event === null || typeof result.event.type !== "string") throw new Error(`decide executor must return { event: { type: string, ... } }; got ${JSON.stringify(result)}. Wrap the chosen event: return { event: { type: 'SAFE' } }.`);
972
993
  const { event } = result;
@@ -1141,22 +1162,22 @@ Object.defineProperty(exports, "getJsonSchemaSync", {
1141
1162
  return getJsonSchemaSync;
1142
1163
  }
1143
1164
  });
1144
- Object.defineProperty(exports, "getMachineStaticTransitionTargets", {
1165
+ Object.defineProperty(exports, "getMachineIdlePredicate", {
1145
1166
  enumerable: true,
1146
1167
  get: function() {
1147
- return getMachineStaticTransitionTargets;
1168
+ return getMachineIdlePredicate;
1148
1169
  }
1149
1170
  });
1150
- Object.defineProperty(exports, "getMachineStructuralHash", {
1171
+ Object.defineProperty(exports, "getMachineStaticTransitionTargets", {
1151
1172
  enumerable: true,
1152
1173
  get: function() {
1153
- return getMachineStructuralHash;
1174
+ return getMachineStaticTransitionTargets;
1154
1175
  }
1155
1176
  });
1156
- Object.defineProperty(exports, "getMachineSuspensionPredicate", {
1177
+ Object.defineProperty(exports, "getMachineStructuralHash", {
1157
1178
  enumerable: true,
1158
1179
  get: function() {
1159
- return getMachineSuspensionPredicate;
1180
+ return getMachineStructuralHash;
1160
1181
  }
1161
1182
  });
1162
1183
  Object.defineProperty(exports, "getRegisteredAgentExecutionOptions", {
@@ -1195,16 +1216,16 @@ Object.defineProperty(exports, "isUnboundPlaceholder", {
1195
1216
  return isUnboundPlaceholder;
1196
1217
  }
1197
1218
  });
1198
- Object.defineProperty(exports, "machineStaticTransitionTargets", {
1219
+ Object.defineProperty(exports, "machineIdlePredicates", {
1199
1220
  enumerable: true,
1200
1221
  get: function() {
1201
- return machineStaticTransitionTargets;
1222
+ return machineIdlePredicates;
1202
1223
  }
1203
1224
  });
1204
- Object.defineProperty(exports, "machineSuspensionPredicates", {
1225
+ Object.defineProperty(exports, "machineStaticTransitionTargets", {
1205
1226
  enumerable: true,
1206
1227
  get: function() {
1207
- return machineSuspensionPredicates;
1228
+ return machineStaticTransitionTargets;
1208
1229
  }
1209
1230
  });
1210
1231
  Object.defineProperty(exports, "missingActor", {
@@ -1243,12 +1264,6 @@ Object.defineProperty(exports, "parseStructuredEnvelope", {
1243
1264
  return parseStructuredEnvelope;
1244
1265
  }
1245
1266
  });
1246
- Object.defineProperty(exports, "persistSnapshot", {
1247
- enumerable: true,
1248
- get: function() {
1249
- return persistSnapshot;
1250
- }
1251
- });
1252
1267
  Object.defineProperty(exports, "renderDecisionAttempts", {
1253
1268
  enumerable: true,
1254
1269
  get: function() {
@@ -1261,6 +1276,12 @@ Object.defineProperty(exports, "resolveDecision", {
1261
1276
  return resolveDecision;
1262
1277
  }
1263
1278
  });
1279
+ Object.defineProperty(exports, "resolveMachineVersion", {
1280
+ enumerable: true,
1281
+ get: function() {
1282
+ return resolveMachineVersion;
1283
+ }
1284
+ });
1264
1285
  Object.defineProperty(exports, "systemMessage", {
1265
1286
  enumerable: true,
1266
1287
  get: function() {
@@ -107,30 +107,29 @@ interface AgentEventLogStore {
107
107
  /** The thread's current log length (0 for an unknown thread) — the next `expectedIndex`. */
108
108
  length(threadId: string): Promise<number>;
109
109
  /**
110
- * Copy a prefix onto a fresh, empty `newThreadId` — either `[0, upToIndex)`
111
- * or through the inclusive `atEventId`. With neither cutoff the full source
112
- * is copied. The fork then appends independently. Rejects (plain `Error`) if
113
- * `newThreadId` already has entries, the source/id is unknown, or both cutoff
114
- * forms are supplied. Implementations may copy-on-write or physically copy;
115
- * observable behavior must match a full copy.
110
+ * Copy the prefix `[0, upToIndex)` onto a fresh, empty `newThreadId`.
111
+ * Without `upToIndex` the full source is copied. The fork then appends
112
+ * independently. Rejects (plain `Error`) if `newThreadId` already has
113
+ * entries, the source is unknown, or `upToIndex` is out of range.
114
+ * Implementations may copy-on-write or physically copy; observable behavior
115
+ * must match a full copy.
116
116
  */
117
117
  fork(input: {
118
118
  threadId: string;
119
- newThreadId: string;
120
- upToIndex?: number; /** Inclusive event-id cutoff. Mutually exclusive with `upToIndex`. */
121
- atEventId?: string;
119
+ newThreadId: string; /** Exclusive index cutoff. */
120
+ upToIndex?: number;
122
121
  }): Promise<void>;
123
122
  }
124
123
  /**
125
124
  * Rejection from {@link AgentEventLogStore.append} when the thread's stored
126
125
  * length is not the `expectedIndex` the writer held — a concurrent writer
127
- * appended first. `actualLength` is the length core found.
126
+ * appended first. `actualIndex` is the next index the store would accept.
128
127
  */
129
128
  declare class AgentEventLogConflictError extends AgentError {
130
129
  readonly threadId: string;
131
130
  readonly expectedIndex: number;
132
- readonly actualLength: number;
133
- constructor(threadId: string, expectedIndex: number, actualLength: number);
131
+ readonly actualIndex: number;
132
+ constructor(threadId: string, expectedIndex: number, actualIndex: number);
134
133
  }
135
134
  /**
136
135
  * In-memory reference store, and the baseline the conformance suite runs
@@ -111,7 +111,7 @@ async function assertEventLogStoreConformance(create) {
111
111
  caught = error;
112
112
  }
113
113
  if (!(caught instanceof AgentEventLogConflictError)) fail("a stale expectedIndex must throw AgentEventLogConflictError");
114
- if (caught.threadId !== "t" || caught.expectedIndex !== 0 || caught.actualLength !== 1) fail("conflict error must carry threadId, expectedIndex, and the actual length");
114
+ if (caught.threadId !== "t" || caught.expectedIndex !== 0 || caught.actualIndex !== 1) fail("conflict error must carry threadId, expectedIndex, and the actual index");
115
115
  }
116
116
  {
117
117
  const store = await create();
@@ -240,10 +240,10 @@ async function assertEventLogStoreConformance(create) {
240
240
  assertJsonEqual((await store.read("fork-1")).map((e) => e.index), [0], "fork with upToIndex 1 must copy only entry 0");
241
241
  await store.fork({
242
242
  threadId: "src",
243
- newThreadId: "fork-id",
244
- atEventId: "evt_1"
243
+ newThreadId: "fork-2",
244
+ upToIndex: 2
245
245
  });
246
- assertJsonEqual((await store.read("fork-id")).map((e) => e.id), ["evt_0", "evt_1"], "fork with atEventId must include the named entry");
246
+ assertJsonEqual((await store.read("fork-2")).map((e) => e.id), ["evt_0", "evt_1"], "fork with upToIndex 2 must copy entries 0 and 1 only");
247
247
  await store.append({
248
248
  threadId: "fork-1",
249
249
  expectedIndex: 1,
@@ -271,6 +271,17 @@ async function assertEventLogStoreConformance(create) {
271
271
  caughtUnknown = error;
272
272
  }
273
273
  if (!(caughtUnknown instanceof Error) || caughtUnknown instanceof AgentEventLogConflictError) fail("forking an unknown source thread must reject with a plain Error");
274
+ let caughtRange;
275
+ try {
276
+ await store.fork({
277
+ threadId: "src",
278
+ newThreadId: "fork-range",
279
+ upToIndex: 99
280
+ });
281
+ } catch (error) {
282
+ caughtRange = error;
283
+ }
284
+ if (!(caughtRange instanceof Error) || caughtRange instanceof AgentEventLogConflictError) fail("forking past the source length must reject with a plain Error");
274
285
  }
275
286
  }
276
287
  //#endregion
@@ -352,18 +363,18 @@ function assertAgentLogEntry(entry) {
352
363
  /**
353
364
  * Rejection from {@link AgentEventLogStore.append} when the thread's stored
354
365
  * length is not the `expectedIndex` the writer held — a concurrent writer
355
- * appended first. `actualLength` is the length core found.
366
+ * appended first. `actualIndex` is the next index the store would accept.
356
367
  */
357
368
  var AgentEventLogConflictError = class extends AgentError {
358
369
  threadId;
359
370
  expectedIndex;
360
- actualLength;
361
- constructor(threadId, expectedIndex, actualLength) {
362
- super("event-log-conflict", `AgentEventLogStore.append: length conflict on thread "${threadId}": expected length ${expectedIndex} but found ${actualLength} — a concurrent writer won.`);
371
+ actualIndex;
372
+ constructor(threadId, expectedIndex, actualIndex) {
373
+ super("event-log-conflict", `AgentEventLogStore.append: index conflict on thread "${threadId}": expected index ${expectedIndex} but found ${actualIndex} — a concurrent writer won.`);
363
374
  this.name = "AgentEventLogConflictError";
364
375
  this.threadId = threadId;
365
376
  this.expectedIndex = expectedIndex;
366
- this.actualLength = actualLength;
377
+ this.actualIndex = actualIndex;
367
378
  }
368
379
  };
369
380
  /**
@@ -402,14 +413,11 @@ function createInMemoryEventLogStore() {
402
413
  async length(threadId) {
403
414
  return threads.get(threadId)?.length ?? 0;
404
415
  },
405
- async fork({ threadId, newThreadId, upToIndex, atEventId }) {
416
+ async fork({ threadId, newThreadId, upToIndex }) {
406
417
  if ((threads.get(newThreadId)?.length ?? 0) > 0) throw new Error(`AgentEventLogStore.fork: newThreadId "${newThreadId}" already has entries.`);
407
418
  const source = threads.get(threadId);
408
419
  if (!source) throw new Error(`AgentEventLogStore.fork: unknown source thread "${threadId}".`);
409
- if (upToIndex !== void 0 && atEventId !== void 0) throw new Error("AgentEventLogStore.fork: pass either upToIndex or atEventId, not both.");
410
- const eventIndex = atEventId === void 0 ? void 0 : source.findIndex((entry) => entry.id === atEventId);
411
- if (atEventId !== void 0 && eventIndex === -1) throw new Error(`AgentEventLogStore.fork: thread "${threadId}" has no event id "${atEventId}".`);
412
- const upTo = eventIndex === void 0 ? upToIndex ?? source.length : eventIndex + 1;
420
+ const upTo = upToIndex ?? source.length;
413
421
  if (upTo < 0 || upTo > source.length) throw new Error(`AgentEventLogStore.fork: thread "${threadId}" (length ${source.length}) has no index ${upTo} to fork up to.`);
414
422
  threads.set(newThreadId, source.slice(0, upTo).map((entry) => clone(entry)));
415
423
  }