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