@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.
- package/dist/ai-sdk.cjs +4 -2
- package/dist/ai-sdk.d.cts +1 -1
- package/dist/ai-sdk.d.mts +1 -1
- package/dist/ai-sdk.mjs +3 -2
- package/dist/{decision-C11xuud2.mjs → decision-BfhSgCc6.mjs} +48 -28
- package/dist/{decision-DnQCQPew.cjs → decision-DhsKLYAI.cjs} +64 -43
- package/dist/{event-log-store-CQJq8_v4.d.cts → event-log-store-Bz7HDBkE.d.cts} +11 -12
- package/dist/{event-log-store-B-1fcfkT.mjs → event-log-store-DmIDosD6.mjs} +22 -14
- package/dist/{event-log-store-yquOV1TX.cjs → event-log-store-a_TKy1gk.cjs} +22 -14
- package/dist/{event-log-store-BrC9Q1xW.d.mts → event-log-store-hrA1vqtN.d.mts} +11 -12
- package/dist/index.cjs +458 -109
- package/dist/index.d.cts +209 -81
- package/dist/index.d.mts +209 -81
- package/dist/index.mjs +455 -108
- package/dist/machines.cjs +13 -17
- package/dist/machines.d.cts +14 -17
- package/dist/machines.d.mts +14 -17
- package/dist/machines.mjs +13 -17
- package/dist/otel.cjs +1 -0
- package/dist/otel.d.cts +1 -1
- package/dist/otel.d.mts +1 -1
- package/dist/{run-agent-r9OD4z8F.d.cts → run-agent--4bbms-D.d.cts} +121 -48
- package/dist/{run-agent-DQIDikfd.d.mts → run-agent-CwmzAZwj.d.mts} +121 -48
- package/dist/{setup-agent-BrE2zFDy.mjs → setup-agent-BOcSpsIq.mjs} +38 -28
- package/dist/{setup-agent-C3ETi_HZ.cjs → setup-agent-gISRLxRe.cjs} +44 -33
- package/dist/sqlite.cjs +3 -9
- package/dist/sqlite.d.cts +1 -1
- package/dist/sqlite.d.mts +1 -1
- package/dist/sqlite.mjs +3 -9
- package/dist/{text-logic-VcWqO-Cl.d.cts → text-logic-Cavva1W6.d.cts} +24 -8
- package/dist/{text-logic-RvnlD-An.d.mts → text-logic-Er5KkTX6.d.mts} +24 -8
- package/dist/validate.cjs +436 -0
- package/dist/validate.d.cts +31 -0
- package/dist/validate.d.mts +31 -0
- package/dist/validate.mjs +411 -0
- package/package.json +17 -3
- package/schemas/agent-workflow.json +2 -2
- 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-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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 (
|
|
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.
|
|
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
|
|
147
|
-
*
|
|
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
|
-
|
|
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({
|
|
236
|
-
* `setupAgent.fromConfig` (its `
|
|
237
|
-
* `
|
|
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
|
|
241
|
-
/** Reads the {@link
|
|
242
|
-
function
|
|
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 ?
|
|
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
|
|
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
|
-
* `
|
|
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,
|
|
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,
|
|
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,
|
|
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 (
|
|
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.
|
|
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
|
|
147
|
-
*
|
|
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
|
-
|
|
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({
|
|
236
|
-
* `setupAgent.fromConfig` (its `
|
|
237
|
-
* `
|
|
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
|
|
241
|
-
/** Reads the {@link
|
|
242
|
-
function
|
|
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 ?
|
|
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
|
|
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
|
-
* `
|
|
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,
|
|
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,
|
|
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, "
|
|
1165
|
+
Object.defineProperty(exports, "getMachineIdlePredicate", {
|
|
1145
1166
|
enumerable: true,
|
|
1146
1167
|
get: function() {
|
|
1147
|
-
return
|
|
1168
|
+
return getMachineIdlePredicate;
|
|
1148
1169
|
}
|
|
1149
1170
|
});
|
|
1150
|
-
Object.defineProperty(exports, "
|
|
1171
|
+
Object.defineProperty(exports, "getMachineStaticTransitionTargets", {
|
|
1151
1172
|
enumerable: true,
|
|
1152
1173
|
get: function() {
|
|
1153
|
-
return
|
|
1174
|
+
return getMachineStaticTransitionTargets;
|
|
1154
1175
|
}
|
|
1155
1176
|
});
|
|
1156
|
-
Object.defineProperty(exports, "
|
|
1177
|
+
Object.defineProperty(exports, "getMachineStructuralHash", {
|
|
1157
1178
|
enumerable: true,
|
|
1158
1179
|
get: function() {
|
|
1159
|
-
return
|
|
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, "
|
|
1219
|
+
Object.defineProperty(exports, "machineIdlePredicates", {
|
|
1199
1220
|
enumerable: true,
|
|
1200
1221
|
get: function() {
|
|
1201
|
-
return
|
|
1222
|
+
return machineIdlePredicates;
|
|
1202
1223
|
}
|
|
1203
1224
|
});
|
|
1204
|
-
Object.defineProperty(exports, "
|
|
1225
|
+
Object.defineProperty(exports, "machineStaticTransitionTargets", {
|
|
1205
1226
|
enumerable: true,
|
|
1206
1227
|
get: function() {
|
|
1207
|
-
return
|
|
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
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
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;
|
|
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. `
|
|
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
|
|
133
|
-
constructor(threadId: string, expectedIndex: 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.
|
|
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-
|
|
244
|
-
|
|
243
|
+
newThreadId: "fork-2",
|
|
244
|
+
upToIndex: 2
|
|
245
245
|
});
|
|
246
|
-
assertJsonEqual((await store.read("fork-
|
|
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. `
|
|
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
|
-
|
|
361
|
-
constructor(threadId, expectedIndex,
|
|
362
|
-
super("event-log-conflict", `AgentEventLogStore.append:
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
}
|