@statelyai/agent 2.0.0-alpha.30 → 2.0.0-alpha.32

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 (68) hide show
  1. package/CHANGELOG.md +1743 -0
  2. package/dist/ai-sdk.cjs +8 -8
  3. package/dist/ai-sdk.d.cts +1 -1
  4. package/dist/ai-sdk.d.mts +1 -1
  5. package/dist/ai-sdk.mjs +3 -3
  6. package/dist/{decision-CIb7ddIv.cjs → decision-BPdEaxPf.cjs} +30 -17
  7. package/dist/{decision-BHkvuImD.mjs → decision-CV7WiV5C.mjs} +22 -9
  8. package/dist/{event-log-BZRfBRd7.cjs → event-log-CKWeC7H-.cjs} +125 -27
  9. package/dist/{event-log-DJCMHek_.mjs → event-log-DAqsalT1.mjs} +108 -28
  10. package/dist/{event-log-store-DsP6GCRh.mjs → event-log-store-BGehvVTb.mjs} +2 -2
  11. package/dist/{event-log-store-CIIJohjj.d.mts → event-log-store-C2NjVlWU.d.mts} +13 -5
  12. package/dist/{event-log-store-DZR4IIWe.cjs → event-log-store-DKyE7JKr.cjs} +2 -2
  13. package/dist/{event-log-store-CLAC9q2Y.d.cts → event-log-store-s73r1Hxf.d.cts} +13 -5
  14. package/dist/index.cjs +129 -21
  15. package/dist/index.d.cts +59 -11
  16. package/dist/index.d.mts +59 -11
  17. package/dist/index.mjs +126 -19
  18. package/dist/log.cjs +40 -5
  19. package/dist/log.d.cts +1 -1
  20. package/dist/log.d.mts +1 -1
  21. package/dist/log.mjs +40 -5
  22. package/dist/machines.cjs +1 -1
  23. package/dist/machines.mjs +1 -1
  24. package/dist/{model-source-BCKg4qJ1.cjs → model-source-BQ97_l1-.cjs} +4 -5
  25. package/dist/{model-source-BaHwJ1wK.mjs → model-source-BilDEyqk.mjs} +1 -2
  26. package/dist/openai.cjs +2 -2
  27. package/dist/openai.d.cts +1 -1
  28. package/dist/openai.d.mts +1 -1
  29. package/dist/openai.mjs +2 -2
  30. package/dist/otel.d.cts +1 -1
  31. package/dist/otel.d.mts +1 -1
  32. package/dist/{run-agent-BpHqkaZw.mjs → run-agent-2UnSUhDb.mjs} +93 -37
  33. package/dist/{run-agent-CAVt5R-r.d.mts → run-agent-Atu-wEk7.d.mts} +17 -6
  34. package/dist/{run-agent-CTlMc3Jb.d.cts → run-agent-B5QhabdY.d.cts} +17 -6
  35. package/dist/{run-agent-ctLCvNgL.cjs → run-agent-Cg0xd3K-.cjs} +93 -37
  36. package/dist/{setup-agent-CLPCkXsu.d.cts → setup-agent-BiF1N3td.d.cts} +11 -3
  37. package/dist/{setup-agent-7rV_cujV.mjs → setup-agent-CmhB-U5P.mjs} +38 -3
  38. package/dist/{setup-agent-DoUk7EdC.cjs → setup-agent-CwUJyqKB.cjs} +38 -3
  39. package/dist/{setup-agent-CGELn1qZ.d.mts → setup-agent-J9f_Wu5T.d.mts} +11 -3
  40. package/dist/tanstack-ai.cjs +3 -3
  41. package/dist/tanstack-ai.d.cts +1 -1
  42. package/dist/tanstack-ai.d.mts +1 -1
  43. package/dist/tanstack-ai.mjs +3 -3
  44. package/dist/testing.cjs +73 -29
  45. package/dist/testing.d.cts +47 -10
  46. package/dist/testing.d.mts +47 -10
  47. package/dist/testing.mjs +65 -22
  48. package/dist/{text-logic-DmciuVUQ.d.cts → text-logic-CYP502VT.d.cts} +9 -3
  49. package/dist/{text-logic-BRYOPWvY.d.mts → text-logic-DuK9HIFM.d.mts} +9 -3
  50. package/dist/{usage-BkM3z02Y.d.mts → usage-D7JKAxLc.d.mts} +1 -1
  51. package/dist/{usage-Cm_ovz9V.d.cts → usage-DVw-646x.d.cts} +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-Cn86rT8l.d.mts → verify-BVz4cURF.d.mts} +14 -6
  57. package/dist/{verify-COFWyprJ.mjs → verify-CoCvR1eM.mjs} +55 -5
  58. package/dist/{verify-CVlsTZ-V.cjs → verify-D_llRCTr.cjs} +57 -7
  59. package/dist/{verify-Dzwd4Mvk.d.cts → verify-Dk3Vwnha.d.cts} +14 -6
  60. package/package.json +34 -4
  61. package/readme.md +70 -40
  62. package/skills/add-evals/SKILL.md +23 -8
  63. package/skills/add-traces/SKILL.md +23 -11
  64. package/skills/generate-machine/SKILL.md +2 -2
  65. package/skills/graph-engineering/SKILL.md +1 -1
  66. package/skills/improve-machine/SKILL.md +7 -6
  67. package/skills/loop-to-machine/SKILL.md +34 -7
  68. package/skills/loop-to-machine/policy.md +14 -18
package/dist/testing.cjs CHANGED
@@ -1,8 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_event_log = require("./event-log-BZRfBRd7.cjs");
3
- const require_decision = require("./decision-CIb7ddIv.cjs");
4
- const require_run_agent = require("./run-agent-ctLCvNgL.cjs");
5
- const require_verify = require("./verify-CVlsTZ-V.cjs");
2
+ const require_event_log = require("./event-log-CKWeC7H-.cjs");
3
+ const require_run_agent = require("./run-agent-Cg0xd3K-.cjs");
4
+ const require_verify = require("./verify-D_llRCTr.cjs");
6
5
  //#region src/trajectory.ts
7
6
  /**
8
7
  * Classifies one item. Event-shaped things (log entries, events) become events;
@@ -10,9 +9,9 @@ const require_verify = require("./verify-CVlsTZ-V.cjs");
10
9
  * @internal
11
10
  */
12
11
  function normalize(item) {
13
- if (require_decision.isRecord(item)) {
12
+ if (require_event_log.isRecord(item)) {
14
13
  const nested = item["event"];
15
- if (require_decision.isRecord(nested) && typeof nested["type"] === "string") return {
14
+ if (require_event_log.isRecord(nested) && typeof nested["type"] === "string") return {
16
15
  kind: "event",
17
16
  event: nested
18
17
  };
@@ -33,7 +32,7 @@ function normalize(item) {
33
32
  /** Every leaf of a state value as a dot path (`{ review: 'editing' }` → `review.editing`). @internal */
34
33
  function statePaths$1(value) {
35
34
  if (typeof value === "string") return [value];
36
- if (!require_decision.isRecord(value)) return [];
35
+ if (!require_event_log.isRecord(value)) return [];
37
36
  return Object.entries(value).flatMap(([key, child]) => statePaths$1(child).map((path) => `${key}.${path}`));
38
37
  }
39
38
  /**
@@ -46,7 +45,7 @@ function stateMatchesPath(path, value) {
46
45
  function deepEqual(a, b) {
47
46
  if (Object.is(a, b)) return true;
48
47
  if (Array.isArray(a) || Array.isArray(b)) return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((item, index) => deepEqual(item, b[index]));
49
- if (!require_decision.isRecord(a) || !require_decision.isRecord(b)) return false;
48
+ if (!require_event_log.isRecord(a) || !require_event_log.isRecord(b)) return false;
50
49
  const keys = Object.keys(a);
51
50
  return keys.length === Object.keys(b).length && keys.every((key) => deepEqual(a[key], b[key]));
52
51
  }
@@ -178,7 +177,7 @@ function isTextResult(value) {
178
177
  */
179
178
  async function resolveSeamScriptEntry(entry, request, info) {
180
179
  const value = typeof entry === "function" ? await entry(request, info) : entry;
181
- return require_decision.isRecord(value) && isTextResult(value) ? value : { result: value };
180
+ return require_event_log.isRecord(value) && isTextResult(value) ? value : { result: value };
182
181
  }
183
182
  /** Names a pending text request in an error message. @internal */
184
183
  function describeText(request) {
@@ -188,7 +187,7 @@ function describeText(request) {
188
187
  * Stream semantics with no model: the whole text lands as one chunk. @internal
189
188
  */
190
189
  function emitScriptedChunk(result, info) {
191
- const text = require_decision.isRecord(result) ? result["result"] : void 0;
190
+ const text = require_event_log.isRecord(result) ? result["result"] : void 0;
192
191
  if (typeof text === "string") info?.onChunk?.(text);
193
192
  }
194
193
  /**
@@ -196,7 +195,7 @@ function emitScriptedChunk(result, info) {
196
195
  * @internal
197
196
  */
198
197
  async function seamOutputOf(result, request) {
199
- if (!require_decision.isRecord(result)) return;
198
+ if (!require_event_log.isRecord(result)) return;
200
199
  return await require_event_log.normalizeGeneratorResult(result, `seam '${request.name ?? request.model}'`);
201
200
  }
202
201
  /**
@@ -321,7 +320,7 @@ async function runSeam(machine, options) {
321
320
  ...event ? { event } : {}
322
321
  });
323
322
  if (result.status !== "idle" || turn === maxTurns) break;
324
- const next = options.respond?.({
323
+ const next = await options.respond?.({
325
324
  snapshot: result.snapshot,
326
325
  state: result.snapshot.value,
327
326
  meta: require_event_log.getStateMeta(result.snapshot),
@@ -361,13 +360,36 @@ async function runSeam(machine, options) {
361
360
  };
362
361
  }
363
362
  //#endregion
363
+ //#region src/internal/trace-states.ts
364
+ /** The `value` of a trace event's `from` or `snapshot`. @internal */
365
+ function valueOf(holder) {
366
+ return require_event_log.isRecord(holder) ? holder.value : void 0;
367
+ }
368
+ /** A decision request on its first attempt (no failed attempts yet). @internal */
369
+ function isFirstDecision(request) {
370
+ return require_event_log.isRecord(request) && request.kind === "decision" && (!Array.isArray(request.attempts) || request.attempts.length === 0);
371
+ }
372
+ /**
373
+ * Every active leaf of a state value as a dot path:
374
+ * `'a'` → `['a']`; `{ a: 'b' }` → `['a.b']`; `{ p: { x: 'one', y: {} } }` → `['p.x.one', 'p.y']`.
375
+ * @internal
376
+ */
377
+ function statePaths(value, prefix = "") {
378
+ if (typeof value === "string") return [prefix + value];
379
+ if (!require_event_log.isRecord(value)) return [];
380
+ const entries = Object.entries(value);
381
+ if (entries.length === 0) return prefix ? [prefix.slice(0, -1)] : [];
382
+ return entries.flatMap(([key, child]) => statePaths(child, `${prefix}${key}.`));
383
+ }
384
+ //#endregion
364
385
  //#region src/fold-traces.ts
365
386
  /**
366
387
  * Folds many runs' traces into per-state stats: how many runs visited each
367
- * state, how many of those failed, and how many options the guards withheld
368
- * at decisions made there. Pure; reads only:
388
+ * state, how many of those failed, how many options the guards withheld
389
+ * at decisions made there, and how many events it ignored. Pure; reads only:
369
390
  *
370
- * - `machine.transition`: the run visited `from.value` and `snapshot.value`.
391
+ * - `machine.transition`: the run visited `from.value` and `snapshot.value`;
392
+ * with `ignored`, each of those states ignored one event.
371
393
  * - `request.start` of a decision, first attempt only: its `request.withheld`
372
394
  * counts toward the state the run was in, the `from.value` of the
373
395
  * transition its choice causes.
@@ -393,7 +415,8 @@ function foldTraces(traces, options) {
393
415
  state,
394
416
  visits: 0,
395
417
  failures: 0,
396
- withheld: 0
418
+ withheld: 0,
419
+ ignored: 0
397
420
  };
398
421
  stats.set(state, entry);
399
422
  }
@@ -410,6 +433,7 @@ function foldTraces(traces, options) {
410
433
  for (const state of statePaths(valueOf(event.from))) visit(state);
411
434
  current = statePaths(valueOf(event.snapshot));
412
435
  for (const state of current) visit(state);
436
+ if (event.ignored === true) for (const state of current) statsFor(state).ignored++;
413
437
  } else if (event.type === "request.start" && isFirstDecision(event.request)) {
414
438
  const withheld = event.request.withheld;
415
439
  if (!Array.isArray(withheld)) continue;
@@ -424,18 +448,37 @@ function foldTraces(traces, options) {
424
448
  }
425
449
  return [...stats.values()];
426
450
  }
427
- function valueOf(holder) {
428
- return require_decision.isRecord(holder) ? holder.value : void 0;
429
- }
430
- function isFirstDecision(request) {
431
- return require_decision.isRecord(request) && request.kind === "decision" && (!Array.isArray(request.attempts) || request.attempts.length === 0);
432
- }
433
- function statePaths(value, prefix = "") {
434
- if (typeof value === "string") return [prefix + value];
435
- if (!require_decision.isRecord(value)) return [];
436
- const entries = Object.entries(value);
437
- if (entries.length === 0) return prefix ? [prefix.slice(0, -1)] : [];
438
- return entries.flatMap(([key, child]) => statePaths(child, `${prefix}${key}.`));
451
+ //#endregion
452
+ //#region src/decision-requests.ts
453
+ /**
454
+ * The decisions a run asked for, read from its trace: each decision's first
455
+ * `request.start`, with the states the run was in. A trace is one run's events,
456
+ * live or serialized with `serializeTraceEvent`. Retries of the same decision
457
+ * are left out, so each decision appears once.
458
+ *
459
+ * Use the requests as eval rows (run a decider on each and compare its event
460
+ * with a label) or as probe inputs for a policy. A serialized request keeps its
461
+ * `options`, `metadata`, `system`, and `prompt`; event schemas do not survive
462
+ * serialization, so replay closed choices (`options`) rather than open ones.
463
+ *
464
+ * @example
465
+ * ```ts no-check
466
+ * const rows = traces.flatMap((trace) => getDecisionRequests(trace, { name: "chooseResolution" }));
467
+ * for (const { request } of rows) console.log((await decide(request)).event);
468
+ * ```
469
+ */
470
+ function getDecisionRequests(trace, options = {}) {
471
+ const requests = [];
472
+ let current = [];
473
+ for (const event of trace) if (event.type === "machine.transition") current = statePaths(valueOf(event.snapshot));
474
+ else if (event.type === "request.start" && isFirstDecision(event.request)) {
475
+ if (options.name !== void 0 && event.request.name !== options.name) continue;
476
+ requests.push({
477
+ states: [...current],
478
+ request: event.request
479
+ });
480
+ }
481
+ return requests;
439
482
  }
440
483
  //#endregion
441
484
  //#region src/compare-runs.ts
@@ -538,7 +581,7 @@ function structurallyEqual(a, b) {
538
581
  if (a instanceof Map || b instanceof Map) return a instanceof Map && b instanceof Map && structurallyEqual([...a], [...b]);
539
582
  if (a instanceof Set || b instanceof Set) return a instanceof Set && b instanceof Set && structurallyEqual([...a], [...b]);
540
583
  if (Array.isArray(a) || Array.isArray(b)) return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((item, index) => structurallyEqual(item, b[index]));
541
- if (!require_decision.isRecord(a) || !require_decision.isRecord(b)) return false;
584
+ if (!require_event_log.isRecord(a) || !require_event_log.isRecord(b)) return false;
542
585
  const keys = Object.keys(a);
543
586
  return keys.length === Object.keys(b).length && keys.every((key) => Object.hasOwn(b, key) && structurallyEqual(a[key], b[key]));
544
587
  }
@@ -550,6 +593,7 @@ exports.canReach = require_verify.canReach;
550
593
  exports.compareRuns = compareRuns;
551
594
  exports.explorePaths = require_verify.explorePaths;
552
595
  exports.foldTraces = foldTraces;
596
+ exports.getDecisionRequests = getDecisionRequests;
553
597
  exports.lintAgentMachine = require_verify.lintAgentMachine;
554
598
  exports.matchesTrajectory = matchesTrajectory;
555
599
  exports.runSeam = runSeam;
@@ -1,7 +1,7 @@
1
- import { c as AgentRequestExecutorInfo, f as AgentTextRequest, s as AgentRequestExecutor, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-DmciuVUQ.cjs";
2
- import { f as AgentRuntimeOptions, l as AgentRunResult, o as AgentRunInit } from "./run-agent-CTlMc3Jb.cjs";
1
+ import { P as AgentExecutorDecisionRequest, c as AgentRequestExecutorInfo, f as AgentTextRequest, s as AgentRequestExecutor, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-CYP502VT.cjs";
2
+ import { f as AgentRuntimeOptions, l as AgentRunResult, o as AgentRunInit } from "./run-agent-B5QhabdY.cjs";
3
3
  import { t as MetaOfSnapshot } from "./utils-ebVpCYoF.cjs";
4
- import { _ as explorePaths, a as AgentPathTerminal, c as CanReachResult, d as SimulateAgentOptions, f as SimulateAgentResult, g as canReach, h as assertAgentMachine, i as AgentPathReport, l as ExplorePathsOptions, m as SimulationTrailEntry, n as AgentLintError, o as AgentUnknownStateError, p as SimulationScript, r as AgentLintSeverity, s as AssertAgentMachineOptions, t as AgentLintDiagnostic, u as LintAgentMachineOptions, v as lintAgentMachine, y as simulateAgent } from "./verify-Dzwd4Mvk.cjs";
4
+ import { _ as assertAgentMachine, a as AgentPathTerminal, b as lintAgentMachine, c as CanReachResult, d as ExploreSnapshot, f as LintAgentMachineOptions, g as SimulationTrailEntry, h as SimulationScript, i as AgentPathReport, l as CanReachTarget, m as SimulateAgentResult, n as AgentLintError, o as AgentUnknownStateError, p as SimulateAgentOptions, r as AgentLintSeverity, s as AssertAgentMachineOptions, t as AgentLintDiagnostic, u as ExplorePathsOptions, v as canReach, x as simulateAgent, y as explorePaths } from "./verify-Dk3Vwnha.cjs";
5
5
  import { AnyStateMachine, EventFromLogic, InputFrom, SnapshotFrom, StateValue } from "xstate";
6
6
  //#region src/trajectory.d.ts
7
7
  /** An event-shaped trajectory item: anything with a string `type`. */
@@ -204,10 +204,10 @@ interface RunSeamOptions<TMachine extends AnyStateMachine> {
204
204
  candidate?: AgentRequestExecutor;
205
205
  /**
206
206
  * The simulated user. Called at every idle pause; return the event to send,
207
- * or `null`/`undefined` to stop the run there. Omitted, the run stops at the
208
- * first idle pause.
207
+ * or `null`/`undefined` to stop the run there, directly or as a promise (a
208
+ * real async client). Omitted, the run stops at the first idle pause.
209
209
  */
210
- respond?: (turn: SeamTurn<TMachine>) => EventFromLogic<TMachine> | null | undefined;
210
+ respond?: (turn: SeamTurn<TMachine>) => EventFromLogic<TMachine> | null | undefined | PromiseLike<EventFromLogic<TMachine> | null | undefined>;
211
211
  /** Maximum idle pauses to answer before stopping. Default `12`. */
212
212
  maxTurns?: number;
213
213
  /**
@@ -288,6 +288,8 @@ interface StateStats {
288
288
  failures: number;
289
289
  /** Options withheld by the guards at decisions made in this state, summed over runs. */
290
290
  withheld: number;
291
+ /** Events this state ignored (`machine.transition` with `ignored`), summed over runs. */
292
+ ignored: number;
291
293
  }
292
294
  /** Options for {@link foldTraces}. */
293
295
  interface FoldTracesOptions<TTrace> {
@@ -296,10 +298,11 @@ interface FoldTracesOptions<TTrace> {
296
298
  }
297
299
  /**
298
300
  * Folds many runs' traces into per-state stats: how many runs visited each
299
- * state, how many of those failed, and how many options the guards withheld
300
- * at decisions made there. Pure; reads only:
301
+ * state, how many of those failed, how many options the guards withheld
302
+ * at decisions made there, and how many events it ignored. Pure; reads only:
301
303
  *
302
- * - `machine.transition`: the run visited `from.value` and `snapshot.value`.
304
+ * - `machine.transition`: the run visited `from.value` and `snapshot.value`;
305
+ * with `ignored`, each of those states ignored one event.
303
306
  * - `request.start` of a decision, first attempt only: its `request.withheld`
304
307
  * counts toward the state the run was in, the `from.value` of the
305
308
  * transition its choice causes.
@@ -320,6 +323,40 @@ export declare function foldTraces<TTrace extends readonly {
320
323
  readonly type: string;
321
324
  }[]>(traces: Iterable<TTrace>, options: FoldTracesOptions<TTrace>): StateStats[];
322
325
  //#endregion
326
+ //#region src/decision-requests.d.ts
327
+ /** One decision a run asked for. See {@link getDecisionRequests}. */
328
+ interface TracedDecisionRequest {
329
+ /** The active states when the decision was asked, as dot paths (one per parallel region). */
330
+ states: string[];
331
+ /** The request as the executor received it, on its first attempt. */
332
+ request: AgentExecutorDecisionRequest;
333
+ }
334
+ /** Options for {@link getDecisionRequests}. */
335
+ interface GetDecisionRequestsOptions {
336
+ /** Keep only requests with this `name` (the `agent.decide` input's `name`). */
337
+ name?: string;
338
+ }
339
+ /**
340
+ * The decisions a run asked for, read from its trace: each decision's first
341
+ * `request.start`, with the states the run was in. A trace is one run's events,
342
+ * live or serialized with `serializeTraceEvent`. Retries of the same decision
343
+ * are left out, so each decision appears once.
344
+ *
345
+ * Use the requests as eval rows (run a decider on each and compare its event
346
+ * with a label) or as probe inputs for a policy. A serialized request keeps its
347
+ * `options`, `metadata`, `system`, and `prompt`; event schemas do not survive
348
+ * serialization, so replay closed choices (`options`) rather than open ones.
349
+ *
350
+ * @example
351
+ * ```ts no-check
352
+ * const rows = traces.flatMap((trace) => getDecisionRequests(trace, { name: "chooseResolution" }));
353
+ * for (const { request } of rows) console.log((await decide(request)).event);
354
+ * ```
355
+ */
356
+ export declare function getDecisionRequests(trace: Iterable<{
357
+ readonly type: string;
358
+ }>, options?: GetDecisionRequestsOptions): TracedDecisionRequest[];
359
+ //#endregion
323
360
  //#region src/compare-runs.d.ts
324
361
  /** One run of one scenario, reduced to what parity compares. See {@link compareRuns}. */
325
362
  interface ParityRun {
@@ -401,4 +438,4 @@ export declare function compareRuns<TScenario extends {
401
438
  expected?: string;
402
439
  }>(options: CompareRunsOptions<TScenario>): Promise<ParityReport<TScenario>>;
403
440
  //#endregion
404
- export { type AgentLintDiagnostic, AgentLintError, type AgentLintSeverity, type AgentPathReport, type AgentPathTerminal, AgentUnknownStateError, type AssertAgentMachineOptions, type CanReachResult, type CompareRunsOptions, type ExplorePathsOptions, type FoldTracesOptions, type LintAgentMachineOptions, type MatchTrajectoryOptions, type ParityLabel, type ParityReport, type ParityResult, type ParityRun, type RunSeamOptions, type RunSeamResult, type SeamCall, type SeamRef, type SeamScriptEntry, type SeamSlice, type SeamTurn, type SimulateAgentOptions, type SimulateAgentResult, type SimulationScript, type SimulationTrailEntry, type StateStats, type TrajectoryEvent, type TrajectoryItem, type TrajectoryMatch, type TrajectoryMiss, assertAgentMachine, canReach, explorePaths, lintAgentMachine, simulateAgent };
441
+ export { type AgentLintDiagnostic, AgentLintError, type AgentLintSeverity, type AgentPathReport, type AgentPathTerminal, AgentUnknownStateError, type AssertAgentMachineOptions, type CanReachResult, type CanReachTarget, type CompareRunsOptions, type ExplorePathsOptions, type ExploreSnapshot, type FoldTracesOptions, type GetDecisionRequestsOptions, type LintAgentMachineOptions, type MatchTrajectoryOptions, type ParityLabel, type ParityReport, type ParityResult, type ParityRun, type RunSeamOptions, type RunSeamResult, type SeamCall, type SeamRef, type SeamScriptEntry, type SeamSlice, type SeamTurn, type SimulateAgentOptions, type SimulateAgentResult, type SimulationScript, type SimulationTrailEntry, type StateStats, type TracedDecisionRequest, type TrajectoryEvent, type TrajectoryItem, type TrajectoryMatch, type TrajectoryMiss, assertAgentMachine, canReach, explorePaths, lintAgentMachine, simulateAgent };
@@ -1,7 +1,7 @@
1
- import { c as AgentRequestExecutorInfo, f as AgentTextRequest, s as AgentRequestExecutor, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-BRYOPWvY.mjs";
2
- import { f as AgentRuntimeOptions, l as AgentRunResult, o as AgentRunInit } from "./run-agent-CAVt5R-r.mjs";
1
+ import { P as AgentExecutorDecisionRequest, c as AgentRequestExecutorInfo, f as AgentTextRequest, s as AgentRequestExecutor, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-DuK9HIFM.mjs";
2
+ import { f as AgentRuntimeOptions, l as AgentRunResult, o as AgentRunInit } from "./run-agent-Atu-wEk7.mjs";
3
3
  import { t as MetaOfSnapshot } from "./utils-BnXdWih3.mjs";
4
- import { _ as explorePaths, a as AgentPathTerminal, c as CanReachResult, d as SimulateAgentOptions, f as SimulateAgentResult, g as canReach, h as assertAgentMachine, i as AgentPathReport, l as ExplorePathsOptions, m as SimulationTrailEntry, n as AgentLintError, o as AgentUnknownStateError, p as SimulationScript, r as AgentLintSeverity, s as AssertAgentMachineOptions, t as AgentLintDiagnostic, u as LintAgentMachineOptions, v as lintAgentMachine, y as simulateAgent } from "./verify-Cn86rT8l.mjs";
4
+ import { _ as assertAgentMachine, a as AgentPathTerminal, b as lintAgentMachine, c as CanReachResult, d as ExploreSnapshot, f as LintAgentMachineOptions, g as SimulationTrailEntry, h as SimulationScript, i as AgentPathReport, l as CanReachTarget, m as SimulateAgentResult, n as AgentLintError, o as AgentUnknownStateError, p as SimulateAgentOptions, r as AgentLintSeverity, s as AssertAgentMachineOptions, t as AgentLintDiagnostic, u as ExplorePathsOptions, v as canReach, x as simulateAgent, y as explorePaths } from "./verify-BVz4cURF.mjs";
5
5
  import { AnyStateMachine, EventFromLogic, InputFrom, SnapshotFrom, StateValue } from "xstate";
6
6
  //#region src/trajectory.d.ts
7
7
  /** An event-shaped trajectory item: anything with a string `type`. */
@@ -204,10 +204,10 @@ interface RunSeamOptions<TMachine extends AnyStateMachine> {
204
204
  candidate?: AgentRequestExecutor;
205
205
  /**
206
206
  * The simulated user. Called at every idle pause; return the event to send,
207
- * or `null`/`undefined` to stop the run there. Omitted, the run stops at the
208
- * first idle pause.
207
+ * or `null`/`undefined` to stop the run there, directly or as a promise (a
208
+ * real async client). Omitted, the run stops at the first idle pause.
209
209
  */
210
- respond?: (turn: SeamTurn<TMachine>) => EventFromLogic<TMachine> | null | undefined;
210
+ respond?: (turn: SeamTurn<TMachine>) => EventFromLogic<TMachine> | null | undefined | PromiseLike<EventFromLogic<TMachine> | null | undefined>;
211
211
  /** Maximum idle pauses to answer before stopping. Default `12`. */
212
212
  maxTurns?: number;
213
213
  /**
@@ -288,6 +288,8 @@ interface StateStats {
288
288
  failures: number;
289
289
  /** Options withheld by the guards at decisions made in this state, summed over runs. */
290
290
  withheld: number;
291
+ /** Events this state ignored (`machine.transition` with `ignored`), summed over runs. */
292
+ ignored: number;
291
293
  }
292
294
  /** Options for {@link foldTraces}. */
293
295
  interface FoldTracesOptions<TTrace> {
@@ -296,10 +298,11 @@ interface FoldTracesOptions<TTrace> {
296
298
  }
297
299
  /**
298
300
  * Folds many runs' traces into per-state stats: how many runs visited each
299
- * state, how many of those failed, and how many options the guards withheld
300
- * at decisions made there. Pure; reads only:
301
+ * state, how many of those failed, how many options the guards withheld
302
+ * at decisions made there, and how many events it ignored. Pure; reads only:
301
303
  *
302
- * - `machine.transition`: the run visited `from.value` and `snapshot.value`.
304
+ * - `machine.transition`: the run visited `from.value` and `snapshot.value`;
305
+ * with `ignored`, each of those states ignored one event.
303
306
  * - `request.start` of a decision, first attempt only: its `request.withheld`
304
307
  * counts toward the state the run was in, the `from.value` of the
305
308
  * transition its choice causes.
@@ -320,6 +323,40 @@ export declare function foldTraces<TTrace extends readonly {
320
323
  readonly type: string;
321
324
  }[]>(traces: Iterable<TTrace>, options: FoldTracesOptions<TTrace>): StateStats[];
322
325
  //#endregion
326
+ //#region src/decision-requests.d.ts
327
+ /** One decision a run asked for. See {@link getDecisionRequests}. */
328
+ interface TracedDecisionRequest {
329
+ /** The active states when the decision was asked, as dot paths (one per parallel region). */
330
+ states: string[];
331
+ /** The request as the executor received it, on its first attempt. */
332
+ request: AgentExecutorDecisionRequest;
333
+ }
334
+ /** Options for {@link getDecisionRequests}. */
335
+ interface GetDecisionRequestsOptions {
336
+ /** Keep only requests with this `name` (the `agent.decide` input's `name`). */
337
+ name?: string;
338
+ }
339
+ /**
340
+ * The decisions a run asked for, read from its trace: each decision's first
341
+ * `request.start`, with the states the run was in. A trace is one run's events,
342
+ * live or serialized with `serializeTraceEvent`. Retries of the same decision
343
+ * are left out, so each decision appears once.
344
+ *
345
+ * Use the requests as eval rows (run a decider on each and compare its event
346
+ * with a label) or as probe inputs for a policy. A serialized request keeps its
347
+ * `options`, `metadata`, `system`, and `prompt`; event schemas do not survive
348
+ * serialization, so replay closed choices (`options`) rather than open ones.
349
+ *
350
+ * @example
351
+ * ```ts no-check
352
+ * const rows = traces.flatMap((trace) => getDecisionRequests(trace, { name: "chooseResolution" }));
353
+ * for (const { request } of rows) console.log((await decide(request)).event);
354
+ * ```
355
+ */
356
+ export declare function getDecisionRequests(trace: Iterable<{
357
+ readonly type: string;
358
+ }>, options?: GetDecisionRequestsOptions): TracedDecisionRequest[];
359
+ //#endregion
323
360
  //#region src/compare-runs.d.ts
324
361
  /** One run of one scenario, reduced to what parity compares. See {@link compareRuns}. */
325
362
  interface ParityRun {
@@ -401,4 +438,4 @@ export declare function compareRuns<TScenario extends {
401
438
  expected?: string;
402
439
  }>(options: CompareRunsOptions<TScenario>): Promise<ParityReport<TScenario>>;
403
440
  //#endregion
404
- export { type AgentLintDiagnostic, AgentLintError, type AgentLintSeverity, type AgentPathReport, type AgentPathTerminal, AgentUnknownStateError, type AssertAgentMachineOptions, type CanReachResult, type CompareRunsOptions, type ExplorePathsOptions, type FoldTracesOptions, type LintAgentMachineOptions, type MatchTrajectoryOptions, type ParityLabel, type ParityReport, type ParityResult, type ParityRun, type RunSeamOptions, type RunSeamResult, type SeamCall, type SeamRef, type SeamScriptEntry, type SeamSlice, type SeamTurn, type SimulateAgentOptions, type SimulateAgentResult, type SimulationScript, type SimulationTrailEntry, type StateStats, type TrajectoryEvent, type TrajectoryItem, type TrajectoryMatch, type TrajectoryMiss, assertAgentMachine, canReach, explorePaths, lintAgentMachine, simulateAgent };
441
+ export { type AgentLintDiagnostic, AgentLintError, type AgentLintSeverity, type AgentPathReport, type AgentPathTerminal, AgentUnknownStateError, type AssertAgentMachineOptions, type CanReachResult, type CanReachTarget, type CompareRunsOptions, type ExplorePathsOptions, type ExploreSnapshot, type FoldTracesOptions, type GetDecisionRequestsOptions, type LintAgentMachineOptions, type MatchTrajectoryOptions, type ParityLabel, type ParityReport, type ParityResult, type ParityRun, type RunSeamOptions, type RunSeamResult, type SeamCall, type SeamRef, type SeamScriptEntry, type SeamSlice, type SeamTurn, type SimulateAgentOptions, type SimulateAgentResult, type SimulationScript, type SimulationTrailEntry, type StateStats, type TracedDecisionRequest, type TrajectoryEvent, type TrajectoryItem, type TrajectoryMatch, type TrajectoryMiss, assertAgentMachine, canReach, explorePaths, lintAgentMachine, simulateAgent };
package/dist/testing.mjs CHANGED
@@ -1,7 +1,6 @@
1
- import { $ as getStateMeta, F as normalizeGeneratorResult, N as getCallUsage, st as AgentError } from "./event-log-DJCMHek_.mjs";
2
- import { m as isRecord } from "./decision-BHkvuImD.mjs";
3
- import { p as runToQuiescence, s as createAgentRuntime } from "./run-agent-BpHqkaZw.mjs";
4
- import { a as explorePaths, i as canReach, n as AgentUnknownStateError, o as lintAgentMachine, r as assertAgentMachine, s as simulateAgent, t as AgentLintError } from "./verify-COFWyprJ.mjs";
1
+ import { $ as getStateMeta, F as normalizeGeneratorResult, N as getCallUsage, lt as isRecord, ut as AgentError } from "./event-log-DAqsalT1.mjs";
2
+ import { p as runToQuiescence, s as createAgentRuntime } from "./run-agent-2UnSUhDb.mjs";
3
+ import { a as explorePaths, i as canReach, n as AgentUnknownStateError, o as lintAgentMachine, r as assertAgentMachine, s as simulateAgent, t as AgentLintError } from "./verify-CoCvR1eM.mjs";
5
4
  //#region src/trajectory.ts
6
5
  /**
7
6
  * Classifies one item. Event-shaped things (log entries, events) become events;
@@ -320,7 +319,7 @@ async function runSeam(machine, options) {
320
319
  ...event ? { event } : {}
321
320
  });
322
321
  if (result.status !== "idle" || turn === maxTurns) break;
323
- const next = options.respond?.({
322
+ const next = await options.respond?.({
324
323
  snapshot: result.snapshot,
325
324
  state: result.snapshot.value,
326
325
  meta: getStateMeta(result.snapshot),
@@ -360,13 +359,36 @@ async function runSeam(machine, options) {
360
359
  };
361
360
  }
362
361
  //#endregion
362
+ //#region src/internal/trace-states.ts
363
+ /** The `value` of a trace event's `from` or `snapshot`. @internal */
364
+ function valueOf(holder) {
365
+ return isRecord(holder) ? holder.value : void 0;
366
+ }
367
+ /** A decision request on its first attempt (no failed attempts yet). @internal */
368
+ function isFirstDecision(request) {
369
+ return isRecord(request) && request.kind === "decision" && (!Array.isArray(request.attempts) || request.attempts.length === 0);
370
+ }
371
+ /**
372
+ * Every active leaf of a state value as a dot path:
373
+ * `'a'` → `['a']`; `{ a: 'b' }` → `['a.b']`; `{ p: { x: 'one', y: {} } }` → `['p.x.one', 'p.y']`.
374
+ * @internal
375
+ */
376
+ function statePaths(value, prefix = "") {
377
+ if (typeof value === "string") return [prefix + value];
378
+ if (!isRecord(value)) return [];
379
+ const entries = Object.entries(value);
380
+ if (entries.length === 0) return prefix ? [prefix.slice(0, -1)] : [];
381
+ return entries.flatMap(([key, child]) => statePaths(child, `${prefix}${key}.`));
382
+ }
383
+ //#endregion
363
384
  //#region src/fold-traces.ts
364
385
  /**
365
386
  * Folds many runs' traces into per-state stats: how many runs visited each
366
- * state, how many of those failed, and how many options the guards withheld
367
- * at decisions made there. Pure; reads only:
387
+ * state, how many of those failed, how many options the guards withheld
388
+ * at decisions made there, and how many events it ignored. Pure; reads only:
368
389
  *
369
- * - `machine.transition`: the run visited `from.value` and `snapshot.value`.
390
+ * - `machine.transition`: the run visited `from.value` and `snapshot.value`;
391
+ * with `ignored`, each of those states ignored one event.
370
392
  * - `request.start` of a decision, first attempt only: its `request.withheld`
371
393
  * counts toward the state the run was in, the `from.value` of the
372
394
  * transition its choice causes.
@@ -392,7 +414,8 @@ function foldTraces(traces, options) {
392
414
  state,
393
415
  visits: 0,
394
416
  failures: 0,
395
- withheld: 0
417
+ withheld: 0,
418
+ ignored: 0
396
419
  };
397
420
  stats.set(state, entry);
398
421
  }
@@ -409,6 +432,7 @@ function foldTraces(traces, options) {
409
432
  for (const state of statePaths(valueOf(event.from))) visit(state);
410
433
  current = statePaths(valueOf(event.snapshot));
411
434
  for (const state of current) visit(state);
435
+ if (event.ignored === true) for (const state of current) statsFor(state).ignored++;
412
436
  } else if (event.type === "request.start" && isFirstDecision(event.request)) {
413
437
  const withheld = event.request.withheld;
414
438
  if (!Array.isArray(withheld)) continue;
@@ -423,18 +447,37 @@ function foldTraces(traces, options) {
423
447
  }
424
448
  return [...stats.values()];
425
449
  }
426
- function valueOf(holder) {
427
- return isRecord(holder) ? holder.value : void 0;
428
- }
429
- function isFirstDecision(request) {
430
- return isRecord(request) && request.kind === "decision" && (!Array.isArray(request.attempts) || request.attempts.length === 0);
431
- }
432
- function statePaths(value, prefix = "") {
433
- if (typeof value === "string") return [prefix + value];
434
- if (!isRecord(value)) return [];
435
- const entries = Object.entries(value);
436
- if (entries.length === 0) return prefix ? [prefix.slice(0, -1)] : [];
437
- return entries.flatMap(([key, child]) => statePaths(child, `${prefix}${key}.`));
450
+ //#endregion
451
+ //#region src/decision-requests.ts
452
+ /**
453
+ * The decisions a run asked for, read from its trace: each decision's first
454
+ * `request.start`, with the states the run was in. A trace is one run's events,
455
+ * live or serialized with `serializeTraceEvent`. Retries of the same decision
456
+ * are left out, so each decision appears once.
457
+ *
458
+ * Use the requests as eval rows (run a decider on each and compare its event
459
+ * with a label) or as probe inputs for a policy. A serialized request keeps its
460
+ * `options`, `metadata`, `system`, and `prompt`; event schemas do not survive
461
+ * serialization, so replay closed choices (`options`) rather than open ones.
462
+ *
463
+ * @example
464
+ * ```ts no-check
465
+ * const rows = traces.flatMap((trace) => getDecisionRequests(trace, { name: "chooseResolution" }));
466
+ * for (const { request } of rows) console.log((await decide(request)).event);
467
+ * ```
468
+ */
469
+ function getDecisionRequests(trace, options = {}) {
470
+ const requests = [];
471
+ let current = [];
472
+ for (const event of trace) if (event.type === "machine.transition") current = statePaths(valueOf(event.snapshot));
473
+ else if (event.type === "request.start" && isFirstDecision(event.request)) {
474
+ if (options.name !== void 0 && event.request.name !== options.name) continue;
475
+ requests.push({
476
+ states: [...current],
477
+ request: event.request
478
+ });
479
+ }
480
+ return requests;
438
481
  }
439
482
  //#endregion
440
483
  //#region src/compare-runs.ts
@@ -542,4 +585,4 @@ function structurallyEqual(a, b) {
542
585
  return keys.length === Object.keys(b).length && keys.every((key) => Object.hasOwn(b, key) && structurallyEqual(a[key], b[key]));
543
586
  }
544
587
  //#endregion
545
- export { AgentLintError, AgentUnknownStateError, assertAgentMachine, canReach, compareRuns, explorePaths, foldTraces, lintAgentMachine, matchesTrajectory, runSeam, simulateAgent };
588
+ export { AgentLintError, AgentUnknownStateError, assertAgentMachine, canReach, compareRuns, explorePaths, foldTraces, getDecisionRequests, lintAgentMachine, matchesTrajectory, runSeam, simulateAgent };
@@ -130,9 +130,13 @@ declare function parseAgentEvent<TSource extends AnyStateMachine | AnyMachineSna
130
130
  * ({@link RESERVED_AGENT_EVENT_PREFIX}) event types are always excluded, before
131
131
  * any `allowedEvents` matching — a machine that handles `'@agent.usage'` still
132
132
  * never offers it to a model.
133
+ *
134
+ * Pass `actor: "agent"` for the list a model may choose from: it also drops an
135
+ * event the state handles through a transition tagged `meta: { actor: "human" }`.
133
136
  */
134
137
  declare function getAcceptedEvents(snapshot: AnyMachineSnapshot, options?: Pick<AgentRequestOptions, "events" | "schemas"> & {
135
138
  eventTypes?: readonly string[];
139
+ actor?: "agent";
136
140
  }): AgentEventDescriptor[];
137
141
  //#endregion
138
142
  //#region src/decision.d.ts
@@ -814,9 +818,11 @@ interface AgentRequestExecutorInfo {
814
818
  * `a` being the number of prior failed attempts), so a retry never collides
815
819
  * with the rejected attempt it is replacing.
816
820
  *
817
- * It identifies the CALL SITE, not the request: a fork inherits its parent's
818
- * lineage id, so cache on `callKey` together with a fingerprint of the
819
- * request and reuse a cached result only when the request also matches.
821
+ * It identifies the CALL SITE, not the request: a version bridge keeps the
822
+ * lineage id, so a migrated machine can ask something else under the same
823
+ * key. Cache on `callKey` together with a fingerprint of the request and
824
+ * reuse a cached result only when the request also matches. A fork mints
825
+ * its own lineage id, so its keys never match its parent's.
820
826
  *
821
827
  * Undefined off the `createAgentRuntime` path, and for a log with no `executionId`.
822
828
  */
@@ -130,9 +130,13 @@ declare function parseAgentEvent<TSource extends AnyStateMachine | AnyMachineSna
130
130
  * ({@link RESERVED_AGENT_EVENT_PREFIX}) event types are always excluded, before
131
131
  * any `allowedEvents` matching — a machine that handles `'@agent.usage'` still
132
132
  * never offers it to a model.
133
+ *
134
+ * Pass `actor: "agent"` for the list a model may choose from: it also drops an
135
+ * event the state handles through a transition tagged `meta: { actor: "human" }`.
133
136
  */
134
137
  declare function getAcceptedEvents(snapshot: AnyMachineSnapshot, options?: Pick<AgentRequestOptions, "events" | "schemas"> & {
135
138
  eventTypes?: readonly string[];
139
+ actor?: "agent";
136
140
  }): AgentEventDescriptor[];
137
141
  //#endregion
138
142
  //#region src/decision.d.ts
@@ -814,9 +818,11 @@ interface AgentRequestExecutorInfo {
814
818
  * `a` being the number of prior failed attempts), so a retry never collides
815
819
  * with the rejected attempt it is replacing.
816
820
  *
817
- * It identifies the CALL SITE, not the request: a fork inherits its parent's
818
- * lineage id, so cache on `callKey` together with a fingerprint of the
819
- * request and reuse a cached result only when the request also matches.
821
+ * It identifies the CALL SITE, not the request: a version bridge keeps the
822
+ * lineage id, so a migrated machine can ask something else under the same
823
+ * key. Cache on `callKey` together with a fingerprint of the request and
824
+ * reuse a cached result only when the request also matches. A fork mints
825
+ * its own lineage id, so its keys never match its parent's.
820
826
  *
821
827
  * Undefined off the `createAgentRuntime` path, and for a log with no `executionId`.
822
828
  */
@@ -1,4 +1,4 @@
1
- import { t as AgentCallUsage } from "./text-logic-BRYOPWvY.mjs";
1
+ import { t as AgentCallUsage } from "./text-logic-DuK9HIFM.mjs";
2
2
  import { EventObject } from "xstate";
3
3
  //#region src/usage.d.ts
4
4
  /** Reserved event delivered after a model call reports token usage. */
@@ -1,4 +1,4 @@
1
- import { t as AgentCallUsage } from "./text-logic-DmciuVUQ.cjs";
1
+ import { t as AgentCallUsage } from "./text-logic-CYP502VT.cjs";
2
2
  import { EventObject } from "xstate";
3
3
  //#region src/usage.d.ts
4
4
  /** Reserved event delivered after a model call reports token usage. */
package/dist/validate.cjs CHANGED
@@ -21,9 +21,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  enumerable: true
22
22
  }) : target, mod));
23
23
  //#endregion
24
- const require_event_log = require("./event-log-BZRfBRd7.cjs");
25
- const require_setup_agent = require("./setup-agent-DoUk7EdC.cjs");
26
- const require_verify = require("./verify-CVlsTZ-V.cjs");
24
+ const require_event_log = require("./event-log-CKWeC7H-.cjs");
25
+ const require_setup_agent = require("./setup-agent-CwUJyqKB.cjs");
26
+ const require_verify = require("./verify-D_llRCTr.cjs");
27
27
  let ajv_dist_2020_js = require("ajv/dist/2020.js");
28
28
  ajv_dist_2020_js = __toESM(ajv_dist_2020_js, 1);
29
29
  //#region schemas/agent-workflow.json
@@ -1,5 +1,5 @@
1
- import { d as AgentWorkflowConfig, g as FromConfigOptions, v as SchemaCompiler } from "./setup-agent-CLPCkXsu.cjs";
2
- import { l as ExplorePathsOptions } from "./verify-Dzwd4Mvk.cjs";
1
+ import { d as AgentWorkflowConfig, g as FromConfigOptions, v as SchemaCompiler } from "./setup-agent-BiF1N3td.cjs";
2
+ import { u as ExplorePathsOptions } from "./verify-Dk3Vwnha.cjs";
3
3
  import { AnyActorLogic, AnyStateMachine } from "xstate";
4
4
  //#region src/validate/validate-config.d.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { d as AgentWorkflowConfig, g as FromConfigOptions, v as SchemaCompiler } from "./setup-agent-CGELn1qZ.mjs";
2
- import { l as ExplorePathsOptions } from "./verify-Cn86rT8l.mjs";
1
+ import { d as AgentWorkflowConfig, g as FromConfigOptions, v as SchemaCompiler } from "./setup-agent-J9f_Wu5T.mjs";
2
+ import { u as ExplorePathsOptions } from "./verify-BVz4cURF.mjs";
3
3
  import { AnyActorLogic, AnyStateMachine } from "xstate";
4
4
  //#region src/validate/validate-config.d.ts
5
5
  /**