@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as AgentError } from "./errors-CeSXQx0v.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { a as assertJsonSerializable, i as assertAgentLogEntry } from "./event-log-store-
|
|
2
|
+
import { F as djb2Hex, M as machineStaticTransitionTargets, N as missingActor, T as agentExecutionOptions, U as resolveMachineVersion, d as USER_INPUT_ACTOR, g as executeAgentTextRequest, h as createTextLogic, j as machineIdlePredicates, k as getRegisteredAgentExecutionOptions, l as DECIDE_ACTOR, m as builtinTextActors, n as createDecideActor, o as getAcceptedEvents, q as validateSchemaSync, r as isDecisionLogic, w as userInputActor, y as isTextLogic } from "./decision-BfhSgCc6.mjs";
|
|
3
|
+
import { a as assertJsonSerializable, i as assertAgentLogEntry } from "./event-log-store-DmIDosD6.mjs";
|
|
4
4
|
import { createMachineFromConfig, initialTransition, setup, transition } from "xstate";
|
|
5
5
|
//#region src/messages.ts
|
|
6
6
|
function addMessages(resolve) {
|
|
@@ -221,7 +221,7 @@ function resolveAgentStep(machine, step, request, output, options) {
|
|
|
221
221
|
return createAgentStep(machine, snapshot, actions, getRegisteredAgentExecutionOptions(machine, options));
|
|
222
222
|
}
|
|
223
223
|
async function executeAgentRequest(requestOrEffect, executors) {
|
|
224
|
-
if (requestOrEffect.kind === "decision") throw new Error("executeAgentRequest(...) is text-only. Resolve a 'decision' request with resolveDecision(request, executors
|
|
224
|
+
if (requestOrEffect.kind === "decision") throw new Error("executeAgentRequest(...) is text-only. Resolve a 'decision' request with resolveDecision(request, executors, ...) instead.");
|
|
225
225
|
const request = "requestId" in requestOrEffect ? {
|
|
226
226
|
kind: "text",
|
|
227
227
|
id: requestOrEffect.requestId,
|
|
@@ -335,7 +335,7 @@ const AGENT_USAGE_EVENT_TYPE = "@agent.usage";
|
|
|
335
335
|
function createReplayEntry(machine, entries, event, options = {}) {
|
|
336
336
|
const index = entries.length;
|
|
337
337
|
const machineId = machine.config.id ?? machine.id ?? "(machine)";
|
|
338
|
-
const machineVersion = options.machineVersion ??
|
|
338
|
+
const machineVersion = options.machineVersion ?? resolveMachineVersion(machine);
|
|
339
339
|
const entry = {
|
|
340
340
|
schemaVersion: 1,
|
|
341
341
|
id: options.id ?? `evt_${String(index).padStart(8, "0")}`,
|
|
@@ -373,6 +373,13 @@ function toEvents(history) {
|
|
|
373
373
|
return candidate && typeof candidate === "object" && "event" in candidate && candidate.event ? candidate.event : entry;
|
|
374
374
|
});
|
|
375
375
|
}
|
|
376
|
+
/**
|
|
377
|
+
* Rewrites a journaled actor event's per-incarnation `sessionId` to the
|
|
378
|
+
* current snapshot's child for the same stable `actorId`, so replayed
|
|
379
|
+
* completions match freshly restored children.
|
|
380
|
+
*
|
|
381
|
+
* @internal
|
|
382
|
+
*/
|
|
376
383
|
function rebindActorSession(event, snapshot, sessions) {
|
|
377
384
|
const actorEvent = event;
|
|
378
385
|
if (typeof actorEvent.actorId !== "string" || typeof actorEvent.sessionId !== "string") return event;
|
|
@@ -631,7 +638,7 @@ function validateReplayEntries(entries, expected, label) {
|
|
|
631
638
|
function replay(machine, entries, options = {}) {
|
|
632
639
|
validateReplayEntries(entries, {
|
|
633
640
|
machineId: machine.config.id ?? machine.id ?? "(machine)",
|
|
634
|
-
machineVersion: options.machineVersion ??
|
|
641
|
+
machineVersion: options.machineVersion ?? resolveMachineVersion(machine)
|
|
635
642
|
}, "Replay entries");
|
|
636
643
|
const events = toEvents(entries);
|
|
637
644
|
const initOffset = events[0]?.type === "@agent.init" ? 1 : 0;
|
|
@@ -661,13 +668,6 @@ function replay(machine, entries, options = {}) {
|
|
|
661
668
|
effects
|
|
662
669
|
};
|
|
663
670
|
}
|
|
664
|
-
/** Requires and checks every entry's recorded state/effect hashes. */
|
|
665
|
-
function verifyReplay(machine, entries, options = {}) {
|
|
666
|
-
return replay(machine, entries, {
|
|
667
|
-
...options,
|
|
668
|
-
verify: "strict"
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
671
|
/** Structural event-tail, logical-state, and owed-effect comparison. */
|
|
672
672
|
function diffEventLogs(machine, parentEntries, forkEntries, options = {}) {
|
|
673
673
|
let commonLength = 0;
|
|
@@ -1135,14 +1135,14 @@ function collectDeclaredStateTags(states, tags = /* @__PURE__ */ new Set()) {
|
|
|
1135
1135
|
}
|
|
1136
1136
|
return tags;
|
|
1137
1137
|
}
|
|
1138
|
-
function
|
|
1139
|
-
if (options.
|
|
1140
|
-
const
|
|
1141
|
-
if (!
|
|
1138
|
+
function resolveIdlePredicate(config, options) {
|
|
1139
|
+
if (options.isIdle) return options.isIdle;
|
|
1140
|
+
const idleTags = config.idleTags ?? [];
|
|
1141
|
+
if (!idleTags.length) return;
|
|
1142
1142
|
const declaredTags = collectDeclaredStateTags(config.states);
|
|
1143
|
-
const unknown =
|
|
1144
|
-
if (unknown.length) throw new Error(`setupAgent.fromConfig: '
|
|
1145
|
-
return (snapshot) =>
|
|
1143
|
+
const unknown = idleTags.filter((tag) => !declaredTags.has(tag));
|
|
1144
|
+
if (unknown.length) throw new Error(`setupAgent.fromConfig: 'idleTags' lists ${unknown.map((tag) => `'${tag}'`).join(", ")}, which no state declares in its 'tags'. Tag the waiting state(s) — e.g. "tags": ["${unknown[0]}"] — or remove the entry.`);
|
|
1145
|
+
return (snapshot) => idleTags.some((tag) => snapshot.hasTag(tag));
|
|
1146
1146
|
}
|
|
1147
1147
|
function setupAgentFromConfig(config, options) {
|
|
1148
1148
|
if (!options || typeof options.compileSchema !== "function") throw new Error("setupAgent.fromConfig(...) requires a 'compileSchema' option: { compileSchema: (jsonSchema, name) => StandardSchemaV1 }. Bring your own JSON Schema engine (Ajv, @cfworker/json-schema, a compiled-Zod-from-JSON-Schema pipeline, ...). Core intentionally ships no JSON Schema engine.");
|
|
@@ -1174,8 +1174,8 @@ function setupAgentFromConfig(config, options) {
|
|
|
1174
1174
|
models: {}
|
|
1175
1175
|
});
|
|
1176
1176
|
if (machine.config) machineStaticTransitionTargets.set(machine.config, translation.transitionTargets);
|
|
1177
|
-
const
|
|
1178
|
-
if (
|
|
1177
|
+
const isIdle = resolveIdlePredicate(config, options);
|
|
1178
|
+
if (isIdle && machine.config) machineIdlePredicates.set(machine.config, isIdle);
|
|
1179
1179
|
return {
|
|
1180
1180
|
machine,
|
|
1181
1181
|
schemas
|
|
@@ -1389,9 +1389,9 @@ function setupAgent(config) {
|
|
|
1389
1389
|
assertStateSchemaKeysExist(config.states, machineConfig?.states);
|
|
1390
1390
|
const machine = createBaseMachine(withRootOutputFromSingleFinal(machineConfig));
|
|
1391
1391
|
agentExecutionOptions.set(machine, machineOptions);
|
|
1392
|
-
if (config.
|
|
1392
|
+
if (config.isIdle) {
|
|
1393
1393
|
const rootConfig = machine.config;
|
|
1394
|
-
if (rootConfig)
|
|
1394
|
+
if (rootConfig) machineIdlePredicates.set(rootConfig, config.isIdle);
|
|
1395
1395
|
}
|
|
1396
1396
|
return machine;
|
|
1397
1397
|
},
|
|
@@ -1482,13 +1482,22 @@ const RESERVED_AGENT_ACTOR_KEYS = [
|
|
|
1482
1482
|
DECIDE_ACTOR
|
|
1483
1483
|
];
|
|
1484
1484
|
/**
|
|
1485
|
+
* The whole `agent.` actor-source namespace is reserved for the library, not
|
|
1486
|
+
* just the shipped builtins: a key starting with this prefix is rejected at
|
|
1487
|
+
* setup time so a future builtin can never collide with (or be shadowed by) a
|
|
1488
|
+
* user source. Name your own sources without it.
|
|
1489
|
+
*/
|
|
1490
|
+
const RESERVED_AGENT_KEY_PREFIX = "agent.";
|
|
1491
|
+
/**
|
|
1485
1492
|
* Runtime guards over the user-supplied `actors`/`requests` keys, in one walk
|
|
1486
1493
|
* of both groups:
|
|
1487
1494
|
*
|
|
1488
|
-
* 1. A key in the reserved `agent
|
|
1489
|
-
*
|
|
1490
|
-
* key overwrite the builtin
|
|
1491
|
-
*
|
|
1495
|
+
* 1. A key in the reserved `agent.` namespace is rejected — every key with
|
|
1496
|
+
* that prefix, not only today's builtins. Without this, the builtins-first
|
|
1497
|
+
* spread in {@link createAgentActors} lets such a key overwrite the builtin
|
|
1498
|
+
* (`agent.decide`, …) silently, and a builtin added later would start
|
|
1499
|
+
* colliding with user code. Deliberate override of a builtin is still
|
|
1500
|
+
* possible after the machine is created, via
|
|
1492
1501
|
* `machine.provide({ actors: { 'agent.decide': ... } })`.
|
|
1493
1502
|
* 2. A key appearing in BOTH groups is almost certainly a mistake (whichever
|
|
1494
1503
|
* spread applies last would silently win) — fail fast with a clear message
|
|
@@ -1499,6 +1508,7 @@ function assertActorKeys(actors, requests) {
|
|
|
1499
1508
|
const groups = [["actors", actors], ["requests", requests]];
|
|
1500
1509
|
for (const [groupName, group] of groups) for (const key of Object.keys(group ?? {})) {
|
|
1501
1510
|
if (RESERVED_AGENT_ACTOR_KEYS.some((reserved) => reserved === key)) throw new Error(`setupAgent: '${groupName}' key '${key}' is a reserved builtin agent actor and cannot be redefined here (it would silently clobber the builtin). Reserved keys: ${RESERVED_AGENT_ACTOR_KEYS.join(", ")}. To deliberately override a builtin, do it on the created machine instead: machine.provide({ actors: { '${key}': ... } }).`);
|
|
1511
|
+
if (key.startsWith(RESERVED_AGENT_KEY_PREFIX)) throw new Error(`setupAgent: '${groupName}' key '${key}' uses the reserved '${RESERVED_AGENT_KEY_PREFIX}' namespace, which belongs to the library (${RESERVED_AGENT_ACTOR_KEYS.join(", ")}, and anything added later). Rename it without the '${RESERVED_AGENT_KEY_PREFIX}' prefix.`);
|
|
1502
1512
|
const existingGroup = seenIn.get(key);
|
|
1503
1513
|
if (existingGroup) throw new Error(`setupAgent: key '${key}' is defined in both '${existingGroup}' and '${groupName}'. Each actor source key must be unique across 'actors' and 'requests'.`);
|
|
1504
1514
|
seenIn.set(key, groupName);
|
|
@@ -1515,4 +1525,4 @@ function createAgentActors(actors, requestActors) {
|
|
|
1515
1525
|
};
|
|
1516
1526
|
}
|
|
1517
1527
|
//#endregion
|
|
1518
|
-
export { initialAgentStep as _, AGENT_USAGE_EVENT_TYPE as a, appendMessages as b, createReplayEntry as c, initEntry as d,
|
|
1528
|
+
export { initialAgentStep as _, AGENT_USAGE_EVENT_TYPE as a, appendMessages as b, createReplayEntry as c, initEntry as d, rebindActorSession as f, getInvokeEffectMetadata as g, executeAgentRequest as h, AGENT_INIT_EVENT_TYPE as i, diffEventLogs as l, validateReplayEntries as m, getAgentSchemas as n, AgentReplayDivergenceError as o, replay as p, setupAgent as r, AgentReplayMachineMismatchError as s, createAgentSchemas as t, getAgentEffects as u, resolveAgentStep as v, messagesSchema as x, transitionAgentStep as y };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const require_errors = require("./errors-DUBBzRLP.cjs");
|
|
2
|
-
const require_decision = require("./decision-
|
|
3
|
-
const require_event_log_store = require("./event-log-store-
|
|
2
|
+
const require_decision = require("./decision-DhsKLYAI.cjs");
|
|
3
|
+
const require_event_log_store = require("./event-log-store-a_TKy1gk.cjs");
|
|
4
|
+
require("./validate.cjs");
|
|
4
5
|
let xstate = require("xstate");
|
|
5
6
|
//#region src/messages.ts
|
|
6
7
|
function addMessages(resolve) {
|
|
@@ -221,7 +222,7 @@ function resolveAgentStep(machine, step, request, output, options) {
|
|
|
221
222
|
return createAgentStep(machine, snapshot, actions, require_decision.getRegisteredAgentExecutionOptions(machine, options));
|
|
222
223
|
}
|
|
223
224
|
async function executeAgentRequest(requestOrEffect, executors) {
|
|
224
|
-
if (requestOrEffect.kind === "decision") throw new Error("executeAgentRequest(...) is text-only. Resolve a 'decision' request with resolveDecision(request, executors
|
|
225
|
+
if (requestOrEffect.kind === "decision") throw new Error("executeAgentRequest(...) is text-only. Resolve a 'decision' request with resolveDecision(request, executors, ...) instead.");
|
|
225
226
|
const request = "requestId" in requestOrEffect ? {
|
|
226
227
|
kind: "text",
|
|
227
228
|
id: requestOrEffect.requestId,
|
|
@@ -335,7 +336,7 @@ const AGENT_USAGE_EVENT_TYPE = "@agent.usage";
|
|
|
335
336
|
function createReplayEntry(machine, entries, event, options = {}) {
|
|
336
337
|
const index = entries.length;
|
|
337
338
|
const machineId = machine.config.id ?? machine.id ?? "(machine)";
|
|
338
|
-
const machineVersion = options.machineVersion ?? require_decision.
|
|
339
|
+
const machineVersion = options.machineVersion ?? require_decision.resolveMachineVersion(machine);
|
|
339
340
|
const entry = {
|
|
340
341
|
schemaVersion: 1,
|
|
341
342
|
id: options.id ?? `evt_${String(index).padStart(8, "0")}`,
|
|
@@ -373,6 +374,13 @@ function toEvents(history) {
|
|
|
373
374
|
return candidate && typeof candidate === "object" && "event" in candidate && candidate.event ? candidate.event : entry;
|
|
374
375
|
});
|
|
375
376
|
}
|
|
377
|
+
/**
|
|
378
|
+
* Rewrites a journaled actor event's per-incarnation `sessionId` to the
|
|
379
|
+
* current snapshot's child for the same stable `actorId`, so replayed
|
|
380
|
+
* completions match freshly restored children.
|
|
381
|
+
*
|
|
382
|
+
* @internal
|
|
383
|
+
*/
|
|
376
384
|
function rebindActorSession(event, snapshot, sessions) {
|
|
377
385
|
const actorEvent = event;
|
|
378
386
|
if (typeof actorEvent.actorId !== "string" || typeof actorEvent.sessionId !== "string") return event;
|
|
@@ -631,7 +639,7 @@ function validateReplayEntries(entries, expected, label) {
|
|
|
631
639
|
function replay(machine, entries, options = {}) {
|
|
632
640
|
validateReplayEntries(entries, {
|
|
633
641
|
machineId: machine.config.id ?? machine.id ?? "(machine)",
|
|
634
|
-
machineVersion: options.machineVersion ?? require_decision.
|
|
642
|
+
machineVersion: options.machineVersion ?? require_decision.resolveMachineVersion(machine)
|
|
635
643
|
}, "Replay entries");
|
|
636
644
|
const events = toEvents(entries);
|
|
637
645
|
const initOffset = events[0]?.type === "@agent.init" ? 1 : 0;
|
|
@@ -661,13 +669,6 @@ function replay(machine, entries, options = {}) {
|
|
|
661
669
|
effects
|
|
662
670
|
};
|
|
663
671
|
}
|
|
664
|
-
/** Requires and checks every entry's recorded state/effect hashes. */
|
|
665
|
-
function verifyReplay(machine, entries, options = {}) {
|
|
666
|
-
return replay(machine, entries, {
|
|
667
|
-
...options,
|
|
668
|
-
verify: "strict"
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
672
|
/** Structural event-tail, logical-state, and owed-effect comparison. */
|
|
672
673
|
function diffEventLogs(machine, parentEntries, forkEntries, options = {}) {
|
|
673
674
|
let commonLength = 0;
|
|
@@ -1135,14 +1136,14 @@ function collectDeclaredStateTags(states, tags = /* @__PURE__ */ new Set()) {
|
|
|
1135
1136
|
}
|
|
1136
1137
|
return tags;
|
|
1137
1138
|
}
|
|
1138
|
-
function
|
|
1139
|
-
if (options.
|
|
1140
|
-
const
|
|
1141
|
-
if (!
|
|
1139
|
+
function resolveIdlePredicate(config, options) {
|
|
1140
|
+
if (options.isIdle) return options.isIdle;
|
|
1141
|
+
const idleTags = config.idleTags ?? [];
|
|
1142
|
+
if (!idleTags.length) return;
|
|
1142
1143
|
const declaredTags = collectDeclaredStateTags(config.states);
|
|
1143
|
-
const unknown =
|
|
1144
|
-
if (unknown.length) throw new Error(`setupAgent.fromConfig: '
|
|
1145
|
-
return (snapshot) =>
|
|
1144
|
+
const unknown = idleTags.filter((tag) => !declaredTags.has(tag));
|
|
1145
|
+
if (unknown.length) throw new Error(`setupAgent.fromConfig: 'idleTags' lists ${unknown.map((tag) => `'${tag}'`).join(", ")}, which no state declares in its 'tags'. Tag the waiting state(s) — e.g. "tags": ["${unknown[0]}"] — or remove the entry.`);
|
|
1146
|
+
return (snapshot) => idleTags.some((tag) => snapshot.hasTag(tag));
|
|
1146
1147
|
}
|
|
1147
1148
|
function setupAgentFromConfig(config, options) {
|
|
1148
1149
|
if (!options || typeof options.compileSchema !== "function") throw new Error("setupAgent.fromConfig(...) requires a 'compileSchema' option: { compileSchema: (jsonSchema, name) => StandardSchemaV1 }. Bring your own JSON Schema engine (Ajv, @cfworker/json-schema, a compiled-Zod-from-JSON-Schema pipeline, ...). Core intentionally ships no JSON Schema engine.");
|
|
@@ -1174,8 +1175,8 @@ function setupAgentFromConfig(config, options) {
|
|
|
1174
1175
|
models: {}
|
|
1175
1176
|
});
|
|
1176
1177
|
if (machine.config) require_decision.machineStaticTransitionTargets.set(machine.config, translation.transitionTargets);
|
|
1177
|
-
const
|
|
1178
|
-
if (
|
|
1178
|
+
const isIdle = resolveIdlePredicate(config, options);
|
|
1179
|
+
if (isIdle && machine.config) require_decision.machineIdlePredicates.set(machine.config, isIdle);
|
|
1179
1180
|
return {
|
|
1180
1181
|
machine,
|
|
1181
1182
|
schemas
|
|
@@ -1389,9 +1390,9 @@ function setupAgent(config) {
|
|
|
1389
1390
|
assertStateSchemaKeysExist(config.states, machineConfig?.states);
|
|
1390
1391
|
const machine = createBaseMachine(withRootOutputFromSingleFinal(machineConfig));
|
|
1391
1392
|
require_decision.agentExecutionOptions.set(machine, machineOptions);
|
|
1392
|
-
if (config.
|
|
1393
|
+
if (config.isIdle) {
|
|
1393
1394
|
const rootConfig = machine.config;
|
|
1394
|
-
if (rootConfig) require_decision.
|
|
1395
|
+
if (rootConfig) require_decision.machineIdlePredicates.set(rootConfig, config.isIdle);
|
|
1395
1396
|
}
|
|
1396
1397
|
return machine;
|
|
1397
1398
|
},
|
|
@@ -1482,13 +1483,22 @@ const RESERVED_AGENT_ACTOR_KEYS = [
|
|
|
1482
1483
|
require_decision.DECIDE_ACTOR
|
|
1483
1484
|
];
|
|
1484
1485
|
/**
|
|
1486
|
+
* The whole `agent.` actor-source namespace is reserved for the library, not
|
|
1487
|
+
* just the shipped builtins: a key starting with this prefix is rejected at
|
|
1488
|
+
* setup time so a future builtin can never collide with (or be shadowed by) a
|
|
1489
|
+
* user source. Name your own sources without it.
|
|
1490
|
+
*/
|
|
1491
|
+
const RESERVED_AGENT_KEY_PREFIX = "agent.";
|
|
1492
|
+
/**
|
|
1485
1493
|
* Runtime guards over the user-supplied `actors`/`requests` keys, in one walk
|
|
1486
1494
|
* of both groups:
|
|
1487
1495
|
*
|
|
1488
|
-
* 1. A key in the reserved `agent
|
|
1489
|
-
*
|
|
1490
|
-
* key overwrite the builtin
|
|
1491
|
-
*
|
|
1496
|
+
* 1. A key in the reserved `agent.` namespace is rejected — every key with
|
|
1497
|
+
* that prefix, not only today's builtins. Without this, the builtins-first
|
|
1498
|
+
* spread in {@link createAgentActors} lets such a key overwrite the builtin
|
|
1499
|
+
* (`agent.decide`, …) silently, and a builtin added later would start
|
|
1500
|
+
* colliding with user code. Deliberate override of a builtin is still
|
|
1501
|
+
* possible after the machine is created, via
|
|
1492
1502
|
* `machine.provide({ actors: { 'agent.decide': ... } })`.
|
|
1493
1503
|
* 2. A key appearing in BOTH groups is almost certainly a mistake (whichever
|
|
1494
1504
|
* spread applies last would silently win) — fail fast with a clear message
|
|
@@ -1499,6 +1509,7 @@ function assertActorKeys(actors, requests) {
|
|
|
1499
1509
|
const groups = [["actors", actors], ["requests", requests]];
|
|
1500
1510
|
for (const [groupName, group] of groups) for (const key of Object.keys(group ?? {})) {
|
|
1501
1511
|
if (RESERVED_AGENT_ACTOR_KEYS.some((reserved) => reserved === key)) throw new Error(`setupAgent: '${groupName}' key '${key}' is a reserved builtin agent actor and cannot be redefined here (it would silently clobber the builtin). Reserved keys: ${RESERVED_AGENT_ACTOR_KEYS.join(", ")}. To deliberately override a builtin, do it on the created machine instead: machine.provide({ actors: { '${key}': ... } }).`);
|
|
1512
|
+
if (key.startsWith(RESERVED_AGENT_KEY_PREFIX)) throw new Error(`setupAgent: '${groupName}' key '${key}' uses the reserved '${RESERVED_AGENT_KEY_PREFIX}' namespace, which belongs to the library (${RESERVED_AGENT_ACTOR_KEYS.join(", ")}, and anything added later). Rename it without the '${RESERVED_AGENT_KEY_PREFIX}' prefix.`);
|
|
1502
1513
|
const existingGroup = seenIn.get(key);
|
|
1503
1514
|
if (existingGroup) throw new Error(`setupAgent: key '${key}' is defined in both '${existingGroup}' and '${groupName}'. Each actor source key must be unique across 'actors' and 'requests'.`);
|
|
1504
1515
|
seenIn.set(key, groupName);
|
|
@@ -1605,6 +1616,12 @@ Object.defineProperty(exports, "messagesSchema", {
|
|
|
1605
1616
|
return messagesSchema;
|
|
1606
1617
|
}
|
|
1607
1618
|
});
|
|
1619
|
+
Object.defineProperty(exports, "rebindActorSession", {
|
|
1620
|
+
enumerable: true,
|
|
1621
|
+
get: function() {
|
|
1622
|
+
return rebindActorSession;
|
|
1623
|
+
}
|
|
1624
|
+
});
|
|
1608
1625
|
Object.defineProperty(exports, "replay", {
|
|
1609
1626
|
enumerable: true,
|
|
1610
1627
|
get: function() {
|
|
@@ -1635,9 +1652,3 @@ Object.defineProperty(exports, "validateReplayEntries", {
|
|
|
1635
1652
|
return validateReplayEntries;
|
|
1636
1653
|
}
|
|
1637
1654
|
});
|
|
1638
|
-
Object.defineProperty(exports, "verifyReplay", {
|
|
1639
|
-
enumerable: true,
|
|
1640
|
-
get: function() {
|
|
1641
|
-
return verifyReplay;
|
|
1642
|
-
}
|
|
1643
|
-
});
|
package/dist/sqlite.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_event_log_store = require("./event-log-store-
|
|
2
|
+
const require_event_log_store = require("./event-log-store-a_TKy1gk.cjs");
|
|
3
3
|
//#region src/sqlite/index.ts
|
|
4
4
|
function openDatabase(path) {
|
|
5
5
|
const sqlite = process.getBuiltinModule?.("node:sqlite");
|
|
@@ -80,18 +80,12 @@ function createSqliteEventLogStore(options) {
|
|
|
80
80
|
async length(threadId) {
|
|
81
81
|
return lengthOf(threadId);
|
|
82
82
|
},
|
|
83
|
-
async fork({ threadId, newThreadId, upToIndex
|
|
84
|
-
if (upToIndex !== void 0 && atEventId !== void 0) throw new Error("AgentEventLogStore.fork: pass either upToIndex or atEventId, not both.");
|
|
83
|
+
async fork({ threadId, newThreadId, upToIndex }) {
|
|
85
84
|
transact(() => {
|
|
86
85
|
if (lengthOf(newThreadId) > 0) throw new Error(`AgentEventLogStore.fork: newThreadId "${newThreadId}" already has entries.`);
|
|
87
86
|
const sourceLength = lengthOf(threadId);
|
|
88
87
|
if (sourceLength === 0) throw new Error(`AgentEventLogStore.fork: unknown source thread "${threadId}".`);
|
|
89
|
-
|
|
90
|
-
if (atEventId !== void 0) {
|
|
91
|
-
const row = db.prepare(`SELECT idx FROM ${table} WHERE thread_id = ? AND entry_id = ?`).get(threadId, atEventId);
|
|
92
|
-
if (!row) throw new Error(`AgentEventLogStore.fork: thread "${threadId}" has no event id "${atEventId}".`);
|
|
93
|
-
upTo = Number(row.idx) + 1;
|
|
94
|
-
}
|
|
88
|
+
const upTo = upToIndex ?? sourceLength;
|
|
95
89
|
if (upTo < 0 || upTo > sourceLength) throw new Error(`AgentEventLogStore.fork: thread "${threadId}" (length ${sourceLength}) has no index ${upTo} to fork up to.`);
|
|
96
90
|
db.prepare(`INSERT INTO ${table} (thread_id, idx, entry_id, entry)
|
|
97
91
|
SELECT ?, idx, entry_id, entry FROM ${table} WHERE thread_id = ? AND idx < ?`).run(newThreadId, threadId, upTo);
|
package/dist/sqlite.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as AgentSnapshotStore } from "./types-pJ5Hn8fv.cjs";
|
|
2
|
-
import { r as AgentEventLogStore } from "./event-log-store-
|
|
2
|
+
import { r as AgentEventLogStore } from "./event-log-store-Bz7HDBkE.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
1
|
import { r as AgentSnapshotStore } from "./types-DYpK3QF4.mjs";
|
|
2
|
-
import { r as AgentEventLogStore } from "./event-log-store-
|
|
2
|
+
import { r as AgentEventLogStore } from "./event-log-store-hrA1vqtN.mjs";
|
|
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.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as assertAgentLogEntry, n as AgentEventLogConflictError } from "./event-log-store-
|
|
1
|
+
import { i as assertAgentLogEntry, n as AgentEventLogConflictError } from "./event-log-store-DmIDosD6.mjs";
|
|
2
2
|
//#region src/sqlite/index.ts
|
|
3
3
|
function openDatabase(path) {
|
|
4
4
|
const sqlite = process.getBuiltinModule?.("node:sqlite");
|
|
@@ -79,18 +79,12 @@ function createSqliteEventLogStore(options) {
|
|
|
79
79
|
async length(threadId) {
|
|
80
80
|
return lengthOf(threadId);
|
|
81
81
|
},
|
|
82
|
-
async fork({ threadId, newThreadId, upToIndex
|
|
83
|
-
if (upToIndex !== void 0 && atEventId !== void 0) throw new Error("AgentEventLogStore.fork: pass either upToIndex or atEventId, not both.");
|
|
82
|
+
async fork({ threadId, newThreadId, upToIndex }) {
|
|
84
83
|
transact(() => {
|
|
85
84
|
if (lengthOf(newThreadId) > 0) throw new Error(`AgentEventLogStore.fork: newThreadId "${newThreadId}" already has entries.`);
|
|
86
85
|
const sourceLength = lengthOf(threadId);
|
|
87
86
|
if (sourceLength === 0) throw new Error(`AgentEventLogStore.fork: unknown source thread "${threadId}".`);
|
|
88
|
-
|
|
89
|
-
if (atEventId !== void 0) {
|
|
90
|
-
const row = db.prepare(`SELECT idx FROM ${table} WHERE thread_id = ? AND entry_id = ?`).get(threadId, atEventId);
|
|
91
|
-
if (!row) throw new Error(`AgentEventLogStore.fork: thread "${threadId}" has no event id "${atEventId}".`);
|
|
92
|
-
upTo = Number(row.idx) + 1;
|
|
93
|
-
}
|
|
87
|
+
const upTo = upToIndex ?? sourceLength;
|
|
94
88
|
if (upTo < 0 || upTo > sourceLength) throw new Error(`AgentEventLogStore.fork: thread "${threadId}" (length ${sourceLength}) has no index ${upTo} to fork up to.`);
|
|
95
89
|
db.prepare(`INSERT INTO ${table} (thread_id, idx, entry_id, entry)
|
|
96
90
|
SELECT ?, idx, entry_id, entry FROM ${table} WHERE thread_id = ? AND idx < ?`).run(newThreadId, threadId, upTo);
|
|
@@ -214,14 +214,17 @@ declare function renderDecisionAttempts(request: Pick<AgentDecisionRequest, "eve
|
|
|
214
214
|
* `generateText`/`streamText` — how the model is coerced into choosing
|
|
215
215
|
* (tool-per-event + forced tool choice, structured output, …) is entirely
|
|
216
216
|
* adapter business; core only validates and retries the returned choice (see
|
|
217
|
-
* {@link resolveDecision}).
|
|
217
|
+
* {@link resolveDecision}). It takes the same `(request, info)` pair as
|
|
218
|
+
* `generateText`/`streamText` — `info` carries the host seams (`signal`,
|
|
219
|
+
* `runId`, `requestId`); `onChunk` is never set for a decision.
|
|
220
|
+
* The optional `reason` is carried through to
|
|
218
221
|
* `onResult`/event-sourcing but never affects validation. Like text
|
|
219
222
|
* executors' `{ output, ...extras }` envelope, any extra keys (finish reason,
|
|
220
223
|
* …) flow untouched to `onResult`'s `raw`; `usage` is the one core reads —
|
|
221
224
|
* report this attempt's tokens there and `runAgent` folds them into the run's
|
|
222
225
|
* aggregated {@link AgentUsage}.
|
|
223
226
|
*/
|
|
224
|
-
type AgentDecisionExecutor = (request: AgentDecisionRequest) => PromiseLike<{
|
|
227
|
+
type AgentDecisionExecutor = (request: AgentDecisionRequest, info?: AgentRequestExecutorInfo) => PromiseLike<{
|
|
225
228
|
event: ChosenEvent;
|
|
226
229
|
reason?: string; /** This attempt's token usage, aggregated into the run result's {@link AgentUsage}. */
|
|
227
230
|
usage?: AgentCallUsage;
|
|
@@ -252,7 +255,7 @@ interface ResolveDecisionOptions<TEvent extends ChosenEvent = ChosenEvent> {
|
|
|
252
255
|
}
|
|
253
256
|
/**
|
|
254
257
|
* Validation + retry core for decisions. No provider mechanics — the
|
|
255
|
-
* `
|
|
258
|
+
* `executors.decide` is responsible for making the model choose an event; this
|
|
256
259
|
* function only validates the choice and retries on failure, up to
|
|
257
260
|
* `options.maxRetries` (default 2, i.e. up to 3 attempts total).
|
|
258
261
|
*
|
|
@@ -270,12 +273,12 @@ interface ResolveDecisionOptions<TEvent extends ChosenEvent = ChosenEvent> {
|
|
|
270
273
|
*
|
|
271
274
|
* @example
|
|
272
275
|
* ```ts
|
|
273
|
-
* const event = await resolveDecision(request,
|
|
276
|
+
* const event = await resolveDecision(request, executors, {
|
|
274
277
|
* canTake: (e) => snapshot.can(e),
|
|
275
278
|
* });
|
|
276
279
|
* ```
|
|
277
280
|
*/
|
|
278
|
-
declare function resolveDecision<TEvent extends ChosenEvent = ChosenEvent>(request: AgentDecisionRequest,
|
|
281
|
+
declare function resolveDecision<TEvent extends ChosenEvent = ChosenEvent>(request: AgentDecisionRequest, executors: Pick<Partial<AgentRequestExecutors>, "decide">, options?: ResolveDecisionOptions<TEvent>): Promise<TEvent>;
|
|
279
282
|
//#endregion
|
|
280
283
|
//#region src/text-logic.d.ts
|
|
281
284
|
declare const USER_INPUT_ACTOR: "agent.userInput";
|
|
@@ -352,12 +355,23 @@ interface AgentTextRequest<TMetadata = Record<string, unknown>> {
|
|
|
352
355
|
topK?: number;
|
|
353
356
|
seed?: number;
|
|
354
357
|
stopSequences?: string[];
|
|
358
|
+
/**
|
|
359
|
+
* Bounds the HOST-side tool-call loop for this one request: the maximum
|
|
360
|
+
* number of model steps the executor may run before it must return. Omitted
|
|
361
|
+
* means single-step (one model call, tool results not fed back). Named and
|
|
362
|
+
* typed to match the AI SDK — the shipped adapter lowers it to
|
|
363
|
+
* `stopWhen: stepCountIs(maxSteps)`.
|
|
364
|
+
*
|
|
365
|
+
* This is a REQUEST budget, distinct from the machine-level `maxTurns` a
|
|
366
|
+
* preset uses for its own turn budget, and from `runAgent`'s run-wide
|
|
367
|
+
* `maxModelCalls`.
|
|
368
|
+
*/
|
|
369
|
+
maxSteps?: number;
|
|
355
370
|
/**
|
|
356
371
|
* Host-owned per-call options. Use this for provider/runtime details such
|
|
357
372
|
* as Cloudflare bindings, tracing IDs, SDK provider options, or transport
|
|
358
|
-
* hints. The machine carries it; the host decides what it means
|
|
359
|
-
*
|
|
360
|
-
* bound its multi-step tool-call loop for that request.
|
|
373
|
+
* hints. The machine carries it; the host decides what it means. Not the
|
|
374
|
+
* place for `maxSteps` any more — that is a typed field above.
|
|
361
375
|
*/
|
|
362
376
|
metadata?: TMetadata;
|
|
363
377
|
}
|
|
@@ -473,6 +487,8 @@ interface TextLogicConfig<TInputSchema extends StandardSchemaV1 = StandardSchema
|
|
|
473
487
|
topK?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
|
|
474
488
|
seed?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
|
|
475
489
|
stopSequences?: ResolveTextLogicValue<string[] | undefined, InferOutput<TInputSchema>>;
|
|
490
|
+
/** Bounds this request's host-side tool loop (see {@link AgentTextRequest.maxSteps}). */
|
|
491
|
+
maxSteps?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
|
|
476
492
|
metadata?: ResolveTextLogicValue<TMetadata | undefined, InferOutput<TInputSchema>>;
|
|
477
493
|
}
|
|
478
494
|
/** Arguments passed to a {@link TextLogicExecutor}: the typed input, the lowered {@link AgentTextRequest}, and the actor's own `signal`/`system`/`self`/`emit`. */
|
|
@@ -214,14 +214,17 @@ declare function renderDecisionAttempts(request: Pick<AgentDecisionRequest, "eve
|
|
|
214
214
|
* `generateText`/`streamText` — how the model is coerced into choosing
|
|
215
215
|
* (tool-per-event + forced tool choice, structured output, …) is entirely
|
|
216
216
|
* adapter business; core only validates and retries the returned choice (see
|
|
217
|
-
* {@link resolveDecision}).
|
|
217
|
+
* {@link resolveDecision}). It takes the same `(request, info)` pair as
|
|
218
|
+
* `generateText`/`streamText` — `info` carries the host seams (`signal`,
|
|
219
|
+
* `runId`, `requestId`); `onChunk` is never set for a decision.
|
|
220
|
+
* The optional `reason` is carried through to
|
|
218
221
|
* `onResult`/event-sourcing but never affects validation. Like text
|
|
219
222
|
* executors' `{ output, ...extras }` envelope, any extra keys (finish reason,
|
|
220
223
|
* …) flow untouched to `onResult`'s `raw`; `usage` is the one core reads —
|
|
221
224
|
* report this attempt's tokens there and `runAgent` folds them into the run's
|
|
222
225
|
* aggregated {@link AgentUsage}.
|
|
223
226
|
*/
|
|
224
|
-
type AgentDecisionExecutor = (request: AgentDecisionRequest) => PromiseLike<{
|
|
227
|
+
type AgentDecisionExecutor = (request: AgentDecisionRequest, info?: AgentRequestExecutorInfo) => PromiseLike<{
|
|
225
228
|
event: ChosenEvent;
|
|
226
229
|
reason?: string; /** This attempt's token usage, aggregated into the run result's {@link AgentUsage}. */
|
|
227
230
|
usage?: AgentCallUsage;
|
|
@@ -252,7 +255,7 @@ interface ResolveDecisionOptions<TEvent extends ChosenEvent = ChosenEvent> {
|
|
|
252
255
|
}
|
|
253
256
|
/**
|
|
254
257
|
* Validation + retry core for decisions. No provider mechanics — the
|
|
255
|
-
* `
|
|
258
|
+
* `executors.decide` is responsible for making the model choose an event; this
|
|
256
259
|
* function only validates the choice and retries on failure, up to
|
|
257
260
|
* `options.maxRetries` (default 2, i.e. up to 3 attempts total).
|
|
258
261
|
*
|
|
@@ -270,12 +273,12 @@ interface ResolveDecisionOptions<TEvent extends ChosenEvent = ChosenEvent> {
|
|
|
270
273
|
*
|
|
271
274
|
* @example
|
|
272
275
|
* ```ts
|
|
273
|
-
* const event = await resolveDecision(request,
|
|
276
|
+
* const event = await resolveDecision(request, executors, {
|
|
274
277
|
* canTake: (e) => snapshot.can(e),
|
|
275
278
|
* });
|
|
276
279
|
* ```
|
|
277
280
|
*/
|
|
278
|
-
declare function resolveDecision<TEvent extends ChosenEvent = ChosenEvent>(request: AgentDecisionRequest,
|
|
281
|
+
declare function resolveDecision<TEvent extends ChosenEvent = ChosenEvent>(request: AgentDecisionRequest, executors: Pick<Partial<AgentRequestExecutors>, "decide">, options?: ResolveDecisionOptions<TEvent>): Promise<TEvent>;
|
|
279
282
|
//#endregion
|
|
280
283
|
//#region src/text-logic.d.ts
|
|
281
284
|
declare const USER_INPUT_ACTOR: "agent.userInput";
|
|
@@ -352,12 +355,23 @@ interface AgentTextRequest<TMetadata = Record<string, unknown>> {
|
|
|
352
355
|
topK?: number;
|
|
353
356
|
seed?: number;
|
|
354
357
|
stopSequences?: string[];
|
|
358
|
+
/**
|
|
359
|
+
* Bounds the HOST-side tool-call loop for this one request: the maximum
|
|
360
|
+
* number of model steps the executor may run before it must return. Omitted
|
|
361
|
+
* means single-step (one model call, tool results not fed back). Named and
|
|
362
|
+
* typed to match the AI SDK — the shipped adapter lowers it to
|
|
363
|
+
* `stopWhen: stepCountIs(maxSteps)`.
|
|
364
|
+
*
|
|
365
|
+
* This is a REQUEST budget, distinct from the machine-level `maxTurns` a
|
|
366
|
+
* preset uses for its own turn budget, and from `runAgent`'s run-wide
|
|
367
|
+
* `maxModelCalls`.
|
|
368
|
+
*/
|
|
369
|
+
maxSteps?: number;
|
|
355
370
|
/**
|
|
356
371
|
* Host-owned per-call options. Use this for provider/runtime details such
|
|
357
372
|
* as Cloudflare bindings, tracing IDs, SDK provider options, or transport
|
|
358
|
-
* hints. The machine carries it; the host decides what it means
|
|
359
|
-
*
|
|
360
|
-
* bound its multi-step tool-call loop for that request.
|
|
373
|
+
* hints. The machine carries it; the host decides what it means. Not the
|
|
374
|
+
* place for `maxSteps` any more — that is a typed field above.
|
|
361
375
|
*/
|
|
362
376
|
metadata?: TMetadata;
|
|
363
377
|
}
|
|
@@ -473,6 +487,8 @@ interface TextLogicConfig<TInputSchema extends StandardSchemaV1 = StandardSchema
|
|
|
473
487
|
topK?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
|
|
474
488
|
seed?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
|
|
475
489
|
stopSequences?: ResolveTextLogicValue<string[] | undefined, InferOutput<TInputSchema>>;
|
|
490
|
+
/** Bounds this request's host-side tool loop (see {@link AgentTextRequest.maxSteps}). */
|
|
491
|
+
maxSteps?: ResolveTextLogicValue<number | undefined, InferOutput<TInputSchema>>;
|
|
476
492
|
metadata?: ResolveTextLogicValue<TMetadata | undefined, InferOutput<TInputSchema>>;
|
|
477
493
|
}
|
|
478
494
|
/** Arguments passed to a {@link TextLogicExecutor}: the typed input, the lowered {@link AgentTextRequest}, and the actor's own `signal`/`system`/`self`/`emit`. */
|