@statelyai/agent 2.0.0-alpha.30 → 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.
- package/CHANGELOG.md +1733 -0
- package/dist/ai-sdk.cjs +8 -8
- package/dist/ai-sdk.d.cts +1 -1
- package/dist/ai-sdk.d.mts +1 -1
- package/dist/ai-sdk.mjs +3 -3
- package/dist/{decision-BHkvuImD.mjs → decision-DqO018Tp.mjs} +22 -9
- package/dist/{decision-CIb7ddIv.cjs → decision-Iys2hzg3.cjs} +30 -17
- package/dist/{event-log-BZRfBRd7.cjs → event-log-Bdww2l1D.cjs} +103 -24
- package/dist/{event-log-DJCMHek_.mjs → event-log-DE430ZCa.mjs} +86 -25
- package/dist/{event-log-store-DZR4IIWe.cjs → event-log-store-BWMLi6oh.cjs} +1 -1
- package/dist/{event-log-store-DsP6GCRh.mjs → event-log-store-CCWdTPEP.mjs} +1 -1
- package/dist/{event-log-store-CIIJohjj.d.mts → event-log-store-DTf_OzB-.d.cts} +1 -1
- package/dist/{event-log-store-CLAC9q2Y.d.cts → event-log-store-RziIobdW.d.mts} +1 -1
- package/dist/index.cjs +129 -21
- package/dist/index.d.cts +58 -11
- package/dist/index.d.mts +58 -11
- package/dist/index.mjs +126 -19
- package/dist/log.cjs +2 -2
- package/dist/log.d.cts +1 -1
- package/dist/log.d.mts +1 -1
- package/dist/log.mjs +2 -2
- package/dist/machines.cjs +1 -1
- package/dist/machines.mjs +1 -1
- package/dist/{model-source-BaHwJ1wK.mjs → model-source-CXsSZPq0.mjs} +1 -2
- package/dist/{model-source-BCKg4qJ1.cjs → model-source-DQ7KgJaT.cjs} +4 -5
- package/dist/openai.cjs +2 -2
- package/dist/openai.d.cts +1 -1
- package/dist/openai.d.mts +1 -1
- package/dist/openai.mjs +2 -2
- package/dist/otel.d.cts +1 -1
- package/dist/otel.d.mts +1 -1
- package/dist/{run-agent-CTlMc3Jb.d.cts → run-agent-B5opVUxx.d.cts} +17 -6
- package/dist/{run-agent-CAVt5R-r.d.mts → run-agent-D4MwS5GY.d.mts} +17 -6
- package/dist/{run-agent-BpHqkaZw.mjs → run-agent-DWZ1uyBJ.mjs} +89 -35
- package/dist/{run-agent-ctLCvNgL.cjs → run-agent-tmk58M0x.cjs} +89 -35
- package/dist/{setup-agent-7rV_cujV.mjs → setup-agent-BaffhCcM.mjs} +38 -3
- package/dist/{setup-agent-CGELn1qZ.d.mts → setup-agent-CPyg2ic7.d.mts} +11 -3
- package/dist/{setup-agent-DoUk7EdC.cjs → setup-agent-D0L8Anl_.cjs} +38 -3
- package/dist/{setup-agent-CLPCkXsu.d.cts → setup-agent-yFFVXf5s.d.cts} +11 -3
- package/dist/tanstack-ai.cjs +3 -3
- package/dist/tanstack-ai.d.cts +1 -1
- package/dist/tanstack-ai.d.mts +1 -1
- package/dist/tanstack-ai.mjs +3 -3
- package/dist/testing.cjs +73 -29
- package/dist/testing.d.cts +47 -10
- package/dist/testing.d.mts +47 -10
- package/dist/testing.mjs +65 -22
- package/dist/{text-logic-BRYOPWvY.d.mts → text-logic-BwdrDpO9.d.mts} +4 -0
- package/dist/{text-logic-DmciuVUQ.d.cts → text-logic-j9hShB7d.d.cts} +4 -0
- package/dist/{usage-BkM3z02Y.d.mts → usage-BYqv7VBw.d.cts} +1 -1
- package/dist/{usage-Cm_ovz9V.d.cts → usage-Bl4nK8D-.d.mts} +1 -1
- package/dist/validate.cjs +3 -3
- package/dist/validate.d.cts +2 -2
- package/dist/validate.d.mts +2 -2
- package/dist/validate.mjs +3 -3
- package/dist/{verify-COFWyprJ.mjs → verify-BH5e0XLK.mjs} +55 -5
- package/dist/{verify-Dzwd4Mvk.d.cts → verify-CPKDPMwY.d.cts} +14 -6
- package/dist/{verify-CVlsTZ-V.cjs → verify-CS_xxvVU.cjs} +57 -7
- package/dist/{verify-Cn86rT8l.d.mts → verify-tkymWz6X.d.mts} +14 -6
- package/package.json +34 -4
- package/readme.md +70 -40
- package/skills/add-evals/SKILL.md +23 -8
- package/skills/add-traces/SKILL.md +23 -11
- package/skills/generate-machine/SKILL.md +2 -2
- package/skills/graph-engineering/SKILL.md +1 -1
- package/skills/improve-machine/SKILL.md +7 -6
- package/skills/loop-to-machine/SKILL.md +34 -7
- package/skills/loop-to-machine/policy.md +14 -18
|
@@ -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-
|
|
3
|
-
import { n as AgentUsageEvent, t as AGENT_USAGE_EVENT_TYPE } from "./usage-
|
|
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
|
|
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.
|
package/dist/tanstack-ai.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_event_log = require("./event-log-
|
|
3
|
-
const require_decision = require("./decision-
|
|
4
|
-
const require_model_source = require("./model-source-
|
|
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
|
/**
|
package/dist/tanstack-ai.d.cts
CHANGED
|
@@ -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-
|
|
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";
|
package/dist/tanstack-ai.d.mts
CHANGED
|
@@ -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-
|
|
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";
|
package/dist/tanstack-ai.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { L as parseProviderOutput, R as providerOutputSchema, X as getJsonSchemaSync, Y as getJsonSchema,
|
|
2
|
-
import { c as renderDecisionAttempts } from "./decision-
|
|
3
|
-
import { t as resolveModelSource } from "./model-source-
|
|
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
|
/**
|
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-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const require_verify = require("./verify-CVlsTZ-V.cjs");
|
|
2
|
+
const require_event_log = require("./event-log-Bdww2l1D.cjs");
|
|
3
|
+
const require_run_agent = require("./run-agent-tmk58M0x.cjs");
|
|
4
|
+
const require_verify = require("./verify-CS_xxvVU.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 (
|
|
12
|
+
if (require_event_log.isRecord(item)) {
|
|
14
13
|
const nested = item["event"];
|
|
15
|
-
if (
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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 =
|
|
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 (!
|
|
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,
|
|
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
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
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 (!
|
|
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;
|
package/dist/testing.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { c as AgentRequestExecutorInfo, f as AgentTextRequest, s as AgentRequestExecutor, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-
|
|
2
|
-
import { f as AgentRuntimeOptions, l as AgentRunResult, o as AgentRunInit } from "./run-agent-
|
|
1
|
+
import { P as AgentExecutorDecisionRequest, c as AgentRequestExecutorInfo, f as AgentTextRequest, s as AgentRequestExecutor, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-j9hShB7d.cjs";
|
|
2
|
+
import { f as AgentRuntimeOptions, l as AgentRunResult, o as AgentRunInit } from "./run-agent-B5opVUxx.cjs";
|
|
3
3
|
import { t as MetaOfSnapshot } from "./utils-ebVpCYoF.cjs";
|
|
4
|
-
import { _ as
|
|
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-CPKDPMwY.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
|
|
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,
|
|
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.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { c as AgentRequestExecutorInfo, f as AgentTextRequest, s as AgentRequestExecutor, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-
|
|
2
|
-
import { f as AgentRuntimeOptions, l as AgentRunResult, o as AgentRunInit } from "./run-agent-
|
|
1
|
+
import { P as AgentExecutorDecisionRequest, c as AgentRequestExecutorInfo, f as AgentTextRequest, s as AgentRequestExecutor, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-BwdrDpO9.mjs";
|
|
2
|
+
import { f as AgentRuntimeOptions, l as AgentRunResult, o as AgentRunInit } from "./run-agent-D4MwS5GY.mjs";
|
|
3
3
|
import { t as MetaOfSnapshot } from "./utils-BnXdWih3.mjs";
|
|
4
|
-
import { _ as
|
|
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-tkymWz6X.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
|
|
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,
|
|
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,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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-DE430ZCa.mjs";
|
|
2
|
+
import { p as runToQuiescence, s as createAgentRuntime } from "./run-agent-DWZ1uyBJ.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-BH5e0XLK.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,
|
|
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
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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
|
|
@@ -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
|