@statelyai/agent 2.0.0-alpha.13 → 2.0.0-alpha.15
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 +1 -1
- package/dist/ai-sdk.d.cts +2 -2
- package/dist/ai-sdk.d.mts +2 -2
- package/dist/ai-sdk.mjs +1 -1
- package/dist/{decision-dWGhBh0P.cjs → decision-C0cUKvNt.cjs} +0 -105
- package/dist/{decision-BezSD_YC.mjs → decision-D9Zi7Xi5.mjs} +2 -65
- package/dist/index.cjs +52 -155
- package/dist/index.d.cts +26 -13
- package/dist/index.d.mts +26 -13
- package/dist/index.mjs +54 -156
- package/dist/machines.cjs +1 -1
- package/dist/machines.d.cts +1 -1
- package/dist/machines.d.mts +1 -1
- package/dist/machines.mjs +1 -1
- package/dist/otel.cjs +5 -15
- package/dist/otel.d.cts +1 -1
- package/dist/otel.d.mts +1 -1
- package/dist/otel.mjs +5 -15
- package/dist/{run-agent-C3mFDGTf.d.mts → run-agent-BWzo4FLv.d.mts} +83 -109
- package/dist/{run-agent-DnvtcnTZ.d.cts → run-agent-B_n4Qxye.d.cts} +83 -109
- package/dist/{setup-agent-DP95MFrI.cjs → setup-agent-CpK0ZRWV.cjs} +10 -210
- package/dist/{setup-agent-DAZZSjDS.mjs → setup-agent-DeHRW-qX.mjs} +11 -205
- package/dist/sqlite.d.cts +2 -2
- package/dist/sqlite.d.mts +2 -2
- package/dist/{text-logic-TkKPw8Aq.d.mts → text-logic-C7anC7qX.d.mts} +8 -94
- package/dist/{text-logic-BDxwQNsD.d.cts → text-logic-DZW7XWy9.d.cts} +8 -94
- package/dist/{types-QbEfCVny.d.cts → types-CTBhMnFu.d.mts} +30 -3
- package/dist/{types-_FXoFBGO.d.mts → types-DFD28AWe.d.cts} +30 -3
- package/package.json +1 -1
- /package/dist/{event-log-store-CriMgX1D.d.mts → event-log-store-BkUNtyOF.d.mts} +0 -0
- /package/dist/{event-log-store-Ruq18mGp.d.cts → event-log-store-CVd2eyRy.d.cts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_errors = require("./errors-DUBBzRLP.cjs");
|
|
2
|
-
const require_decision = require("./decision-
|
|
2
|
+
const require_decision = require("./decision-C0cUKvNt.cjs");
|
|
3
3
|
const require_event_log_store = require("./event-log-store-CNT_7F0V.cjs");
|
|
4
4
|
let xstate = require("xstate");
|
|
5
5
|
//#region src/messages.ts
|
|
@@ -117,7 +117,7 @@ function getInvokeEffectMetadata(action) {
|
|
|
117
117
|
* @internal
|
|
118
118
|
*/
|
|
119
119
|
function getAgentRequestsWith(actions, options = {}) {
|
|
120
|
-
return
|
|
120
|
+
return actions.flatMap((action) => {
|
|
121
121
|
const params = getInvokeEffectMetadata(action);
|
|
122
122
|
if (!params || typeof params.src !== "string") return [];
|
|
123
123
|
if (typeof params.id !== "string" || params.id.length === 0) throw new Error(`Agent invoke '${params.src}' must define a durable string id.`);
|
|
@@ -149,60 +149,7 @@ function getAgentRequestsWith(actions, options = {}) {
|
|
|
149
149
|
tools: input.tools ?? {},
|
|
150
150
|
events: []
|
|
151
151
|
}];
|
|
152
|
-
})
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Scans the live snapshot's children for active `agent.plan` (plan-logic)
|
|
156
|
-
* invokes and lowers each into an {@link AgentPlanRequest} — the re-surfacing
|
|
157
|
-
* half of plan discovery. Reads the applied-event trail and remaining budget
|
|
158
|
-
* from the child's own ledger `context` ({@link PlanLedgerContext}), recomputes
|
|
159
|
-
* the currently-legal candidates (∩ declared `allowedEvents`) plus the reserved
|
|
160
|
-
* `agent.plan.done` move, and takes `stepsRemaining` from the ledger (falling
|
|
161
|
-
* back to `maxSteps - applied.length` for a snapshot with no context yet).
|
|
162
|
-
* Returns `[]` when no snapshot is available (candidates need a live snapshot).
|
|
163
|
-
*
|
|
164
|
-
* @internal
|
|
165
|
-
*/
|
|
166
|
-
function getActivePlanRequests(options) {
|
|
167
|
-
const snapshot = options.snapshot;
|
|
168
|
-
if (!snapshot) return [];
|
|
169
|
-
const children = snapshot.children;
|
|
170
|
-
if (!children) return [];
|
|
171
|
-
const requests = [];
|
|
172
|
-
for (const [id, child] of Object.entries(children)) {
|
|
173
|
-
const ref = child;
|
|
174
|
-
if (typeof ref?.getSnapshot !== "function") continue;
|
|
175
|
-
const src = typeof ref.src === "string" ? ref.src : void 0;
|
|
176
|
-
const logic = (src ? options.actors?.[src] : void 0) ?? ref.logic;
|
|
177
|
-
if (!require_decision.isPlanLogic(logic)) continue;
|
|
178
|
-
const childSnapshot = ref.getSnapshot();
|
|
179
|
-
if (childSnapshot?.status !== "active") continue;
|
|
180
|
-
const input = childSnapshot.input ?? {};
|
|
181
|
-
const maxSteps = input.maxSteps ?? 8;
|
|
182
|
-
const ledger = childSnapshot.context ?? {};
|
|
183
|
-
const applied = ledger.applied ?? [];
|
|
184
|
-
const stepsRemaining = ledger.stepsRemaining ?? maxSteps - applied.length;
|
|
185
|
-
const machineEvents = require_decision.getAcceptedEvents(snapshot, {
|
|
186
|
-
events: options.events,
|
|
187
|
-
schemas: options.schemas,
|
|
188
|
-
eventTypes: logic.allowedEventTypes(input) ?? void 0,
|
|
189
|
-
eventToolName: options.eventToolName
|
|
190
|
-
});
|
|
191
|
-
const events = machineEvents.some((event) => event.type === "agent.plan.done") ? machineEvents : [...machineEvents, {
|
|
192
|
-
type: require_decision.PLAN_DONE_EVENT_TYPE,
|
|
193
|
-
toolName: require_decision.sanitizeEventToolName(require_decision.PLAN_DONE_EVENT_TYPE)
|
|
194
|
-
}];
|
|
195
|
-
requests.push({
|
|
196
|
-
kind: "plan",
|
|
197
|
-
id,
|
|
198
|
-
src: src ?? "",
|
|
199
|
-
input,
|
|
200
|
-
events,
|
|
201
|
-
applied,
|
|
202
|
-
stepsRemaining: Math.max(0, stepsRemaining)
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
return requests;
|
|
152
|
+
});
|
|
206
153
|
}
|
|
207
154
|
/**
|
|
208
155
|
* Builds the canonical `xstate.done.actor` event xstate's `transition()`
|
|
@@ -289,133 +236,11 @@ async function executeAgentRequest(requestOrEffect, executors, options) {
|
|
|
289
236
|
raw
|
|
290
237
|
} : normalizedOutput;
|
|
291
238
|
}
|
|
292
|
-
/**
|
|
293
|
-
* Resolves the current step's pending requests and returns the next
|
|
294
|
-
* {@link AgentStep} — one iteration of the durable step loop, collapsing the
|
|
295
|
-
* manual `request.kind` dispatch a host would otherwise write by hand.
|
|
296
|
-
*
|
|
297
|
-
* For each pending request, in order: a `kind: 'text'` request is run with
|
|
298
|
-
* {@link executeAgentRequest} then fed back via {@link resolveAgentStep}; a
|
|
299
|
-
* `kind: 'decision'` request is resolved with `resolveDecision` (wiring
|
|
300
|
-
* `canTake` to `step.snapshot.can` so guard-rejected choices retry) then
|
|
301
|
-
* applied with {@link transitionAgentStep}. The **current** step is re-read
|
|
302
|
-
* after each application — the machine may advance and its `requests` change —
|
|
303
|
-
* so this always resolves against the live step, never a stale list.
|
|
304
|
-
*
|
|
305
|
-
* A `kind: 'plan'` request (`agent.plan`) is resolved natively too: one plan
|
|
306
|
-
* step per call. It resolves a single decision from `request.events` (wiring
|
|
307
|
-
* `canTake` to `step.snapshot.can`, exempting the reserved `agent.plan.done`
|
|
308
|
-
* move and `stopOn` events), then either applies the chosen machine event and
|
|
309
|
-
* lets the next step re-surface the plan, or completes the plan (feeding its
|
|
310
|
-
* `{ steps, stopped }` output back) on the done move / a `stopOn` event / an
|
|
311
|
-
* exhausted budget / no legal events. The plan's applied trail is carried in
|
|
312
|
-
* the invoke child's snapshot, so persisting the step between calls resumes the
|
|
313
|
-
* plan identically.
|
|
314
|
-
*
|
|
315
|
-
* Missing the executor a request needs throws a clear error
|
|
316
|
-
* (`generateText`/`streamText` for text, `decide` for decisions and plans).
|
|
317
|
-
*
|
|
318
|
-
* A complete durable host is two lines:
|
|
319
|
-
*
|
|
320
|
-
* ```ts
|
|
321
|
-
* let step = initialAgentStep(machine, input);
|
|
322
|
-
* while (!step.done) step = await resolveAgentRequests(machine, step, executors);
|
|
323
|
-
* ```
|
|
324
|
-
*
|
|
325
|
-
* All pending **text** requests of a step are resolved in parallel
|
|
326
|
-
* (`Promise.all`) — parallel statechart regions are genuinely concurrent, so
|
|
327
|
-
* their model calls run concurrently — then their outputs apply in
|
|
328
|
-
* **request-array order** (deterministic for durable replay regardless of which
|
|
329
|
-
* call finishes first). Decisions and plans stay **one at a time**: applying
|
|
330
|
-
* either changes the set of legal candidates for what follows, so they cannot be
|
|
331
|
-
* resolved against a stale snapshot. A host that instead wants strictly
|
|
332
|
-
* sequential text resolution loops the manual per-request helpers
|
|
333
|
-
* ({@link executeAgentRequest} + {@link resolveAgentStep}) one at a time.
|
|
334
|
-
*/
|
|
335
|
-
async function resolveAgentRequests(machine, step, executors, options) {
|
|
336
|
-
const [request] = step.requests;
|
|
337
|
-
if (!request) return step;
|
|
338
|
-
if (request.kind === "decision") {
|
|
339
|
-
if (!executors.decide) throw new Error(`this step's decision request '${request.id}' needs a 'decide' executor but none was provided.`);
|
|
340
|
-
return transitionAgentStep(machine, step, await require_decision.resolveDecision(request, executors.decide, {
|
|
341
|
-
canTake: (event) => step.snapshot.can(event),
|
|
342
|
-
maxRetries: options?.maxRetries
|
|
343
|
-
}), options);
|
|
344
|
-
}
|
|
345
|
-
if (request.kind === "plan") return resolvePlanRequest(machine, step, request, executors, options);
|
|
346
|
-
const textRequests = step.requests.filter((candidate) => candidate.kind === "text");
|
|
347
|
-
for (const textRequest of textRequests) assertTextExecutor(textRequest, executors);
|
|
348
|
-
const outputs = await Promise.all(textRequests.map((textRequest) => executeAgentRequest(textRequest, executors)));
|
|
349
|
-
let next = step;
|
|
350
|
-
for (let index = 0; index < textRequests.length; index++) next = resolveAgentStep(machine, next, textRequests[index], outputs[index], options);
|
|
351
|
-
return next;
|
|
352
|
-
}
|
|
353
239
|
function assertTextExecutor(request, executors) {
|
|
354
240
|
const mode = request.mode ?? "generate";
|
|
355
241
|
const kind = mode === "stream" ? "streamText" : "generateText";
|
|
356
242
|
if (!(mode === "stream" ? executors.streamText : executors.generateText)) throw new Error(`this step's text request '${request.src}' needs a '${kind}' executor but none was provided.`);
|
|
357
243
|
}
|
|
358
|
-
async function resolvePlanRequest(machine, step, request, executors, options) {
|
|
359
|
-
if (!executors.decide) throw new Error(`this step's plan request '${request.src}' needs a 'decide' executor but none was provided.`);
|
|
360
|
-
const stopOn = new Set(request.input.stopOn ?? []);
|
|
361
|
-
if (request.stepsRemaining <= 0) return completePlan(machine, step, request.id, request.applied, "max-steps", options);
|
|
362
|
-
if (request.events.filter((event) => event.type !== "agent.plan.done").length === 0) return completePlan(machine, step, request.id, request.applied, "no-legal-events", options);
|
|
363
|
-
const chosen = await require_decision.resolveDecision(planStepDecisionRequest(request), executors.decide, {
|
|
364
|
-
maxRetries: options?.maxRetries,
|
|
365
|
-
canTake: (event) => {
|
|
366
|
-
if (event.type === "agent.plan.done" || stopOn.has(event.type)) return true;
|
|
367
|
-
return step.snapshot.can(event);
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
if (chosen.type === "agent.plan.done") return completePlan(machine, step, request.id, request.applied, "done", options);
|
|
371
|
-
const applied = [...request.applied, chosen];
|
|
372
|
-
advancePlanChildLedger(step.snapshot, request.id, {
|
|
373
|
-
type: "plan.applied",
|
|
374
|
-
event: chosen
|
|
375
|
-
});
|
|
376
|
-
const next = transitionAgentStep(machine, step, chosen, options);
|
|
377
|
-
if (stopOn.has(chosen.type)) {
|
|
378
|
-
if (isPlanActive(next.snapshot, request.id)) return completePlan(machine, next, request.id, applied, "stop-event", options);
|
|
379
|
-
}
|
|
380
|
-
return next;
|
|
381
|
-
}
|
|
382
|
-
function completePlan(machine, step, id, steps, stopped, options) {
|
|
383
|
-
return resolveAgentStep(machine, step, { id }, {
|
|
384
|
-
steps,
|
|
385
|
-
stopped
|
|
386
|
-
}, options);
|
|
387
|
-
}
|
|
388
|
-
function planStepDecisionRequest(request) {
|
|
389
|
-
const { input, applied, events, id } = request;
|
|
390
|
-
const trail = applied.length === 0 ? "" : `\n\nEvents already applied in this plan, in order:\n${applied.map((step) => JSON.stringify(step)).join("\n")}\nContinue from here; do not repeat applied events.`;
|
|
391
|
-
const doneHint = `\n\nWhen the request is fully handled (or no action is needed), choose '${require_decision.PLAN_DONE_EVENT_TYPE}'.`;
|
|
392
|
-
return {
|
|
393
|
-
kind: "decision",
|
|
394
|
-
id: `${id}[${applied.length}]`,
|
|
395
|
-
model: input.model,
|
|
396
|
-
system: input.system,
|
|
397
|
-
prompt: `${input.prompt ?? ""}${trail}${doneHint}`,
|
|
398
|
-
messages: input.messages,
|
|
399
|
-
events,
|
|
400
|
-
attempts: [],
|
|
401
|
-
temperature: input.temperature,
|
|
402
|
-
maxOutputTokens: input.maxOutputTokens,
|
|
403
|
-
topP: input.topP,
|
|
404
|
-
topK: input.topK,
|
|
405
|
-
seed: input.seed,
|
|
406
|
-
stopSequences: input.stopSequences,
|
|
407
|
-
metadata: input.metadata
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
function advancePlanChildLedger(snapshot, id, event) {
|
|
411
|
-
const child = snapshot.children?.[id];
|
|
412
|
-
const childSnapshot = child?.getSnapshot?.();
|
|
413
|
-
if (!require_decision.isPlanLogic(child?.logic) || !childSnapshot || typeof childSnapshot !== "object") return;
|
|
414
|
-
Object.assign(childSnapshot, require_decision.advancePlanLedger(child.logic, childSnapshot, event));
|
|
415
|
-
}
|
|
416
|
-
function isPlanActive(snapshot, id) {
|
|
417
|
-
return (snapshot.children?.[id])?.getSnapshot?.()?.status === "active";
|
|
418
|
-
}
|
|
419
244
|
function createAgentStep(machine, snapshot, actions, options) {
|
|
420
245
|
applyFinalStateOutput(machine, snapshot);
|
|
421
246
|
return {
|
|
@@ -644,12 +469,7 @@ function buildInvokeEffect(meta, mapped, events, snapshot, options) {
|
|
|
644
469
|
requestId,
|
|
645
470
|
request: mapped
|
|
646
471
|
};
|
|
647
|
-
|
|
648
|
-
kind: "plan",
|
|
649
|
-
requestId,
|
|
650
|
-
request: mapped
|
|
651
|
-
};
|
|
652
|
-
const logic = require_decision.isTextLogic(meta.logic) || require_decision.isDecisionLogic(meta.logic) || require_decision.isPlanLogic(meta.logic) ? meta.logic : typeof meta.src === "string" ? options.actors?.[meta.src] : void 0;
|
|
472
|
+
const logic = require_decision.isTextLogic(meta.logic) || require_decision.isDecisionLogic(meta.logic) ? meta.logic : typeof meta.src === "string" ? options.actors?.[meta.src] : void 0;
|
|
653
473
|
if (require_decision.isTextLogic(logic)) return {
|
|
654
474
|
kind: "text",
|
|
655
475
|
requestId,
|
|
@@ -692,8 +512,8 @@ function buildInvokeEffect(meta, mapped, events, snapshot, options) {
|
|
|
692
512
|
* Ordering is load-bearing: a single transition's actions are emitted in
|
|
693
513
|
* document order (a custom entry action, a spawn, and a `sendTo` in that order
|
|
694
514
|
* yield `execute`, then `task`/agent effect, then `execute` — never a
|
|
695
|
-
* reordered set). Effects visible only on the snapshot (
|
|
696
|
-
*
|
|
515
|
+
* reordered set). Effects visible only on the snapshot (children spawned by
|
|
516
|
+
* an EARLIER transition that
|
|
697
517
|
* have not completed yet — the fan-out / crash-resume case) are appended after
|
|
698
518
|
* the action-derived effects, deduped by site id.
|
|
699
519
|
*
|
|
@@ -754,14 +574,6 @@ function getAgentEffects(machine, snapshot, actions, options = {}) {
|
|
|
754
574
|
});
|
|
755
575
|
}
|
|
756
576
|
}
|
|
757
|
-
for (const request of requests) if (request.kind === "plan" && !emitted.has(request.id)) {
|
|
758
|
-
effects.push({
|
|
759
|
-
kind: "plan",
|
|
760
|
-
requestId: `${request.id}#${invokeOccurrence(events, request.id)}`,
|
|
761
|
-
request
|
|
762
|
-
});
|
|
763
|
-
emitted.add(request.id);
|
|
764
|
-
}
|
|
765
577
|
const children = snapshot.children;
|
|
766
578
|
for (const [id, child] of Object.entries(children ?? {})) {
|
|
767
579
|
if (emitted.has(id) || invokeOccurrence(events, id) > 1) continue;
|
|
@@ -1388,11 +1200,7 @@ const USAGE_ATTRIBUTION_FIELDS = [
|
|
|
1388
1200
|
"model",
|
|
1389
1201
|
"name"
|
|
1390
1202
|
];
|
|
1391
|
-
const USAGE_KINDS = [
|
|
1392
|
-
"text",
|
|
1393
|
-
"decision",
|
|
1394
|
-
"plan"
|
|
1395
|
-
];
|
|
1203
|
+
const USAGE_KINDS = ["text", "decision"];
|
|
1396
1204
|
/**
|
|
1397
1205
|
* Standard Schema for the reserved `'@agent.usage'` payload. Hand-rolled (no
|
|
1398
1206
|
* validation-library dependency in core) and deliberately permissive about
|
|
@@ -1510,7 +1318,7 @@ function resolveAgentStateSchemas(contextSchema, states) {
|
|
|
1510
1318
|
* state/transition meta are all standard schemas — no `{} as Type` casts —
|
|
1511
1319
|
* and are retained on `result.schemas` for runtime validation. Also
|
|
1512
1320
|
* registers the `agent.generateText`/`agent.streamText`/`agent.userInput`/
|
|
1513
|
-
* `agent.decide
|
|
1321
|
+
* `agent.decide` builtin actors and lowers `requests`/`actors` into the
|
|
1514
1322
|
* machine's actor sources. The result is the xstate `setup(...)` object with
|
|
1515
1323
|
* a wrapped `result.createMachine(...)` plus `result.schemas`/`models`/
|
|
1516
1324
|
* `requests`/`appendMessages` attached. Also has a
|
|
@@ -1632,14 +1440,13 @@ function assertStateSchemaKeysExist(stateSchemas, machineStates, path = []) {
|
|
|
1632
1440
|
const RESERVED_AGENT_ACTOR_KEYS = [
|
|
1633
1441
|
...Object.keys(require_decision.builtinTextActors),
|
|
1634
1442
|
require_decision.USER_INPUT_ACTOR,
|
|
1635
|
-
require_decision.DECIDE_ACTOR
|
|
1636
|
-
require_decision.PLAN_ACTOR
|
|
1443
|
+
require_decision.DECIDE_ACTOR
|
|
1637
1444
|
];
|
|
1638
1445
|
/**
|
|
1639
1446
|
* Rejects a user-supplied `actors`/`requests` key in the reserved
|
|
1640
1447
|
* `agent.*` builtin namespace. Without this, the builtins-first spread in
|
|
1641
1448
|
* {@link createAgentActors} lets such a key overwrite the builtin
|
|
1642
|
-
* (`agent.decide`,
|
|
1449
|
+
* (`agent.decide`, …) silently. Deliberate override of a builtin
|
|
1643
1450
|
* is still possible after the machine is created, via
|
|
1644
1451
|
* `machine.provide({ actors: { 'agent.decide': ... } })`.
|
|
1645
1452
|
*/
|
|
@@ -1654,7 +1461,6 @@ function createAgentActors(actors, requestActors) {
|
|
|
1654
1461
|
...require_decision.builtinTextActors,
|
|
1655
1462
|
[require_decision.USER_INPUT_ACTOR]: require_decision.userInputActor,
|
|
1656
1463
|
[require_decision.DECIDE_ACTOR]: require_decision.createDecideActor(),
|
|
1657
|
-
[require_decision.PLAN_ACTOR]: require_decision.createPlanActor(),
|
|
1658
1464
|
...actors,
|
|
1659
1465
|
...requestActors
|
|
1660
1466
|
};
|
|
@@ -1804,12 +1610,6 @@ Object.defineProperty(exports, "replay", {
|
|
|
1804
1610
|
return replay;
|
|
1805
1611
|
}
|
|
1806
1612
|
});
|
|
1807
|
-
Object.defineProperty(exports, "resolveAgentRequests", {
|
|
1808
|
-
enumerable: true,
|
|
1809
|
-
get: function() {
|
|
1810
|
-
return resolveAgentRequests;
|
|
1811
|
-
}
|
|
1812
|
-
});
|
|
1813
1613
|
Object.defineProperty(exports, "resolveAgentStep", {
|
|
1814
1614
|
enumerable: true,
|
|
1815
1615
|
get: function() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as AgentError } from "./errors-CeSXQx0v.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { K as validateSchemaSync, M as machineSuspensionPredicates, N as missingActor, T as agentExecutionOptions, _ as extractCallUsage, d as USER_INPUT_ACTOR, g as executeAgentTextRequest, h as createTextLogic, j as machineStaticTransitionTargets, k as getRegisteredAgentExecutionOptions, l as DECIDE_ACTOR, m as builtinTextActors, n as createDecideActor, o as getAcceptedEvents, r as isDecisionLogic, w as userInputActor, y as isTextLogic, z as getMachineStructuralHash } from "./decision-D9Zi7Xi5.mjs";
|
|
3
3
|
import { i as assertAgentLogEntry, o as assertJsonSerializable } from "./event-log-store-D7pWtIhb.mjs";
|
|
4
4
|
import { createMachineFromConfig, initialTransition, setup, transition } from "xstate";
|
|
5
5
|
//#region src/messages.ts
|
|
@@ -117,7 +117,7 @@ function getInvokeEffectMetadata(action) {
|
|
|
117
117
|
* @internal
|
|
118
118
|
*/
|
|
119
119
|
function getAgentRequestsWith(actions, options = {}) {
|
|
120
|
-
return
|
|
120
|
+
return actions.flatMap((action) => {
|
|
121
121
|
const params = getInvokeEffectMetadata(action);
|
|
122
122
|
if (!params || typeof params.src !== "string") return [];
|
|
123
123
|
if (typeof params.id !== "string" || params.id.length === 0) throw new Error(`Agent invoke '${params.src}' must define a durable string id.`);
|
|
@@ -149,60 +149,7 @@ function getAgentRequestsWith(actions, options = {}) {
|
|
|
149
149
|
tools: input.tools ?? {},
|
|
150
150
|
events: []
|
|
151
151
|
}];
|
|
152
|
-
})
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Scans the live snapshot's children for active `agent.plan` (plan-logic)
|
|
156
|
-
* invokes and lowers each into an {@link AgentPlanRequest} — the re-surfacing
|
|
157
|
-
* half of plan discovery. Reads the applied-event trail and remaining budget
|
|
158
|
-
* from the child's own ledger `context` ({@link PlanLedgerContext}), recomputes
|
|
159
|
-
* the currently-legal candidates (∩ declared `allowedEvents`) plus the reserved
|
|
160
|
-
* `agent.plan.done` move, and takes `stepsRemaining` from the ledger (falling
|
|
161
|
-
* back to `maxSteps - applied.length` for a snapshot with no context yet).
|
|
162
|
-
* Returns `[]` when no snapshot is available (candidates need a live snapshot).
|
|
163
|
-
*
|
|
164
|
-
* @internal
|
|
165
|
-
*/
|
|
166
|
-
function getActivePlanRequests(options) {
|
|
167
|
-
const snapshot = options.snapshot;
|
|
168
|
-
if (!snapshot) return [];
|
|
169
|
-
const children = snapshot.children;
|
|
170
|
-
if (!children) return [];
|
|
171
|
-
const requests = [];
|
|
172
|
-
for (const [id, child] of Object.entries(children)) {
|
|
173
|
-
const ref = child;
|
|
174
|
-
if (typeof ref?.getSnapshot !== "function") continue;
|
|
175
|
-
const src = typeof ref.src === "string" ? ref.src : void 0;
|
|
176
|
-
const logic = (src ? options.actors?.[src] : void 0) ?? ref.logic;
|
|
177
|
-
if (!isPlanLogic(logic)) continue;
|
|
178
|
-
const childSnapshot = ref.getSnapshot();
|
|
179
|
-
if (childSnapshot?.status !== "active") continue;
|
|
180
|
-
const input = childSnapshot.input ?? {};
|
|
181
|
-
const maxSteps = input.maxSteps ?? 8;
|
|
182
|
-
const ledger = childSnapshot.context ?? {};
|
|
183
|
-
const applied = ledger.applied ?? [];
|
|
184
|
-
const stepsRemaining = ledger.stepsRemaining ?? maxSteps - applied.length;
|
|
185
|
-
const machineEvents = getAcceptedEvents(snapshot, {
|
|
186
|
-
events: options.events,
|
|
187
|
-
schemas: options.schemas,
|
|
188
|
-
eventTypes: logic.allowedEventTypes(input) ?? void 0,
|
|
189
|
-
eventToolName: options.eventToolName
|
|
190
|
-
});
|
|
191
|
-
const events = machineEvents.some((event) => event.type === "agent.plan.done") ? machineEvents : [...machineEvents, {
|
|
192
|
-
type: PLAN_DONE_EVENT_TYPE,
|
|
193
|
-
toolName: sanitizeEventToolName(PLAN_DONE_EVENT_TYPE)
|
|
194
|
-
}];
|
|
195
|
-
requests.push({
|
|
196
|
-
kind: "plan",
|
|
197
|
-
id,
|
|
198
|
-
src: src ?? "",
|
|
199
|
-
input,
|
|
200
|
-
events,
|
|
201
|
-
applied,
|
|
202
|
-
stepsRemaining: Math.max(0, stepsRemaining)
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
return requests;
|
|
152
|
+
});
|
|
206
153
|
}
|
|
207
154
|
/**
|
|
208
155
|
* Builds the canonical `xstate.done.actor` event xstate's `transition()`
|
|
@@ -289,133 +236,11 @@ async function executeAgentRequest(requestOrEffect, executors, options) {
|
|
|
289
236
|
raw
|
|
290
237
|
} : normalizedOutput;
|
|
291
238
|
}
|
|
292
|
-
/**
|
|
293
|
-
* Resolves the current step's pending requests and returns the next
|
|
294
|
-
* {@link AgentStep} — one iteration of the durable step loop, collapsing the
|
|
295
|
-
* manual `request.kind` dispatch a host would otherwise write by hand.
|
|
296
|
-
*
|
|
297
|
-
* For each pending request, in order: a `kind: 'text'` request is run with
|
|
298
|
-
* {@link executeAgentRequest} then fed back via {@link resolveAgentStep}; a
|
|
299
|
-
* `kind: 'decision'` request is resolved with `resolveDecision` (wiring
|
|
300
|
-
* `canTake` to `step.snapshot.can` so guard-rejected choices retry) then
|
|
301
|
-
* applied with {@link transitionAgentStep}. The **current** step is re-read
|
|
302
|
-
* after each application — the machine may advance and its `requests` change —
|
|
303
|
-
* so this always resolves against the live step, never a stale list.
|
|
304
|
-
*
|
|
305
|
-
* A `kind: 'plan'` request (`agent.plan`) is resolved natively too: one plan
|
|
306
|
-
* step per call. It resolves a single decision from `request.events` (wiring
|
|
307
|
-
* `canTake` to `step.snapshot.can`, exempting the reserved `agent.plan.done`
|
|
308
|
-
* move and `stopOn` events), then either applies the chosen machine event and
|
|
309
|
-
* lets the next step re-surface the plan, or completes the plan (feeding its
|
|
310
|
-
* `{ steps, stopped }` output back) on the done move / a `stopOn` event / an
|
|
311
|
-
* exhausted budget / no legal events. The plan's applied trail is carried in
|
|
312
|
-
* the invoke child's snapshot, so persisting the step between calls resumes the
|
|
313
|
-
* plan identically.
|
|
314
|
-
*
|
|
315
|
-
* Missing the executor a request needs throws a clear error
|
|
316
|
-
* (`generateText`/`streamText` for text, `decide` for decisions and plans).
|
|
317
|
-
*
|
|
318
|
-
* A complete durable host is two lines:
|
|
319
|
-
*
|
|
320
|
-
* ```ts
|
|
321
|
-
* let step = initialAgentStep(machine, input);
|
|
322
|
-
* while (!step.done) step = await resolveAgentRequests(machine, step, executors);
|
|
323
|
-
* ```
|
|
324
|
-
*
|
|
325
|
-
* All pending **text** requests of a step are resolved in parallel
|
|
326
|
-
* (`Promise.all`) — parallel statechart regions are genuinely concurrent, so
|
|
327
|
-
* their model calls run concurrently — then their outputs apply in
|
|
328
|
-
* **request-array order** (deterministic for durable replay regardless of which
|
|
329
|
-
* call finishes first). Decisions and plans stay **one at a time**: applying
|
|
330
|
-
* either changes the set of legal candidates for what follows, so they cannot be
|
|
331
|
-
* resolved against a stale snapshot. A host that instead wants strictly
|
|
332
|
-
* sequential text resolution loops the manual per-request helpers
|
|
333
|
-
* ({@link executeAgentRequest} + {@link resolveAgentStep}) one at a time.
|
|
334
|
-
*/
|
|
335
|
-
async function resolveAgentRequests(machine, step, executors, options) {
|
|
336
|
-
const [request] = step.requests;
|
|
337
|
-
if (!request) return step;
|
|
338
|
-
if (request.kind === "decision") {
|
|
339
|
-
if (!executors.decide) throw new Error(`this step's decision request '${request.id}' needs a 'decide' executor but none was provided.`);
|
|
340
|
-
return transitionAgentStep(machine, step, await resolveDecision(request, executors.decide, {
|
|
341
|
-
canTake: (event) => step.snapshot.can(event),
|
|
342
|
-
maxRetries: options?.maxRetries
|
|
343
|
-
}), options);
|
|
344
|
-
}
|
|
345
|
-
if (request.kind === "plan") return resolvePlanRequest(machine, step, request, executors, options);
|
|
346
|
-
const textRequests = step.requests.filter((candidate) => candidate.kind === "text");
|
|
347
|
-
for (const textRequest of textRequests) assertTextExecutor(textRequest, executors);
|
|
348
|
-
const outputs = await Promise.all(textRequests.map((textRequest) => executeAgentRequest(textRequest, executors)));
|
|
349
|
-
let next = step;
|
|
350
|
-
for (let index = 0; index < textRequests.length; index++) next = resolveAgentStep(machine, next, textRequests[index], outputs[index], options);
|
|
351
|
-
return next;
|
|
352
|
-
}
|
|
353
239
|
function assertTextExecutor(request, executors) {
|
|
354
240
|
const mode = request.mode ?? "generate";
|
|
355
241
|
const kind = mode === "stream" ? "streamText" : "generateText";
|
|
356
242
|
if (!(mode === "stream" ? executors.streamText : executors.generateText)) throw new Error(`this step's text request '${request.src}' needs a '${kind}' executor but none was provided.`);
|
|
357
243
|
}
|
|
358
|
-
async function resolvePlanRequest(machine, step, request, executors, options) {
|
|
359
|
-
if (!executors.decide) throw new Error(`this step's plan request '${request.src}' needs a 'decide' executor but none was provided.`);
|
|
360
|
-
const stopOn = new Set(request.input.stopOn ?? []);
|
|
361
|
-
if (request.stepsRemaining <= 0) return completePlan(machine, step, request.id, request.applied, "max-steps", options);
|
|
362
|
-
if (request.events.filter((event) => event.type !== "agent.plan.done").length === 0) return completePlan(machine, step, request.id, request.applied, "no-legal-events", options);
|
|
363
|
-
const chosen = await resolveDecision(planStepDecisionRequest(request), executors.decide, {
|
|
364
|
-
maxRetries: options?.maxRetries,
|
|
365
|
-
canTake: (event) => {
|
|
366
|
-
if (event.type === "agent.plan.done" || stopOn.has(event.type)) return true;
|
|
367
|
-
return step.snapshot.can(event);
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
if (chosen.type === "agent.plan.done") return completePlan(machine, step, request.id, request.applied, "done", options);
|
|
371
|
-
const applied = [...request.applied, chosen];
|
|
372
|
-
advancePlanChildLedger(step.snapshot, request.id, {
|
|
373
|
-
type: "plan.applied",
|
|
374
|
-
event: chosen
|
|
375
|
-
});
|
|
376
|
-
const next = transitionAgentStep(machine, step, chosen, options);
|
|
377
|
-
if (stopOn.has(chosen.type)) {
|
|
378
|
-
if (isPlanActive(next.snapshot, request.id)) return completePlan(machine, next, request.id, applied, "stop-event", options);
|
|
379
|
-
}
|
|
380
|
-
return next;
|
|
381
|
-
}
|
|
382
|
-
function completePlan(machine, step, id, steps, stopped, options) {
|
|
383
|
-
return resolveAgentStep(machine, step, { id }, {
|
|
384
|
-
steps,
|
|
385
|
-
stopped
|
|
386
|
-
}, options);
|
|
387
|
-
}
|
|
388
|
-
function planStepDecisionRequest(request) {
|
|
389
|
-
const { input, applied, events, id } = request;
|
|
390
|
-
const trail = applied.length === 0 ? "" : `\n\nEvents already applied in this plan, in order:\n${applied.map((step) => JSON.stringify(step)).join("\n")}\nContinue from here; do not repeat applied events.`;
|
|
391
|
-
const doneHint = `\n\nWhen the request is fully handled (or no action is needed), choose '${PLAN_DONE_EVENT_TYPE}'.`;
|
|
392
|
-
return {
|
|
393
|
-
kind: "decision",
|
|
394
|
-
id: `${id}[${applied.length}]`,
|
|
395
|
-
model: input.model,
|
|
396
|
-
system: input.system,
|
|
397
|
-
prompt: `${input.prompt ?? ""}${trail}${doneHint}`,
|
|
398
|
-
messages: input.messages,
|
|
399
|
-
events,
|
|
400
|
-
attempts: [],
|
|
401
|
-
temperature: input.temperature,
|
|
402
|
-
maxOutputTokens: input.maxOutputTokens,
|
|
403
|
-
topP: input.topP,
|
|
404
|
-
topK: input.topK,
|
|
405
|
-
seed: input.seed,
|
|
406
|
-
stopSequences: input.stopSequences,
|
|
407
|
-
metadata: input.metadata
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
function advancePlanChildLedger(snapshot, id, event) {
|
|
411
|
-
const child = snapshot.children?.[id];
|
|
412
|
-
const childSnapshot = child?.getSnapshot?.();
|
|
413
|
-
if (!isPlanLogic(child?.logic) || !childSnapshot || typeof childSnapshot !== "object") return;
|
|
414
|
-
Object.assign(childSnapshot, advancePlanLedger(child.logic, childSnapshot, event));
|
|
415
|
-
}
|
|
416
|
-
function isPlanActive(snapshot, id) {
|
|
417
|
-
return (snapshot.children?.[id])?.getSnapshot?.()?.status === "active";
|
|
418
|
-
}
|
|
419
244
|
function createAgentStep(machine, snapshot, actions, options) {
|
|
420
245
|
applyFinalStateOutput(machine, snapshot);
|
|
421
246
|
return {
|
|
@@ -644,12 +469,7 @@ function buildInvokeEffect(meta, mapped, events, snapshot, options) {
|
|
|
644
469
|
requestId,
|
|
645
470
|
request: mapped
|
|
646
471
|
};
|
|
647
|
-
|
|
648
|
-
kind: "plan",
|
|
649
|
-
requestId,
|
|
650
|
-
request: mapped
|
|
651
|
-
};
|
|
652
|
-
const logic = isTextLogic(meta.logic) || isDecisionLogic(meta.logic) || isPlanLogic(meta.logic) ? meta.logic : typeof meta.src === "string" ? options.actors?.[meta.src] : void 0;
|
|
472
|
+
const logic = isTextLogic(meta.logic) || isDecisionLogic(meta.logic) ? meta.logic : typeof meta.src === "string" ? options.actors?.[meta.src] : void 0;
|
|
653
473
|
if (isTextLogic(logic)) return {
|
|
654
474
|
kind: "text",
|
|
655
475
|
requestId,
|
|
@@ -692,8 +512,8 @@ function buildInvokeEffect(meta, mapped, events, snapshot, options) {
|
|
|
692
512
|
* Ordering is load-bearing: a single transition's actions are emitted in
|
|
693
513
|
* document order (a custom entry action, a spawn, and a `sendTo` in that order
|
|
694
514
|
* yield `execute`, then `task`/agent effect, then `execute` — never a
|
|
695
|
-
* reordered set). Effects visible only on the snapshot (
|
|
696
|
-
*
|
|
515
|
+
* reordered set). Effects visible only on the snapshot (children spawned by
|
|
516
|
+
* an EARLIER transition that
|
|
697
517
|
* have not completed yet — the fan-out / crash-resume case) are appended after
|
|
698
518
|
* the action-derived effects, deduped by site id.
|
|
699
519
|
*
|
|
@@ -754,14 +574,6 @@ function getAgentEffects(machine, snapshot, actions, options = {}) {
|
|
|
754
574
|
});
|
|
755
575
|
}
|
|
756
576
|
}
|
|
757
|
-
for (const request of requests) if (request.kind === "plan" && !emitted.has(request.id)) {
|
|
758
|
-
effects.push({
|
|
759
|
-
kind: "plan",
|
|
760
|
-
requestId: `${request.id}#${invokeOccurrence(events, request.id)}`,
|
|
761
|
-
request
|
|
762
|
-
});
|
|
763
|
-
emitted.add(request.id);
|
|
764
|
-
}
|
|
765
577
|
const children = snapshot.children;
|
|
766
578
|
for (const [id, child] of Object.entries(children ?? {})) {
|
|
767
579
|
if (emitted.has(id) || invokeOccurrence(events, id) > 1) continue;
|
|
@@ -1388,11 +1200,7 @@ const USAGE_ATTRIBUTION_FIELDS = [
|
|
|
1388
1200
|
"model",
|
|
1389
1201
|
"name"
|
|
1390
1202
|
];
|
|
1391
|
-
const USAGE_KINDS = [
|
|
1392
|
-
"text",
|
|
1393
|
-
"decision",
|
|
1394
|
-
"plan"
|
|
1395
|
-
];
|
|
1203
|
+
const USAGE_KINDS = ["text", "decision"];
|
|
1396
1204
|
/**
|
|
1397
1205
|
* Standard Schema for the reserved `'@agent.usage'` payload. Hand-rolled (no
|
|
1398
1206
|
* validation-library dependency in core) and deliberately permissive about
|
|
@@ -1510,7 +1318,7 @@ function resolveAgentStateSchemas(contextSchema, states) {
|
|
|
1510
1318
|
* state/transition meta are all standard schemas — no `{} as Type` casts —
|
|
1511
1319
|
* and are retained on `result.schemas` for runtime validation. Also
|
|
1512
1320
|
* registers the `agent.generateText`/`agent.streamText`/`agent.userInput`/
|
|
1513
|
-
* `agent.decide
|
|
1321
|
+
* `agent.decide` builtin actors and lowers `requests`/`actors` into the
|
|
1514
1322
|
* machine's actor sources. The result is the xstate `setup(...)` object with
|
|
1515
1323
|
* a wrapped `result.createMachine(...)` plus `result.schemas`/`models`/
|
|
1516
1324
|
* `requests`/`appendMessages` attached. Also has a
|
|
@@ -1632,14 +1440,13 @@ function assertStateSchemaKeysExist(stateSchemas, machineStates, path = []) {
|
|
|
1632
1440
|
const RESERVED_AGENT_ACTOR_KEYS = [
|
|
1633
1441
|
...Object.keys(builtinTextActors),
|
|
1634
1442
|
USER_INPUT_ACTOR,
|
|
1635
|
-
DECIDE_ACTOR
|
|
1636
|
-
PLAN_ACTOR
|
|
1443
|
+
DECIDE_ACTOR
|
|
1637
1444
|
];
|
|
1638
1445
|
/**
|
|
1639
1446
|
* Rejects a user-supplied `actors`/`requests` key in the reserved
|
|
1640
1447
|
* `agent.*` builtin namespace. Without this, the builtins-first spread in
|
|
1641
1448
|
* {@link createAgentActors} lets such a key overwrite the builtin
|
|
1642
|
-
* (`agent.decide`,
|
|
1449
|
+
* (`agent.decide`, …) silently. Deliberate override of a builtin
|
|
1643
1450
|
* is still possible after the machine is created, via
|
|
1644
1451
|
* `machine.provide({ actors: { 'agent.decide': ... } })`.
|
|
1645
1452
|
*/
|
|
@@ -1654,7 +1461,6 @@ function createAgentActors(actors, requestActors) {
|
|
|
1654
1461
|
...builtinTextActors,
|
|
1655
1462
|
[USER_INPUT_ACTOR]: userInputActor,
|
|
1656
1463
|
[DECIDE_ACTOR]: createDecideActor(),
|
|
1657
|
-
[PLAN_ACTOR]: createPlanActor(),
|
|
1658
1464
|
...actors,
|
|
1659
1465
|
...requestActors
|
|
1660
1466
|
};
|
|
@@ -1708,4 +1514,4 @@ function createSetupAgent(config) {
|
|
|
1708
1514
|
});
|
|
1709
1515
|
}
|
|
1710
1516
|
//#endregion
|
|
1711
|
-
export {
|
|
1517
|
+
export { resolveAgentStep as _, AgentReplayDivergenceError as a, messagesSchema as b, diffEventLogs as c, initEntry as d, replay as f, initialAgentStep as g, getInvokeEffectMetadata as h, AGENT_USAGE_EVENT_TYPE as i, getAgentEffects as l, executeAgentRequest as m, setupAgent as n, AgentReplayMachineMismatchError as o, verifyReplay as p, AGENT_INIT_EVENT_TYPE as r, createReplayEntry as s, createAgentSchemas as t, getCallUsage as u, transitionAgentStep as v, appendMessages as y };
|
package/dist/sqlite.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as AgentSnapshotStore } from "./types-
|
|
2
|
-
import { r as AgentEventLogStore } from "./event-log-store-
|
|
1
|
+
import { r as AgentSnapshotStore } from "./types-DFD28AWe.cjs";
|
|
2
|
+
import { r as AgentEventLogStore } from "./event-log-store-CVd2eyRy.cjs";
|
|
3
3
|
|
|
4
4
|
//#region src/sqlite/index.d.ts
|
|
5
5
|
/** A prepared statement, structurally compatible with `node:sqlite`'s `StatementSync`. */
|
package/dist/sqlite.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as AgentSnapshotStore } from "./types-
|
|
2
|
-
import { r as AgentEventLogStore } from "./event-log-store-
|
|
1
|
+
import { r as AgentSnapshotStore } from "./types-CTBhMnFu.mjs";
|
|
2
|
+
import { r as AgentEventLogStore } from "./event-log-store-BkUNtyOF.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/sqlite/index.d.ts
|
|
5
5
|
/** A prepared statement, structurally compatible with `node:sqlite`'s `StatementSync`. */
|