@statelyai/agent 2.0.0-alpha.29 → 2.0.0-alpha.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CHANGELOG.md +1733 -0
  2. package/dist/ai-sdk.cjs +9 -9
  3. package/dist/ai-sdk.d.cts +5 -5
  4. package/dist/ai-sdk.d.mts +5 -5
  5. package/dist/ai-sdk.mjs +4 -4
  6. package/dist/{decision-Bl_rKQnU.mjs → decision-DqO018Tp.mjs} +23 -10
  7. package/dist/{decision-oevZnkBe.cjs → decision-Iys2hzg3.cjs} +31 -18
  8. package/dist/{event-log-Dtb16p1p.cjs → event-log-Bdww2l1D.cjs} +104 -25
  9. package/dist/{event-log-GPZO9p7_.mjs → event-log-DE430ZCa.mjs} +87 -26
  10. package/dist/{event-log-store-bCdskPNS.cjs → event-log-store-BWMLi6oh.cjs} +1 -1
  11. package/dist/{event-log-store-yalq8C77.mjs → event-log-store-CCWdTPEP.mjs} +1 -1
  12. package/dist/{event-log-store-CN9ygggF.d.cts → event-log-store-DTf_OzB-.d.cts} +1 -1
  13. package/dist/{event-log-store-DS836wch.d.mts → event-log-store-RziIobdW.d.mts} +1 -1
  14. package/dist/index.cjs +136 -23
  15. package/dist/index.d.cts +58 -11
  16. package/dist/index.d.mts +58 -11
  17. package/dist/index.mjs +133 -21
  18. package/dist/log.cjs +2 -2
  19. package/dist/log.d.cts +1 -1
  20. package/dist/log.d.mts +1 -1
  21. package/dist/log.mjs +2 -2
  22. package/dist/machines.cjs +1 -1
  23. package/dist/machines.mjs +1 -1
  24. package/dist/{model-source-C7FFP2Sj.mjs → model-source-CXsSZPq0.mjs} +1 -2
  25. package/dist/{model-source-DjJPjGSP.cjs → model-source-DQ7KgJaT.cjs} +4 -5
  26. package/dist/openai.cjs +3 -3
  27. package/dist/openai.d.cts +2 -2
  28. package/dist/openai.d.mts +2 -2
  29. package/dist/openai.mjs +3 -3
  30. package/dist/otel.d.cts +1 -1
  31. package/dist/otel.d.mts +1 -1
  32. package/dist/{run-agent-C9ubX8Tx.d.cts → run-agent-B5opVUxx.d.cts} +25 -6
  33. package/dist/{run-agent-CxSyZmIE.d.mts → run-agent-D4MwS5GY.d.mts} +25 -6
  34. package/dist/{run-agent-CuQT1xSS.mjs → run-agent-DWZ1uyBJ.mjs} +100 -37
  35. package/dist/{run-agent-cToZ3K42.cjs → run-agent-tmk58M0x.cjs} +100 -37
  36. package/dist/{setup-agent-DniLvDu7.mjs → setup-agent-BaffhCcM.mjs} +38 -3
  37. package/dist/{setup-agent-tsc3vm5I.d.mts → setup-agent-CPyg2ic7.d.mts} +11 -3
  38. package/dist/{setup-agent-DTF3NQg3.cjs → setup-agent-D0L8Anl_.cjs} +38 -3
  39. package/dist/{setup-agent-DlbgwsIJ.d.cts → setup-agent-yFFVXf5s.d.cts} +11 -3
  40. package/dist/tanstack-ai.cjs +3 -3
  41. package/dist/tanstack-ai.d.cts +2 -2
  42. package/dist/tanstack-ai.d.mts +2 -2
  43. package/dist/tanstack-ai.mjs +3 -3
  44. package/dist/testing.cjs +176 -26
  45. package/dist/testing.d.cts +128 -10
  46. package/dist/testing.d.mts +128 -10
  47. package/dist/testing.mjs +168 -20
  48. package/dist/{text-logic-BDbGjYMh.d.mts → text-logic-BwdrDpO9.d.mts} +6 -2
  49. package/dist/{text-logic-9fv1i9aK.d.cts → text-logic-j9hShB7d.d.cts} +6 -2
  50. package/dist/{usage-D8UphgEA.d.mts → usage-BYqv7VBw.d.cts} +1 -1
  51. package/dist/{usage-R1NTmLxY.d.cts → usage-Bl4nK8D-.d.mts} +1 -1
  52. package/dist/validate.cjs +3 -3
  53. package/dist/validate.d.cts +2 -2
  54. package/dist/validate.d.mts +2 -2
  55. package/dist/validate.mjs +3 -3
  56. package/dist/{verify-B5qGC5WN.mjs → verify-BH5e0XLK.mjs} +55 -5
  57. package/dist/{verify-DYH_2VzU.d.cts → verify-CPKDPMwY.d.cts} +14 -6
  58. package/dist/{verify-Cqghu4gz.cjs → verify-CS_xxvVU.cjs} +57 -7
  59. package/dist/{verify-CBuYIpsa.d.mts → verify-tkymWz6X.d.mts} +14 -6
  60. package/package.json +34 -4
  61. package/readme.md +72 -42
  62. package/skills/add-evals/SKILL.md +144 -0
  63. package/skills/add-traces/SKILL.md +147 -0
  64. package/skills/generate-machine/SKILL.md +6 -6
  65. package/skills/graph-engineering/SKILL.md +33 -0
  66. package/skills/improve-machine/SKILL.md +73 -21
  67. package/skills/improve-machine/reference.md +12 -7
  68. package/skills/loop-to-machine/SKILL.md +210 -0
  69. package/skills/loop-to-machine/policy.md +154 -0
@@ -1,6 +1,6 @@
1
- const require_event_log = require("./event-log-Dtb16p1p.cjs");
2
- const require_decision = require("./decision-oevZnkBe.cjs");
3
- const require_event_log_store = require("./event-log-store-bCdskPNS.cjs");
1
+ const require_event_log = require("./event-log-Bdww2l1D.cjs");
2
+ const require_decision = require("./decision-Iys2hzg3.cjs");
3
+ const require_event_log_store = require("./event-log-store-BWMLi6oh.cjs");
4
4
  let xstate = require("xstate");
5
5
  let xstate_durable = require("xstate/durable");
6
6
  //#region src/run-agent.ts
@@ -290,6 +290,13 @@ function unrebindableChildRequestError(childPath, stateName, requestSrc, kind) {
290
290
  function declaresUsageTransition(snapshot) {
291
291
  return (0, xstate.getNextTransitions)(snapshot).some((transition) => transition.eventType === "@agent.usage" || transition.eventType === "*");
292
292
  }
293
+ function observe(name, call) {
294
+ try {
295
+ call();
296
+ } catch (error) {
297
+ console.error(`@statelyai/agent: ${name} threw; the run continues.`, error);
298
+ }
299
+ }
293
300
  /**
294
301
  * Builds the ONE place a trace payload is emitted: it hands the payload to the
295
302
  * envelope-stamping trace sink and, from that same payload, invokes the sugar
@@ -306,21 +313,21 @@ function createTraceDispatch(sinks) {
306
313
  return (payload, self) => {
307
314
  switch (payload.type) {
308
315
  case "stream.chunk":
309
- sinks.onTrace?.(payload, self);
310
- sinks.onChunk?.(payload.chunk, { request: payload.request });
316
+ observe("onTrace", () => sinks.onTrace?.(payload, self));
317
+ observe("onChunk", () => sinks.onChunk?.(payload.chunk, { request: payload.request }));
311
318
  return;
312
319
  case "request.end":
313
- sinks.onResult?.(payload.request, {
320
+ observe("onResult", () => sinks.onResult?.(payload.request, {
314
321
  result: payload.output,
315
322
  raw: payload.raw
316
- });
317
- sinks.onTrace?.(payload, self);
323
+ }));
324
+ observe("onTrace", () => sinks.onTrace?.(payload, self));
318
325
  return;
319
326
  case "machine.transition":
320
- sinks.onTrace?.(payload, self);
321
- sinks.onTransition?.(payload.snapshot, payload.event);
327
+ observe("onTrace", () => sinks.onTrace?.(payload, self));
328
+ observe("onTransition", () => sinks.onTransition?.(payload.snapshot, payload.event));
322
329
  return;
323
- default: sinks.onTrace?.(payload, self);
330
+ default: observe("onTrace", () => sinks.onTrace?.(payload, self));
324
331
  }
325
332
  };
326
333
  }
@@ -509,6 +516,11 @@ function bindDecisionLogic(logic, runCtx) {
509
516
  schemas: runCtx.schemas,
510
517
  eventTypes: declaredEventTypes
511
518
  }) : [];
519
+ const agentCan = (event) => {
520
+ if (!actorRef) return true;
521
+ const snapshot = actorRef.getSnapshot();
522
+ return !require_decision.getHumanEventTypes(snapshot).has(event.type) && snapshot.can(event);
523
+ };
512
524
  const lowered = logic.request(input);
513
525
  const request = {
514
526
  ...lowered,
@@ -521,7 +533,7 @@ function bindDecisionLogic(logic, runCtx) {
521
533
  const options = require_decision.acceptedDecisionOptions(request, (event) => {
522
534
  let accepted;
523
535
  try {
524
- accepted = actorRef ? actorRef.getSnapshot().can(event) : true;
536
+ accepted = agentCan(event);
525
537
  } catch {
526
538
  accepted = false;
527
539
  }
@@ -532,6 +544,10 @@ function bindDecisionLogic(logic, runCtx) {
532
544
  request.options = options;
533
545
  request.withheld = withheld;
534
546
  }
547
+ if (actorRef) {
548
+ const humanEventTypes = require_decision.getHumanEventTypes(actorRef.getSnapshot());
549
+ request.events = events.filter((event) => !humanEventTypes.has(event.type));
550
+ }
535
551
  if (options?.length === 0) {
536
552
  const error = new require_decision.AgentDecisionExhaustedError([]);
537
553
  error.message = `Decision '${request.name}' has no offered option the current snapshot accepts; no model call was made.`;
@@ -554,7 +570,7 @@ function bindDecisionLogic(logic, runCtx) {
554
570
  } }, {
555
571
  maxRetries: lowered.maxRetries ?? logic.maxRetries,
556
572
  signal,
557
- canTake: (event) => actorRef ? actorRef.getSnapshot().can(event) : true
573
+ canTake: agentCan
558
574
  });
559
575
  if (priorAttempts.length > 0) runCtx.noteDecision?.(chosen, priorAttempts);
560
576
  actorRef?.send(chosen);
@@ -918,6 +934,8 @@ function createAgentRuntime(machine, options = {}) {
918
934
  let traceSeq = 0;
919
935
  const machineId = machine.config.id ?? machine.id ?? "(machine)";
920
936
  const machineVersion = require_event_log.resolveMachineVersion(machine);
937
+ if (options.metadata !== void 0) require_event_log.assertJsonSerializable(options.metadata, "metadata");
938
+ const initMetadata = options.metadata === void 0 ? void 0 : structuredClone(options.metadata);
921
939
  const onTrace = createTraceDispatch({
922
940
  onTrace: (payload) => {
923
941
  options.onTrace?.({
@@ -998,13 +1016,32 @@ function createAgentRuntime(machine, options = {}) {
998
1016
  let loggingEnabled = true;
999
1017
  const attemptsByEvent = /* @__PURE__ */ new WeakMap();
1000
1018
  let logFold;
1019
+ const stopLogging = (error) => {
1020
+ if (!loggingEnabled) return;
1021
+ loggingEnabled = false;
1022
+ if (store !== void 0) {
1023
+ journalError ??= error;
1024
+ stopRun({
1025
+ cause: "journal",
1026
+ error
1027
+ });
1028
+ return;
1029
+ }
1030
+ console.warn(`@statelyai/agent: this run's log stopped at entry ${logEntries.length}, so result.events is incomplete: ${error instanceof Error ? error.message : String(error)}. Pass input and events that JSON can hold.`);
1031
+ };
1001
1032
  const appendLogEntry = (event, attempts) => {
1002
1033
  if (!loggingEnabled) return;
1003
- const entry = require_event_log.createReplayEntry(logMachine, logEntries, event, {
1004
- machineVersion,
1005
- verification: false,
1006
- ...attempts !== void 0 ? { attempts } : {}
1007
- });
1034
+ let entry;
1035
+ try {
1036
+ entry = require_event_log.createReplayEntry(logMachine, logEntries, event, {
1037
+ machineVersion,
1038
+ verification: false,
1039
+ ...attempts !== void 0 ? { attempts } : {}
1040
+ });
1041
+ } catch (error) {
1042
+ stopLogging(error);
1043
+ return;
1044
+ }
1008
1045
  if (verificationEnabled && logFold !== null) try {
1009
1046
  logFold ??= require_event_log.foldLog(logMachine, logEntries, {
1010
1047
  machineVersion,
@@ -1016,7 +1053,7 @@ function createAgentRuntime(machine, options = {}) {
1016
1053
  }
1017
1054
  logEntries.push(entry);
1018
1055
  journalEntry(entry);
1019
- options.onEvent?.(entry);
1056
+ observe("onEvent", () => options.onEvent?.(entry));
1020
1057
  return entry;
1021
1058
  };
1022
1059
  const recordUsage = (usage, source = {}) => {
@@ -1191,8 +1228,8 @@ function createAgentRuntime(machine, options = {}) {
1191
1228
  event
1192
1229
  });
1193
1230
  const on = options.on ?? {};
1194
- on[event.type]?.(event);
1195
- if (event.type !== "*") on["*"]?.(event);
1231
+ observe(`on['${event.type}']`, () => on[event.type]?.(event));
1232
+ if (event.type !== "*") observe("on['*']", () => on["*"]?.(event));
1196
1233
  };
1197
1234
  const inspect = options.inspect === void 0 ? void 0 : (event) => {
1198
1235
  if (typeof options.inspect === "function") options.inspect(event);
@@ -1246,14 +1283,15 @@ function createAgentRuntime(machine, options = {}) {
1246
1283
  }
1247
1284
  }, inspect ? { inspect } : void 0);
1248
1285
  const runErrorCause = (error) => budgetExceeded ? "max-model-calls" : wrapsDecisionExhausted(error) ? "decision-exhausted" : "machine";
1249
- const commit = (snapshot, event) => {
1286
+ const commit = (snapshot, event, ignored = false) => {
1250
1287
  const from = { value: (current ?? snapshot).value };
1251
1288
  current = snapshot;
1252
1289
  onTrace({
1253
1290
  type: "machine.transition",
1254
1291
  from,
1255
1292
  snapshot,
1256
- event
1293
+ event,
1294
+ ...ignored ? { ignored: true } : {}
1257
1295
  });
1258
1296
  };
1259
1297
  /** True for a child completion/failure whose child is no longer running under the current state. */
@@ -1267,14 +1305,23 @@ function createAgentRuntime(machine, options = {}) {
1267
1305
  if (started) throw new require_event_log.AgentError("runtime-started", "createAgentRuntime: `start` was already called.");
1268
1306
  started = true;
1269
1307
  let resumeEvents = init.events;
1308
+ let resumedFromStore = false;
1270
1309
  if (store !== void 0) {
1271
1310
  const storedThread = await store.read(threadId);
1272
1311
  if (resumeEvents !== void 0) {
1273
1312
  if (storedThread.length !== resumeEvents.length) throw new require_event_log_store.AgentEventLogConflictError(threadId, resumeEvents.length, storedThread.length);
1274
1313
  assertThreadMatchesEvents(threadId, storedThread, resumeEvents);
1275
- } else if (storedThread.length > 0) resumeEvents = storedThread;
1314
+ resumedFromStore = storedThread.length > 0;
1315
+ } else if (storedThread.length > 0) {
1316
+ resumeEvents = storedThread;
1317
+ resumedFromStore = true;
1318
+ }
1276
1319
  }
1277
1320
  const resolvedInput = resolveMachineInput(machine, init.input);
1321
+ const threadInit = resumeEvents?.[0]?.event;
1322
+ if (resumedFromStore && init.input !== void 0 && threadInit !== void 0 && Object.hasOwn(threadInit, "input")) {
1323
+ if (require_event_log.canonicalJson(threadInit.input) !== require_event_log.canonicalJson(resolvedInput)) throw new require_event_log.AgentError("thread-input-mismatch", `createAgentRuntime: thread '${threadId}' was started with different input. A thread that already has entries is resumed, not restarted; give a new run a new threadId.`);
1324
+ }
1278
1325
  let effectiveSnapshot = init.snapshot;
1279
1326
  let seedInitEntry;
1280
1327
  const restoredPersistedSnapshot = () => {
@@ -1292,18 +1339,25 @@ function createAgentRuntime(machine, options = {}) {
1292
1339
  * run WITHOUT a log rather than failing it.
1293
1340
  */
1294
1341
  const appendInitEntry = (candidates, metadata) => {
1295
- for (const candidate of candidates) for (const verification of verificationEnabled ? [true, false] : [false]) try {
1296
- const entry = require_event_log.initEntry(logMachine, candidate, {
1297
- machineVersion,
1298
- verification,
1299
- metadata
1300
- });
1342
+ let lastError;
1343
+ for (const candidate of candidates) for (const verification of verificationEnabled ? [true, false] : [false]) {
1344
+ let entry;
1345
+ try {
1346
+ entry = require_event_log.initEntry(logMachine, candidate, {
1347
+ machineVersion,
1348
+ verification,
1349
+ metadata
1350
+ });
1351
+ } catch (error) {
1352
+ lastError = error;
1353
+ continue;
1354
+ }
1301
1355
  logEntries.push(entry);
1302
1356
  journalEntry(entry);
1303
- options.onEvent?.(entry);
1357
+ observe("onEvent", () => options.onEvent?.(entry));
1304
1358
  return;
1305
- } catch {}
1306
- loggingEnabled = false;
1359
+ }
1360
+ stopLogging(lastError);
1307
1361
  };
1308
1362
  /** Init forms for a snapshot resume, most faithful first. */
1309
1363
  const snapshotInitCandidates = () => {
@@ -1370,16 +1424,23 @@ function createAgentRuntime(machine, options = {}) {
1370
1424
  logIndex: resumeEvents.length
1371
1425
  };
1372
1426
  seedInitEntry = () => appendInitEntry(snapshotInitCandidates(), {
1427
+ ...initMetadata,
1373
1428
  ...logExecutionId !== void 0 ? { executionId: logExecutionId } : {},
1374
1429
  migratedFrom
1375
1430
  });
1376
1431
  }
1377
1432
  } else if (init.snapshot !== void 0) {
1378
1433
  logExecutionId = crypto.randomUUID();
1379
- seedInitEntry = () => appendInitEntry(snapshotInitCandidates(), { executionId: logExecutionId });
1434
+ seedInitEntry = () => appendInitEntry(snapshotInitCandidates(), {
1435
+ ...initMetadata,
1436
+ executionId: logExecutionId
1437
+ });
1380
1438
  } else {
1381
1439
  logExecutionId = crypto.randomUUID();
1382
- seedInitEntry = () => appendInitEntry([resolvedInput !== void 0 ? { input: resolvedInput } : {}], { executionId: logExecutionId });
1440
+ seedInitEntry = () => appendInitEntry([resolvedInput !== void 0 ? { input: resolvedInput } : {}], {
1441
+ ...initMetadata,
1442
+ executionId: logExecutionId
1443
+ });
1383
1444
  }
1384
1445
  const resumedHistory = [...logEntries];
1385
1446
  const siteCallCounts = /* @__PURE__ */ new Map();
@@ -1447,9 +1508,11 @@ function createAgentRuntime(machine, options = {}) {
1447
1508
  const attempts = transitionOptions?.attempts ?? attemptsByEvent.get(event);
1448
1509
  if (transitionOptions?.attempts !== void 0) require_event_log.assertJsonSerializable(transitionOptions.attempts, "attempts");
1449
1510
  const [next, effects] = execution.transition(state, event);
1450
- if (!fromMailbox.has(event) && next === state && effects.length === 0) ignoredEvent = event;
1511
+ const ignored = !fromMailbox.has(event) && next === state && effects.length === 0;
1512
+ if (ignored) ignoredEvent = event;
1451
1513
  appendLogEntry(event, attempts);
1452
- commit(next, event);
1514
+ if (stopReason !== void 0) return [state, []];
1515
+ commit(next, event, ignored);
1453
1516
  return [next, effects];
1454
1517
  },
1455
1518
  async execute(effects) {
@@ -1,5 +1,5 @@
1
- import { A as createTextLogic, C as AGENT_USAGE_EVENT_TYPE, G as missingActor, H as getAgentExecutionOptions, K as setAgentExecutionOptions, T as DECIDE_ACTOR, k as builtinTextActors, ot as validateSchemaSync } from "./event-log-GPZO9p7_.mjs";
2
- import { r as createDecideActor } from "./decision-Bl_rKQnU.mjs";
1
+ import { A as createTextLogic, C as AGENT_USAGE_EVENT_TYPE, G as missingActor, H as getAgentExecutionOptions, K as setAgentExecutionOptions, T as DECIDE_ACTOR, ct as isPlainObject, k as builtinTextActors, ot as validateSchemaSync, ut as AgentError } from "./event-log-DE430ZCa.mjs";
2
+ import { r as createDecideActor } from "./decision-DqO018Tp.mjs";
3
3
  import { machineFromJSON, setup } from "xstate";
4
4
  //#region src/workflow-config.ts
5
5
  /**
@@ -387,7 +387,27 @@ function withAgentUsageEventSchema(events) {
387
387
  };
388
388
  }
389
389
  function normalizeEventSchemas(events) {
390
- return Object.fromEntries(Object.entries(events).map(([type, schema]) => [type, schema && typeof schema === "object" && "~standard" in schema ? schema : emptyEventSchema]));
390
+ return Object.fromEntries(Object.entries(events).map(([type, schema]) => {
391
+ if (schema && typeof schema === "object" && "~standard" in schema) return [type, schema];
392
+ if (!(isPlainObject(schema) && Object.keys(schema).length === 0)) assertStandardSchema(schema, `events.${type}`);
393
+ return [type, emptyEventSchema];
394
+ }));
395
+ }
396
+ /**
397
+ * Throws for a declared schema without the Standard Schema `~standard`
398
+ * property. Such a schema would otherwise be skipped, so values it should
399
+ * reject would pass unchecked. Zod 3.23 and earlier are the usual cause.
400
+ */
401
+ function assertStandardSchema(schema, where) {
402
+ if (schema === void 0 || typeof schema === "object" && schema !== null && "~standard" in schema) return;
403
+ throw new AgentError("invalid-schema", `setupAgent: '${where}' is not a Standard Schema (it has no '~standard' property), so it cannot be used to validate. Use zod 4 or zod 3.24 and later, Valibot, ArkType, or any other Standard Schema library; zod 3.23 and earlier do not implement it.`);
404
+ }
405
+ function assertStateSchemasAreStandard(states, path = []) {
406
+ for (const [key, state] of Object.entries(states ?? {})) {
407
+ const statePath = [...path, key];
408
+ for (const [name, schema] of Object.entries(state?.schemas ?? {})) assertStandardSchema(schema, `states.${statePath.join(".states.")}.schemas.${name}`);
409
+ assertStateSchemasAreStandard(state?.states, statePath);
410
+ }
391
411
  }
392
412
  /**
393
413
  * Builds a machine's {@link AgentSchemaPack} from a partial schema
@@ -454,8 +474,23 @@ function createAgentSchemas(schemas) {
454
474
  */
455
475
  function setupAgent(config) {
456
476
  const schemas = normalizeAgentSchemas(config);
477
+ for (const key of [
478
+ "context",
479
+ "input",
480
+ "output",
481
+ "meta"
482
+ ]) assertStandardSchema(schemas[key], key);
483
+ for (const [type, schema] of Object.entries(schemas.emitted ?? {})) assertStandardSchema(schema, `emitted.${type}`);
484
+ assertStateSchemasAreStandard(config.states);
457
485
  const requestActors = createRequestActors(config.requests ?? {});
458
486
  const actors = createAgentActors(config.actors, requestActors);
487
+ for (const [name, request] of Object.entries(config.requests ?? {})) {
488
+ const source = request;
489
+ if (source.prompt === void 0 && source.messages === void 0) throw new AgentError("invalid-request", `setupAgent: request '${name}' has neither \`prompt\` nor \`messages\`, so every call to it fails. A request whose executor builds its own model call still needs one: pass the conversation as \`messages: ({ input }) => input.messages\` (or a \`prompt\`) and read it in the executor.`);
490
+ const requestSchemas = request.schemas;
491
+ assertStandardSchema(requestSchemas?.input, `requests.${name}.schemas.input`);
492
+ assertStandardSchema(requestSchemas?.output, `requests.${name}.schemas.output`);
493
+ }
459
494
  const setupConfig = {
460
495
  schemas: {
461
496
  context: schemas.context,
@@ -1,6 +1,6 @@
1
1
  import { _ as StandardSchemaV1, d as EventUnion, g as NormalizedEventSchemas, h as InferOutput, i as AgentToolChoice, m as InferInput, s as AgentTools, t as AgentEventSchemaInputMap, w as WithAgentInputSchema } from "./types-Dp5_Ru4R.mjs";
2
- import { J as AgentSchemas, Y as EventFromSnapshot, _ as TextLogic, a as AgentModelRef, d as AgentRequestMode, h as BuiltinAgentActors, i as AgentModelMap, v as TextLogicConfig } from "./text-logic-BDbGjYMh.mjs";
3
- import { n as AgentUsageEvent, t as AGENT_USAGE_EVENT_TYPE } from "./usage-D8UphgEA.mjs";
2
+ import { J as AgentSchemas, Y as EventFromSnapshot, _ as TextLogic, a as AgentModelRef, d as AgentRequestMode, h as BuiltinAgentActors, i as AgentModelMap, v as TextLogicConfig } from "./text-logic-BwdrDpO9.mjs";
3
+ import { n as AgentUsageEvent, t as AGENT_USAGE_EVENT_TYPE } from "./usage-Bl4nK8D-.mjs";
4
4
  import { AnyActorLogic, AnyMachineSnapshot, AnySetupConfig, AnyStateMachine, AsyncActorLogic, EventObject, MachineContext, MetaObject, NonReducibleUnknown, SetupReturnFromConfig, SetupStateSchema } from "xstate";
5
5
  //#region src/interaction.d.ts
6
6
  interface AgentInteractionEvent<TType extends string = string> {
@@ -84,13 +84,21 @@ interface AgentInteractionDescriptor<TEvent extends string = string> {
84
84
  */
85
85
  interface AgentInteractionMeta<TEvent extends string = string> {
86
86
  interaction?: AgentInteractionDescriptor<TEvent>;
87
+ /**
88
+ * On a transition: `"human"` means a person sends its event, never a model.
89
+ * Model-facing decisions (`agent.decide`, `decideNext`) withhold an event a
90
+ * state handles through a transition tagged this way. Read from object
91
+ * transitions only; a transition written as a function cannot be tagged.
92
+ */
93
+ actor?: "human";
87
94
  }
88
95
  /**
89
96
  * A {@link StandardSchemaV1} for the state metadata {@link getInteraction}
90
97
  * reads: an object whose optional `interaction` declares a `label` (a string
91
98
  * with `{context.path}` interpolation, or a function of the context), an
92
99
  * `events` map of choices, payload `choices` (an array, or a context path to
93
- * one), and a `textEvent` (a type, or `{ type, field }`) for free-text answers. This is
100
+ * one), and a `textEvent` (a type, or `{ type, field }`) for free-text answers; and
101
+ * an optional `actor: "human"`, which tags a transition as sent by a person. This is
94
102
  * the default `meta` type `setupAgent` gives a machine; pass it to
95
103
  * `createAgentSchemas({ meta: interactionMetaSchema })` only when building a
96
104
  * schema pack by hand.
@@ -1,5 +1,5 @@
1
- const require_event_log = require("./event-log-Dtb16p1p.cjs");
2
- const require_decision = require("./decision-oevZnkBe.cjs");
1
+ const require_event_log = require("./event-log-Bdww2l1D.cjs");
2
+ const require_decision = require("./decision-Iys2hzg3.cjs");
3
3
  let xstate = require("xstate");
4
4
  //#region src/workflow-config.ts
5
5
  /**
@@ -387,7 +387,27 @@ function withAgentUsageEventSchema(events) {
387
387
  };
388
388
  }
389
389
  function normalizeEventSchemas(events) {
390
- return Object.fromEntries(Object.entries(events).map(([type, schema]) => [type, schema && typeof schema === "object" && "~standard" in schema ? schema : emptyEventSchema]));
390
+ return Object.fromEntries(Object.entries(events).map(([type, schema]) => {
391
+ if (schema && typeof schema === "object" && "~standard" in schema) return [type, schema];
392
+ if (!(require_event_log.isPlainObject(schema) && Object.keys(schema).length === 0)) assertStandardSchema(schema, `events.${type}`);
393
+ return [type, emptyEventSchema];
394
+ }));
395
+ }
396
+ /**
397
+ * Throws for a declared schema without the Standard Schema `~standard`
398
+ * property. Such a schema would otherwise be skipped, so values it should
399
+ * reject would pass unchecked. Zod 3.23 and earlier are the usual cause.
400
+ */
401
+ function assertStandardSchema(schema, where) {
402
+ if (schema === void 0 || typeof schema === "object" && schema !== null && "~standard" in schema) return;
403
+ throw new require_event_log.AgentError("invalid-schema", `setupAgent: '${where}' is not a Standard Schema (it has no '~standard' property), so it cannot be used to validate. Use zod 4 or zod 3.24 and later, Valibot, ArkType, or any other Standard Schema library; zod 3.23 and earlier do not implement it.`);
404
+ }
405
+ function assertStateSchemasAreStandard(states, path = []) {
406
+ for (const [key, state] of Object.entries(states ?? {})) {
407
+ const statePath = [...path, key];
408
+ for (const [name, schema] of Object.entries(state?.schemas ?? {})) assertStandardSchema(schema, `states.${statePath.join(".states.")}.schemas.${name}`);
409
+ assertStateSchemasAreStandard(state?.states, statePath);
410
+ }
391
411
  }
392
412
  /**
393
413
  * Builds a machine's {@link AgentSchemaPack} from a partial schema
@@ -454,8 +474,23 @@ function createAgentSchemas(schemas) {
454
474
  */
455
475
  function setupAgent(config) {
456
476
  const schemas = normalizeAgentSchemas(config);
477
+ for (const key of [
478
+ "context",
479
+ "input",
480
+ "output",
481
+ "meta"
482
+ ]) assertStandardSchema(schemas[key], key);
483
+ for (const [type, schema] of Object.entries(schemas.emitted ?? {})) assertStandardSchema(schema, `emitted.${type}`);
484
+ assertStateSchemasAreStandard(config.states);
457
485
  const requestActors = createRequestActors(config.requests ?? {});
458
486
  const actors = createAgentActors(config.actors, requestActors);
487
+ for (const [name, request] of Object.entries(config.requests ?? {})) {
488
+ const source = request;
489
+ if (source.prompt === void 0 && source.messages === void 0) throw new require_event_log.AgentError("invalid-request", `setupAgent: request '${name}' has neither \`prompt\` nor \`messages\`, so every call to it fails. A request whose executor builds its own model call still needs one: pass the conversation as \`messages: ({ input }) => input.messages\` (or a \`prompt\`) and read it in the executor.`);
490
+ const requestSchemas = request.schemas;
491
+ assertStandardSchema(requestSchemas?.input, `requests.${name}.schemas.input`);
492
+ assertStandardSchema(requestSchemas?.output, `requests.${name}.schemas.output`);
493
+ }
459
494
  const setupConfig = {
460
495
  schemas: {
461
496
  context: schemas.context,
@@ -1,6 +1,6 @@
1
1
  import { _ as StandardSchemaV1, d as EventUnion, g as NormalizedEventSchemas, h as InferOutput, i as AgentToolChoice, m as InferInput, s as AgentTools, t as AgentEventSchemaInputMap, w as WithAgentInputSchema } from "./types-Dp5_Ru4R.cjs";
2
- import { J as AgentSchemas, Y as EventFromSnapshot, _ as TextLogic, a as AgentModelRef, d as AgentRequestMode, h as BuiltinAgentActors, i as AgentModelMap, v as TextLogicConfig } from "./text-logic-9fv1i9aK.cjs";
3
- import { n as AgentUsageEvent, t as AGENT_USAGE_EVENT_TYPE } from "./usage-R1NTmLxY.cjs";
2
+ import { J as AgentSchemas, Y as EventFromSnapshot, _ as TextLogic, a as AgentModelRef, d as AgentRequestMode, h as BuiltinAgentActors, i as AgentModelMap, v as TextLogicConfig } from "./text-logic-j9hShB7d.cjs";
3
+ import { n as AgentUsageEvent, t as AGENT_USAGE_EVENT_TYPE } from "./usage-BYqv7VBw.cjs";
4
4
  import { AnyActorLogic, AnyMachineSnapshot, AnySetupConfig, AnyStateMachine, AsyncActorLogic, EventObject, MachineContext, MetaObject, NonReducibleUnknown, SetupReturnFromConfig, SetupStateSchema } from "xstate";
5
5
  //#region src/interaction.d.ts
6
6
  interface AgentInteractionEvent<TType extends string = string> {
@@ -84,13 +84,21 @@ interface AgentInteractionDescriptor<TEvent extends string = string> {
84
84
  */
85
85
  interface AgentInteractionMeta<TEvent extends string = string> {
86
86
  interaction?: AgentInteractionDescriptor<TEvent>;
87
+ /**
88
+ * On a transition: `"human"` means a person sends its event, never a model.
89
+ * Model-facing decisions (`agent.decide`, `decideNext`) withhold an event a
90
+ * state handles through a transition tagged this way. Read from object
91
+ * transitions only; a transition written as a function cannot be tagged.
92
+ */
93
+ actor?: "human";
87
94
  }
88
95
  /**
89
96
  * A {@link StandardSchemaV1} for the state metadata {@link getInteraction}
90
97
  * reads: an object whose optional `interaction` declares a `label` (a string
91
98
  * with `{context.path}` interpolation, or a function of the context), an
92
99
  * `events` map of choices, payload `choices` (an array, or a context path to
93
- * one), and a `textEvent` (a type, or `{ type, field }`) for free-text answers. This is
100
+ * one), and a `textEvent` (a type, or `{ type, field }`) for free-text answers; and
101
+ * an optional `actor: "human"`, which tags a transition as sent by a person. This is
94
102
  * the default `meta` type `setupAgent` gives a machine; pass it to
95
103
  * `createAgentSchemas({ meta: interactionMetaSchema })` only when building a
96
104
  * schema pack by hand.
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_event_log = require("./event-log-Dtb16p1p.cjs");
3
- const require_decision = require("./decision-oevZnkBe.cjs");
4
- const require_model_source = require("./model-source-DjJPjGSP.cjs");
2
+ const require_event_log = require("./event-log-Bdww2l1D.cjs");
3
+ const require_decision = require("./decision-Iys2hzg3.cjs");
4
+ const require_model_source = require("./model-source-DQ7KgJaT.cjs");
5
5
  let _tanstack_ai = require("@tanstack/ai");
6
6
  //#region src/tanstack-ai/index.ts
7
7
  /**
@@ -1,5 +1,5 @@
1
1
  import { i as AgentToolChoice, n as AgentMessage, s as AgentTools, u as ChosenEvent } from "./types-Dp5_Ru4R.cjs";
2
- import { N as AgentDecisionRequest, W as AgentEventDescriptor, c as AgentRequestExecutorInfo, f as AgentTextRequest, r as AgentFinishReason, t as AgentCallUsage } from "./text-logic-9fv1i9aK.cjs";
2
+ import { N as AgentDecisionRequest, W as AgentEventDescriptor, c as AgentRequestExecutorInfo, f as AgentTextRequest, r as AgentFinishReason, t as AgentCallUsage } from "./text-logic-j9hShB7d.cjs";
3
3
  import { AnyStateMachine } from "xstate";
4
4
  import { AnyTextAdapter, ModelMessage, StreamChunk, TokenUsage, Tool } from "@tanstack/ai";
5
5
  import { TextActivityOptions } from "@tanstack/ai/adapters";
@@ -195,7 +195,7 @@ export declare function toTextAdapter(entry: TanStackAiModelEntry): AnyTextAdapt
195
195
  * ```ts
196
196
  * import { openaiText } from '@tanstack/ai-openai';
197
197
  *
198
- * const executors = createTanStackAiExecutors({ models: { quick: openaiText('gpt-5.4-mini') } });
198
+ * const executors = createTanStackAiExecutors({ models: { quick: openaiText('gpt-6-luna') } });
199
199
  * const result = await runToQuiescence(createAgentRuntime(machine, { executors }), { input });
200
200
  * ```
201
201
  */
@@ -1,5 +1,5 @@
1
1
  import { i as AgentToolChoice, n as AgentMessage, s as AgentTools, u as ChosenEvent } from "./types-Dp5_Ru4R.mjs";
2
- import { N as AgentDecisionRequest, W as AgentEventDescriptor, c as AgentRequestExecutorInfo, f as AgentTextRequest, r as AgentFinishReason, t as AgentCallUsage } from "./text-logic-BDbGjYMh.mjs";
2
+ import { N as AgentDecisionRequest, W as AgentEventDescriptor, c as AgentRequestExecutorInfo, f as AgentTextRequest, r as AgentFinishReason, t as AgentCallUsage } from "./text-logic-BwdrDpO9.mjs";
3
3
  import { AnyStateMachine } from "xstate";
4
4
  import { AnyTextAdapter, ModelMessage, StreamChunk, TokenUsage, Tool } from "@tanstack/ai";
5
5
  import { TextActivityOptions } from "@tanstack/ai/adapters";
@@ -195,7 +195,7 @@ export declare function toTextAdapter(entry: TanStackAiModelEntry): AnyTextAdapt
195
195
  * ```ts
196
196
  * import { openaiText } from '@tanstack/ai-openai';
197
197
  *
198
- * const executors = createTanStackAiExecutors({ models: { quick: openaiText('gpt-5.4-mini') } });
198
+ * const executors = createTanStackAiExecutors({ models: { quick: openaiText('gpt-6-luna') } });
199
199
  * const result = await runToQuiescence(createAgentRuntime(machine, { executors }), { input });
200
200
  * ```
201
201
  */
@@ -1,6 +1,6 @@
1
- import { L as parseProviderOutput, R as providerOutputSchema, X as getJsonSchemaSync, Y as getJsonSchema, ct as AgentTruncatedError, j as getAgentOutputMode, tt as isStandardSchema, w as AGENT_USAGE_TOKEN_FIELDS } from "./event-log-GPZO9p7_.mjs";
2
- import { c as renderDecisionAttempts } from "./decision-Bl_rKQnU.mjs";
3
- import { t as resolveModelSource } from "./model-source-C7FFP2Sj.mjs";
1
+ import { L as parseProviderOutput, R as providerOutputSchema, X as getJsonSchemaSync, Y as getJsonSchema, dt as AgentTruncatedError, j as getAgentOutputMode, tt as isStandardSchema, w as AGENT_USAGE_TOKEN_FIELDS } from "./event-log-DE430ZCa.mjs";
2
+ import { c as renderDecisionAttempts } from "./decision-DqO018Tp.mjs";
3
+ import { t as resolveModelSource } from "./model-source-CXsSZPq0.mjs";
4
4
  import { chat, maxIterations } from "@tanstack/ai";
5
5
  //#region src/tanstack-ai/index.ts
6
6
  /**