@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,4 +1,4 @@
|
|
|
1
|
-
import { t as AgentCallUsage } from "./text-logic-
|
|
1
|
+
import { t as AgentCallUsage } from "./text-logic-j9hShB7d.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. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as AgentCallUsage } from "./text-logic-
|
|
1
|
+
import { t as AgentCallUsage } from "./text-logic-BwdrDpO9.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. */
|
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-
|
|
25
|
-
const require_setup_agent = require("./setup-agent-
|
|
26
|
-
const require_verify = require("./verify-
|
|
24
|
+
const require_event_log = require("./event-log-Bdww2l1D.cjs");
|
|
25
|
+
const require_setup_agent = require("./setup-agent-D0L8Anl_.cjs");
|
|
26
|
+
const require_verify = require("./verify-CS_xxvVU.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
|
package/dist/validate.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as AgentWorkflowConfig, g as FromConfigOptions, v as SchemaCompiler } from "./setup-agent-
|
|
2
|
-
import {
|
|
1
|
+
import { d as AgentWorkflowConfig, g as FromConfigOptions, v as SchemaCompiler } from "./setup-agent-yFFVXf5s.cjs";
|
|
2
|
+
import { u as ExplorePathsOptions } from "./verify-CPKDPMwY.cjs";
|
|
3
3
|
import { AnyActorLogic, AnyStateMachine } from "xstate";
|
|
4
4
|
//#region src/validate/validate-config.d.ts
|
|
5
5
|
/**
|
package/dist/validate.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as AgentWorkflowConfig, g as FromConfigOptions, v as SchemaCompiler } from "./setup-agent-
|
|
2
|
-
import {
|
|
1
|
+
import { d as AgentWorkflowConfig, g as FromConfigOptions, v as SchemaCompiler } from "./setup-agent-CPyg2ic7.mjs";
|
|
2
|
+
import { u as ExplorePathsOptions } from "./verify-tkymWz6X.mjs";
|
|
3
3
|
import { AnyActorLogic, AnyStateMachine } from "xstate";
|
|
4
4
|
//#region src/validate/validate-config.d.ts
|
|
5
5
|
/**
|
package/dist/validate.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { D as STREAM_TEXT_ACTOR, E as GENERATE_TEXT_ACTOR, T as DECIDE_ACTOR } from "./event-log-
|
|
2
|
-
import { i as setupAgentFromConfig } from "./setup-agent-
|
|
3
|
-
import { a as explorePaths, o as lintAgentMachine } from "./verify-
|
|
1
|
+
import { D as STREAM_TEXT_ACTOR, E as GENERATE_TEXT_ACTOR, T as DECIDE_ACTOR } from "./event-log-DE430ZCa.mjs";
|
|
2
|
+
import { i as setupAgentFromConfig } from "./setup-agent-BaffhCcM.mjs";
|
|
3
|
+
import { a as explorePaths, o as lintAgentMachine } from "./verify-BH5e0XLK.mjs";
|
|
4
4
|
import Ajv2020 from "ajv/dist/2020.js";
|
|
5
5
|
//#region schemas/agent-workflow.json
|
|
6
6
|
var agent_workflow_default = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { P as isTextLogic, U as getRegisteredAgentExecutionOptions, V as executorBoundLogics, X as getJsonSchemaSync,
|
|
2
|
-
import { d as getAcceptedEvents,
|
|
3
|
-
import { getNextTransitions, initialTransition, transition } from "xstate";
|
|
1
|
+
import { P as isTextLogic, U as getRegisteredAgentExecutionOptions, V as executorBoundLogics, X as getJsonSchemaSync, lt as isRecord, ut as AgentError } from "./event-log-DE430ZCa.mjs";
|
|
2
|
+
import { d as getAcceptedEvents, f as getHumanEventTypes, l as resolveDecision, n as acceptedDecisionOptions, p as isEventPattern, s as isDecisionLogic, t as AgentDecisionExhaustedError } from "./decision-DqO018Tp.mjs";
|
|
3
|
+
import { getNextTransitions, initialTransition, machineToJSON, transition } from "xstate";
|
|
4
4
|
//#region src/steps.ts
|
|
5
5
|
/**
|
|
6
6
|
* Internal: the pure `(state, event) => (nextState, requests)` view of an
|
|
@@ -79,12 +79,15 @@ function getAgentRequests(actions, { machine, ...options } = {}) {
|
|
|
79
79
|
const events = options.snapshot ? getAcceptedEvents(options.snapshot, {
|
|
80
80
|
events: options.events,
|
|
81
81
|
schemas: options.schemas,
|
|
82
|
-
eventTypes: allowedEventTypes
|
|
82
|
+
eventTypes: allowedEventTypes,
|
|
83
|
+
actor: "agent"
|
|
83
84
|
}) : [];
|
|
85
|
+
const humanEventTypes = options.snapshot ? getHumanEventTypes(options.snapshot) : /* @__PURE__ */ new Set();
|
|
84
86
|
return [{
|
|
85
87
|
...decisionRequest,
|
|
86
88
|
id: params.id,
|
|
87
|
-
events
|
|
89
|
+
events,
|
|
90
|
+
...decisionRequest.options ? { options: decisionRequest.options.filter((option) => !humanEventTypes.has(option.event.type)) } : {}
|
|
88
91
|
}];
|
|
89
92
|
}
|
|
90
93
|
const textLogic = isTextLogic(registeredLogic) ? registeredLogic : void 0;
|
|
@@ -335,6 +338,45 @@ function checkDecideWithoutEvents(ctx) {
|
|
|
335
338
|
}
|
|
336
339
|
return out;
|
|
337
340
|
}
|
|
341
|
+
function literalAllowedEvents(json, path, index) {
|
|
342
|
+
let node = json;
|
|
343
|
+
for (const key of path.split(".")) node = node?.states?.[key];
|
|
344
|
+
let input = normalizeInvokes(node?.invoke)[index]?.input;
|
|
345
|
+
if (isRecord(input) && typeof input["@expr"] === "string") try {
|
|
346
|
+
input = JSON.parse(input["@expr"]);
|
|
347
|
+
} catch {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
const allowedEvents = isRecord(input) ? input.allowedEvents : void 0;
|
|
351
|
+
return typeof allowedEvents === "string" ? [allowedEvents] : Array.isArray(allowedEvents) ? allowedEvents : void 0;
|
|
352
|
+
}
|
|
353
|
+
function handlesAsHuman(config, eventType) {
|
|
354
|
+
const transitions = config.on?.[eventType];
|
|
355
|
+
return (Array.isArray(transitions) ? transitions : [transitions]).some((transition) => !!transition && typeof transition === "object" && transition.meta?.actor === "human");
|
|
356
|
+
}
|
|
357
|
+
function checkDecideAllowsHumanEvent(ctx) {
|
|
358
|
+
const out = [];
|
|
359
|
+
for (const node of ctx.index.values()) for (const [index, invoke] of node.invokes.entries()) {
|
|
360
|
+
if (!isDecisionInvoke(invoke.src, ctx.actors)) continue;
|
|
361
|
+
const allowedEvents = literalAllowedEvents(ctx.json, node.path, index);
|
|
362
|
+
if (!allowedEvents) continue;
|
|
363
|
+
const configs = [
|
|
364
|
+
node.config,
|
|
365
|
+
...ancestorChain(node, ctx.index).map((ancestor) => ancestor.config),
|
|
366
|
+
ctx.config
|
|
367
|
+
];
|
|
368
|
+
for (const type of allowedEvents) {
|
|
369
|
+
if (typeof type !== "string" || isEventPattern(type) || !configs.some((config) => handlesAsHuman(config, type))) continue;
|
|
370
|
+
out.push({
|
|
371
|
+
code: "decide-allows-human-event",
|
|
372
|
+
severity: "error",
|
|
373
|
+
path: node.path,
|
|
374
|
+
message: `State '${node.path}' lets a decision choose '${type}', but a transition tagged 'meta: { actor: "human" }' handles it, so the model is never offered it. Remove '${type}' from 'allowedEvents', or drop the tag if a model may send it.`
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return out;
|
|
379
|
+
}
|
|
338
380
|
function checkDirectObjectSrc(ctx) {
|
|
339
381
|
const out = [];
|
|
340
382
|
for (const node of ctx.index.values()) for (const invoke of node.invokes) {
|
|
@@ -371,6 +413,7 @@ function checkInvokeWithoutOnError(ctx) {
|
|
|
371
413
|
}
|
|
372
414
|
const LINT_CHECKS = [
|
|
373
415
|
checkDecideWithoutEvents,
|
|
416
|
+
checkDecideAllowsHumanEvent,
|
|
374
417
|
checkDirectObjectSrc,
|
|
375
418
|
checkInvokeWithoutOnError
|
|
376
419
|
];
|
|
@@ -408,8 +451,15 @@ function lintAgentMachine(machine, options = {}) {
|
|
|
408
451
|
const config = machine.config ?? {};
|
|
409
452
|
const index = buildStateIndex(config);
|
|
410
453
|
const registered = getRegisteredAgentExecutionOptions(machine);
|
|
454
|
+
let json;
|
|
455
|
+
try {
|
|
456
|
+
json = machineToJSON(machine);
|
|
457
|
+
} catch {
|
|
458
|
+
json = void 0;
|
|
459
|
+
}
|
|
411
460
|
const ctx = {
|
|
412
461
|
config,
|
|
462
|
+
json,
|
|
413
463
|
index,
|
|
414
464
|
schemas: registered.schemas,
|
|
415
465
|
actors: registered.actors ?? machine.sources?.actors ?? {}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { u as ChosenEvent } from "./types-Dp5_Ru4R.cjs";
|
|
2
|
-
import { Q as AgentError } from "./text-logic-
|
|
2
|
+
import { Q as AgentError } from "./text-logic-j9hShB7d.cjs";
|
|
3
3
|
import { AnyMachineSnapshot, AnyStateMachine } from "xstate";
|
|
4
4
|
//#region src/verify.d.ts
|
|
5
5
|
/** Severity of an {@link AgentLintDiagnostic}. `error` findings fail CI/the CLI; `warning`s are advisory. */
|
|
@@ -10,7 +10,7 @@ type AgentLintSeverity = "error" | "warning";
|
|
|
10
10
|
* or config location, and `message` explains the problem and its remedy.
|
|
11
11
|
*/
|
|
12
12
|
interface AgentLintDiagnostic {
|
|
13
|
-
code: "decide-without-events" | "direct-object-src" | "invoke-without-on-error";
|
|
13
|
+
code: "decide-without-events" | "decide-allows-human-event" | "direct-object-src" | "invoke-without-on-error";
|
|
14
14
|
severity: AgentLintSeverity;
|
|
15
15
|
/** State path (`parent.child`) or config pointer (e.g. `(root)`, `context`) the finding is about. */
|
|
16
16
|
path: string;
|
|
@@ -212,6 +212,14 @@ interface SimulateAgentResult {
|
|
|
212
212
|
*/
|
|
213
213
|
declare function simulateAgent(machine: AnyStateMachine, options: SimulateAgentOptions): Promise<SimulateAgentResult>;
|
|
214
214
|
/** Options for {@link explorePaths}. */
|
|
215
|
+
/**
|
|
216
|
+
* The snapshot type the exploration callbacks (`payloads`, `dedupeBy`, a
|
|
217
|
+
* `canReach` predicate) receive. Import it from here rather than from your
|
|
218
|
+
* own `xstate`, which can be another version than the one this package uses.
|
|
219
|
+
*/
|
|
220
|
+
type ExploreSnapshot = AnyMachineSnapshot;
|
|
221
|
+
/** What {@link canReach} looks for: a state id or path, or a snapshot predicate. */
|
|
222
|
+
type CanReachTarget = string | ((snapshot: ExploreSnapshot) => boolean);
|
|
215
223
|
interface ExplorePathsOptions {
|
|
216
224
|
input?: unknown;
|
|
217
225
|
/** Max branch points (decisions + external-event forks) along any path. Default 8. */
|
|
@@ -274,7 +282,7 @@ interface ExplorePathsOptions {
|
|
|
274
282
|
* were not all tried, so it is listed in `unexpandedEvents`. A type with no
|
|
275
283
|
* schema at all is applied as `{ type }`.
|
|
276
284
|
*/
|
|
277
|
-
payloads?: (snapshot:
|
|
285
|
+
payloads?: (snapshot: ExploreSnapshot) => Partial<Record<string, Record<string, unknown>[]>>;
|
|
278
286
|
/**
|
|
279
287
|
* A projection of the snapshot that determines its future. Settled
|
|
280
288
|
* snapshots with an equal key are explored once (again only when reached
|
|
@@ -283,7 +291,7 @@ interface ExplorePathsOptions {
|
|
|
283
291
|
* a key that drops a field the machine reads makes the search unsound.
|
|
284
292
|
* Without it, every path is explored in full.
|
|
285
293
|
*/
|
|
286
|
-
dedupeBy?: (snapshot:
|
|
294
|
+
dedupeBy?: (snapshot: ExploreSnapshot) => string;
|
|
287
295
|
}
|
|
288
296
|
/** A single explored path's terminal outcome. */
|
|
289
297
|
interface AgentPathTerminal {
|
|
@@ -409,6 +417,6 @@ declare class AgentUnknownStateError extends AgentError {
|
|
|
409
417
|
* // violation.reachable → false is the safety proof
|
|
410
418
|
* ```
|
|
411
419
|
*/
|
|
412
|
-
declare function canReach(machine: AnyStateMachine, target:
|
|
420
|
+
declare function canReach(machine: AnyStateMachine, target: CanReachTarget, options?: ExplorePathsOptions): Promise<CanReachResult>;
|
|
413
421
|
//#endregion
|
|
414
|
-
export {
|
|
422
|
+
export { assertAgentMachine as _, AgentPathTerminal as a, lintAgentMachine as b, CanReachResult as c, ExploreSnapshot as d, LintAgentMachineOptions as f, SimulationTrailEntry as g, SimulationScript as h, AgentPathReport as i, CanReachTarget as l, SimulateAgentResult as m, AgentLintError as n, AgentUnknownStateError as o, SimulateAgentOptions as p, AgentLintSeverity as r, AssertAgentMachineOptions as s, AgentLintDiagnostic as t, ExplorePathsOptions as u, canReach as v, simulateAgent as x, explorePaths as y };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_event_log = require("./event-log-
|
|
2
|
-
const require_decision = require("./decision-
|
|
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/steps.ts
|
|
5
5
|
/**
|
|
@@ -79,12 +79,15 @@ function getAgentRequests(actions, { machine, ...options } = {}) {
|
|
|
79
79
|
const events = options.snapshot ? require_decision.getAcceptedEvents(options.snapshot, {
|
|
80
80
|
events: options.events,
|
|
81
81
|
schemas: options.schemas,
|
|
82
|
-
eventTypes: allowedEventTypes
|
|
82
|
+
eventTypes: allowedEventTypes,
|
|
83
|
+
actor: "agent"
|
|
83
84
|
}) : [];
|
|
85
|
+
const humanEventTypes = options.snapshot ? require_decision.getHumanEventTypes(options.snapshot) : /* @__PURE__ */ new Set();
|
|
84
86
|
return [{
|
|
85
87
|
...decisionRequest,
|
|
86
88
|
id: params.id,
|
|
87
|
-
events
|
|
89
|
+
events,
|
|
90
|
+
...decisionRequest.options ? { options: decisionRequest.options.filter((option) => !humanEventTypes.has(option.event.type)) } : {}
|
|
88
91
|
}];
|
|
89
92
|
}
|
|
90
93
|
const textLogic = require_event_log.isTextLogic(registeredLogic) ? registeredLogic : void 0;
|
|
@@ -335,6 +338,45 @@ function checkDecideWithoutEvents(ctx) {
|
|
|
335
338
|
}
|
|
336
339
|
return out;
|
|
337
340
|
}
|
|
341
|
+
function literalAllowedEvents(json, path, index) {
|
|
342
|
+
let node = json;
|
|
343
|
+
for (const key of path.split(".")) node = node?.states?.[key];
|
|
344
|
+
let input = normalizeInvokes(node?.invoke)[index]?.input;
|
|
345
|
+
if (require_event_log.isRecord(input) && typeof input["@expr"] === "string") try {
|
|
346
|
+
input = JSON.parse(input["@expr"]);
|
|
347
|
+
} catch {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
const allowedEvents = require_event_log.isRecord(input) ? input.allowedEvents : void 0;
|
|
351
|
+
return typeof allowedEvents === "string" ? [allowedEvents] : Array.isArray(allowedEvents) ? allowedEvents : void 0;
|
|
352
|
+
}
|
|
353
|
+
function handlesAsHuman(config, eventType) {
|
|
354
|
+
const transitions = config.on?.[eventType];
|
|
355
|
+
return (Array.isArray(transitions) ? transitions : [transitions]).some((transition) => !!transition && typeof transition === "object" && transition.meta?.actor === "human");
|
|
356
|
+
}
|
|
357
|
+
function checkDecideAllowsHumanEvent(ctx) {
|
|
358
|
+
const out = [];
|
|
359
|
+
for (const node of ctx.index.values()) for (const [index, invoke] of node.invokes.entries()) {
|
|
360
|
+
if (!isDecisionInvoke(invoke.src, ctx.actors)) continue;
|
|
361
|
+
const allowedEvents = literalAllowedEvents(ctx.json, node.path, index);
|
|
362
|
+
if (!allowedEvents) continue;
|
|
363
|
+
const configs = [
|
|
364
|
+
node.config,
|
|
365
|
+
...ancestorChain(node, ctx.index).map((ancestor) => ancestor.config),
|
|
366
|
+
ctx.config
|
|
367
|
+
];
|
|
368
|
+
for (const type of allowedEvents) {
|
|
369
|
+
if (typeof type !== "string" || require_decision.isEventPattern(type) || !configs.some((config) => handlesAsHuman(config, type))) continue;
|
|
370
|
+
out.push({
|
|
371
|
+
code: "decide-allows-human-event",
|
|
372
|
+
severity: "error",
|
|
373
|
+
path: node.path,
|
|
374
|
+
message: `State '${node.path}' lets a decision choose '${type}', but a transition tagged 'meta: { actor: "human" }' handles it, so the model is never offered it. Remove '${type}' from 'allowedEvents', or drop the tag if a model may send it.`
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return out;
|
|
379
|
+
}
|
|
338
380
|
function checkDirectObjectSrc(ctx) {
|
|
339
381
|
const out = [];
|
|
340
382
|
for (const node of ctx.index.values()) for (const invoke of node.invokes) {
|
|
@@ -371,6 +413,7 @@ function checkInvokeWithoutOnError(ctx) {
|
|
|
371
413
|
}
|
|
372
414
|
const LINT_CHECKS = [
|
|
373
415
|
checkDecideWithoutEvents,
|
|
416
|
+
checkDecideAllowsHumanEvent,
|
|
374
417
|
checkDirectObjectSrc,
|
|
375
418
|
checkInvokeWithoutOnError
|
|
376
419
|
];
|
|
@@ -408,8 +451,15 @@ function lintAgentMachine(machine, options = {}) {
|
|
|
408
451
|
const config = machine.config ?? {};
|
|
409
452
|
const index = buildStateIndex(config);
|
|
410
453
|
const registered = require_event_log.getRegisteredAgentExecutionOptions(machine);
|
|
454
|
+
let json;
|
|
455
|
+
try {
|
|
456
|
+
json = (0, xstate.machineToJSON)(machine);
|
|
457
|
+
} catch {
|
|
458
|
+
json = void 0;
|
|
459
|
+
}
|
|
411
460
|
const ctx = {
|
|
412
461
|
config,
|
|
462
|
+
json,
|
|
413
463
|
index,
|
|
414
464
|
schemas: registered.schemas,
|
|
415
465
|
actors: registered.actors ?? machine.sources?.actors ?? {}
|
|
@@ -716,7 +766,7 @@ const MAX_ADVANCE_STEPS = 1e3;
|
|
|
716
766
|
const FINITE_PAYLOAD_CAP = 64;
|
|
717
767
|
const DEFAULT_MAX_NODES = 1e5;
|
|
718
768
|
function finiteDomain(schema) {
|
|
719
|
-
if (!
|
|
769
|
+
if (!require_event_log.isRecord(schema)) return;
|
|
720
770
|
if ("const" in schema) return [schema["const"]];
|
|
721
771
|
if (Array.isArray(schema["enum"])) return schema["enum"];
|
|
722
772
|
const union = schema["anyOf"] ?? schema["oneOf"];
|
|
@@ -733,8 +783,8 @@ function finitePayloads(jsonSchema) {
|
|
|
733
783
|
payloads: [{}],
|
|
734
784
|
complete: false
|
|
735
785
|
};
|
|
736
|
-
if (!
|
|
737
|
-
const properties =
|
|
786
|
+
if (!require_event_log.isRecord(jsonSchema) || jsonSchema["type"] !== "object" && !require_event_log.isRecord(jsonSchema["properties"])) return bare;
|
|
787
|
+
const properties = require_event_log.isRecord(jsonSchema["properties"]) ? jsonSchema["properties"] : {};
|
|
738
788
|
const required = new Set(Array.isArray(jsonSchema["required"]) ? jsonSchema["required"] : []);
|
|
739
789
|
if ([...required].some((key) => key !== "type" && !(key in properties))) return bare;
|
|
740
790
|
let product = [{}];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { u as ChosenEvent } from "./types-Dp5_Ru4R.mjs";
|
|
2
|
-
import { Q as AgentError } from "./text-logic-
|
|
2
|
+
import { Q as AgentError } from "./text-logic-BwdrDpO9.mjs";
|
|
3
3
|
import { AnyMachineSnapshot, AnyStateMachine } from "xstate";
|
|
4
4
|
//#region src/verify.d.ts
|
|
5
5
|
/** Severity of an {@link AgentLintDiagnostic}. `error` findings fail CI/the CLI; `warning`s are advisory. */
|
|
@@ -10,7 +10,7 @@ type AgentLintSeverity = "error" | "warning";
|
|
|
10
10
|
* or config location, and `message` explains the problem and its remedy.
|
|
11
11
|
*/
|
|
12
12
|
interface AgentLintDiagnostic {
|
|
13
|
-
code: "decide-without-events" | "direct-object-src" | "invoke-without-on-error";
|
|
13
|
+
code: "decide-without-events" | "decide-allows-human-event" | "direct-object-src" | "invoke-without-on-error";
|
|
14
14
|
severity: AgentLintSeverity;
|
|
15
15
|
/** State path (`parent.child`) or config pointer (e.g. `(root)`, `context`) the finding is about. */
|
|
16
16
|
path: string;
|
|
@@ -212,6 +212,14 @@ interface SimulateAgentResult {
|
|
|
212
212
|
*/
|
|
213
213
|
declare function simulateAgent(machine: AnyStateMachine, options: SimulateAgentOptions): Promise<SimulateAgentResult>;
|
|
214
214
|
/** Options for {@link explorePaths}. */
|
|
215
|
+
/**
|
|
216
|
+
* The snapshot type the exploration callbacks (`payloads`, `dedupeBy`, a
|
|
217
|
+
* `canReach` predicate) receive. Import it from here rather than from your
|
|
218
|
+
* own `xstate`, which can be another version than the one this package uses.
|
|
219
|
+
*/
|
|
220
|
+
type ExploreSnapshot = AnyMachineSnapshot;
|
|
221
|
+
/** What {@link canReach} looks for: a state id or path, or a snapshot predicate. */
|
|
222
|
+
type CanReachTarget = string | ((snapshot: ExploreSnapshot) => boolean);
|
|
215
223
|
interface ExplorePathsOptions {
|
|
216
224
|
input?: unknown;
|
|
217
225
|
/** Max branch points (decisions + external-event forks) along any path. Default 8. */
|
|
@@ -274,7 +282,7 @@ interface ExplorePathsOptions {
|
|
|
274
282
|
* were not all tried, so it is listed in `unexpandedEvents`. A type with no
|
|
275
283
|
* schema at all is applied as `{ type }`.
|
|
276
284
|
*/
|
|
277
|
-
payloads?: (snapshot:
|
|
285
|
+
payloads?: (snapshot: ExploreSnapshot) => Partial<Record<string, Record<string, unknown>[]>>;
|
|
278
286
|
/**
|
|
279
287
|
* A projection of the snapshot that determines its future. Settled
|
|
280
288
|
* snapshots with an equal key are explored once (again only when reached
|
|
@@ -283,7 +291,7 @@ interface ExplorePathsOptions {
|
|
|
283
291
|
* a key that drops a field the machine reads makes the search unsound.
|
|
284
292
|
* Without it, every path is explored in full.
|
|
285
293
|
*/
|
|
286
|
-
dedupeBy?: (snapshot:
|
|
294
|
+
dedupeBy?: (snapshot: ExploreSnapshot) => string;
|
|
287
295
|
}
|
|
288
296
|
/** A single explored path's terminal outcome. */
|
|
289
297
|
interface AgentPathTerminal {
|
|
@@ -409,6 +417,6 @@ declare class AgentUnknownStateError extends AgentError {
|
|
|
409
417
|
* // violation.reachable → false is the safety proof
|
|
410
418
|
* ```
|
|
411
419
|
*/
|
|
412
|
-
declare function canReach(machine: AnyStateMachine, target:
|
|
420
|
+
declare function canReach(machine: AnyStateMachine, target: CanReachTarget, options?: ExplorePathsOptions): Promise<CanReachResult>;
|
|
413
421
|
//#endregion
|
|
414
|
-
export {
|
|
422
|
+
export { assertAgentMachine as _, AgentPathTerminal as a, lintAgentMachine as b, CanReachResult as c, ExploreSnapshot as d, LintAgentMachineOptions as f, SimulationTrailEntry as g, SimulationScript as h, AgentPathReport as i, CanReachTarget as l, SimulateAgentResult as m, AgentLintError as n, AgentUnknownStateError as o, SimulateAgentOptions as p, AgentLintSeverity as r, AssertAgentMachineOptions as s, AgentLintDiagnostic as t, ExplorePathsOptions as u, canReach as v, simulateAgent as x, explorePaths as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statelyai/agent",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.31",
|
|
4
4
|
"description": "Make invalid agent actions impossible. Agent logic as state machines: deterministic, inspectable, resumable, runs anywhere.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -21,12 +21,41 @@
|
|
|
21
21
|
"files": [
|
|
22
22
|
"dist",
|
|
23
23
|
"schemas",
|
|
24
|
-
"skills"
|
|
24
|
+
"skills",
|
|
25
|
+
"CHANGELOG.md"
|
|
25
26
|
],
|
|
26
27
|
"type": "module",
|
|
27
28
|
"main": "dist/index.cjs",
|
|
28
29
|
"module": "dist/index.mjs",
|
|
29
30
|
"types": "dist/index.d.mts",
|
|
31
|
+
"typesVersions": {
|
|
32
|
+
"*": {
|
|
33
|
+
"ai-sdk": [
|
|
34
|
+
"./dist/ai-sdk.d.mts"
|
|
35
|
+
],
|
|
36
|
+
"log": [
|
|
37
|
+
"./dist/log.d.mts"
|
|
38
|
+
],
|
|
39
|
+
"machines": [
|
|
40
|
+
"./dist/machines.d.mts"
|
|
41
|
+
],
|
|
42
|
+
"openai": [
|
|
43
|
+
"./dist/openai.d.mts"
|
|
44
|
+
],
|
|
45
|
+
"otel": [
|
|
46
|
+
"./dist/otel.d.mts"
|
|
47
|
+
],
|
|
48
|
+
"tanstack-ai": [
|
|
49
|
+
"./dist/tanstack-ai.d.mts"
|
|
50
|
+
],
|
|
51
|
+
"testing": [
|
|
52
|
+
"./dist/testing.d.mts"
|
|
53
|
+
],
|
|
54
|
+
"validate": [
|
|
55
|
+
"./dist/validate.d.mts"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
},
|
|
30
59
|
"exports": {
|
|
31
60
|
".": {
|
|
32
61
|
"import": {
|
|
@@ -132,6 +161,7 @@
|
|
|
132
161
|
"@langchain/core": "^1.2.17",
|
|
133
162
|
"@langchain/openai": "^1.6.2",
|
|
134
163
|
"@mastra/core": "^1.75.0",
|
|
164
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
135
165
|
"@opentelemetry/api": "^1.9.1",
|
|
136
166
|
"@opentelemetry/context-async-hooks": "^2.12.0",
|
|
137
167
|
"@opentelemetry/sdk-trace-base": "^2.12.0",
|
|
@@ -159,7 +189,7 @@
|
|
|
159
189
|
"peerDependencies": {
|
|
160
190
|
"@opentelemetry/api": "^1",
|
|
161
191
|
"@tanstack/ai": ">=0.66.0 <1",
|
|
162
|
-
"ai": "^7.0.
|
|
192
|
+
"ai": "^7.0.128",
|
|
163
193
|
"ajv": "^8.20.0",
|
|
164
194
|
"openai": ">=5.0.0 <8",
|
|
165
195
|
"xstate": "6.0.0-alpha.69"
|
|
@@ -182,7 +212,7 @@
|
|
|
182
212
|
}
|
|
183
213
|
},
|
|
184
214
|
"engines": {
|
|
185
|
-
"node": ">=22
|
|
215
|
+
"node": ">=22"
|
|
186
216
|
},
|
|
187
217
|
"scripts": {
|
|
188
218
|
"build": "tsdown",
|
package/readme.md
CHANGED
|
@@ -14,18 +14,18 @@ Environment and policy:
|
|
|
14
14
|
|
|
15
15
|
- The environment is code you own and can verify; the policy is something a model can write inside it.
|
|
16
16
|
- The environment holds the rules and invariants as TypeScript states and guards, fixed and checked with `canReach`.
|
|
17
|
-
- The policy is a JSON machine a model can author and improve from traces, gated before it runs and promoted only on a measured gain. See [Environment and policy](docs/environment-and-policy.md).
|
|
17
|
+
- The policy is a JSON machine a model can author and improve from traces, gated before it runs and promoted only on a measured gain. See [Environment and policy](https://github.com/statelyai/agent/blob/next/docs/environment-and-policy.md).
|
|
18
18
|
|
|
19
19
|
Stately Agent 2 is in alpha. APIs may change before the stable release.
|
|
20
20
|
|
|
21
|
-
[Documentation](https://stately.ai/docs/packages/agent) · [Examples](examples/README.md) · [XState](https://github.com/statelyai/xstate)
|
|
21
|
+
[Documentation](https://stately.ai/docs/packages/agent) · [Examples](https://github.com/statelyai/agent/blob/next/examples/README.md) · [XState](https://github.com/statelyai/xstate)
|
|
22
22
|
|
|
23
23
|
## Four starting points
|
|
24
24
|
|
|
25
|
-
- **Author a new agent.** Build a machine from states, decisions, and typed requests; run it locally with `runAgent`, test it with no API key, then use it in any framework or runtime with zero machine changes. See the [Quickstart](docs/quickstart.md) and [Use in any stack](docs/any-stack.md).
|
|
26
|
-
- **Retrofit an existing agent.** Turn a `while` loop into a machine: your SDK calls, tools, and retry code become the executors; the machine replaces only the control flow. See [Migrating from a hand-rolled loop](docs/from-a-loop.md).
|
|
27
|
-
- **Copy a known pattern.** ReAct, reflection, plan-and-execute, RAG, supervisor, and more, each a single runnable file you lift in 60 seconds. See [Agent patterns](docs/patterns.md).
|
|
28
|
-
- **Let an agent improve its own logic.** Keep the rules in a fixed TypeScript environment and let a model rewrite the JSON policy inside it, gated by `verifyAgentConfig` and promoted only when held-out scenarios improve. See [Environment and policy](docs/environment-and-policy.md) and the [`improve-machine` skill](skills/improve-machine/SKILL.md).
|
|
25
|
+
- **Author a new agent.** Build a machine from states, decisions, and typed requests; run it locally with `runAgent`, test it with no API key, then use it in any framework or runtime with zero machine changes. See the [Quickstart](https://github.com/statelyai/agent/blob/next/docs/quickstart.md) and [Use in any stack](https://github.com/statelyai/agent/blob/next/docs/any-stack.md).
|
|
26
|
+
- **Retrofit an existing agent.** Turn a `while` loop into a machine: your SDK calls, tools, and retry code become the executors; the machine replaces only the control flow. See [Migrating from a hand-rolled loop](https://github.com/statelyai/agent/blob/next/docs/from-a-loop.md).
|
|
27
|
+
- **Copy a known pattern.** ReAct, reflection, plan-and-execute, RAG, supervisor, and more, each a single runnable file you lift in 60 seconds. See [Agent patterns](https://github.com/statelyai/agent/blob/next/docs/patterns.md).
|
|
28
|
+
- **Let an agent improve its own logic.** Keep the rules in a fixed TypeScript environment and let a model rewrite the JSON policy inside it, gated by `verifyAgentConfig` and promoted only when held-out scenarios improve. See [Environment and policy](https://github.com/statelyai/agent/blob/next/docs/environment-and-policy.md) and the [`improve-machine` skill](https://github.com/statelyai/agent/blob/next/skills/improve-machine/SKILL.md).
|
|
29
29
|
|
|
30
30
|
## Install
|
|
31
31
|
|
|
@@ -40,7 +40,7 @@ XState is pinned while its experimental durable restoration API evolves.
|
|
|
40
40
|
For the optional Vercel AI SDK executor:
|
|
41
41
|
|
|
42
42
|
```sh
|
|
43
|
-
pnpm add ai@^7 @ai-sdk/openai@^4
|
|
43
|
+
pnpm add ai@^7.0.128 @ai-sdk/openai@^4
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
For the optional raw OpenAI SDK executor (`@statelyai/agent/openai`):
|
|
@@ -55,13 +55,43 @@ For the optional TanStack AI executor (`@statelyai/agent/tanstack-ai`):
|
|
|
55
55
|
pnpm add @tanstack/ai @tanstack/ai-openai
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
Classification, grading, relevance, and yes/no checks are judgments: call the AI SDK's `experimental_decide` with `@ai-sdk/typesafe-ai` (`pnpm add ai @ai-sdk/typesafe-ai`) from an ordinary actor; see [Judgments with the AI SDK](docs/judgments.md).
|
|
58
|
+
Classification, grading, relevance, and yes/no checks are judgments: call the AI SDK's `experimental_decide` with `@ai-sdk/typesafe-ai` (`pnpm add ai @ai-sdk/typesafe-ai`) from an ordinary actor; see [Judgments with the AI SDK](https://github.com/statelyai/agent/blob/next/docs/judgments.md).
|
|
59
|
+
|
|
60
|
+
Upgrading from an earlier alpha: see [Upgrading between alphas](https://github.com/statelyai/agent/blob/next/docs/upgrading.md). Every release's notes are in `CHANGELOG.md`, which ships in the package.
|
|
59
61
|
|
|
60
62
|
Requirements:
|
|
61
63
|
|
|
62
|
-
- Node 22
|
|
63
|
-
-
|
|
64
|
-
-
|
|
64
|
+
- Node 22 or newer, and XState exactly `6.0.0-alpha.69`.
|
|
65
|
+
- TypeScript 5.4 or newer. Older versions accept the code, but callback parameters in `createMachine` silently become `any`.
|
|
66
|
+
- A [Standard Schema](https://standardschema.dev) library: zod 4, zod 3.24 or newer, Valibot, or ArkType. `setupAgent` throws `invalid-schema` for zod 3.23 and earlier.
|
|
67
|
+
- The package is ESM-first. CommonJS builds are published too, so `require()` works. Subpath imports (`@statelyai/agent/testing`) resolve under every `moduleResolution`, including `node`.
|
|
68
|
+
- `@statelyai/agent/ai-sdk` needs `ai` 7.0.128 or newer. Provider packages must match your `ai` major: `@ai-sdk/openai@^4` pairs with `ai@^7`. A bare `@ai-sdk/openai` resolves to `@latest`, which can mismatch the `ai` peer. `@statelyai/agent/openai` needs `openai` 5 or newer.
|
|
69
|
+
|
|
70
|
+
An app that already uses XState 4 or 5 keeps it: put the agent in its own workspace package. See [Use in an XState 4 or 5 app](https://github.com/statelyai/agent/blob/next/docs/xstate-4-and-5-apps.md). If both versions land in one `node_modules`, the package fails with errors that do not mention a version:
|
|
71
|
+
|
|
72
|
+
| Error | Cause |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| `createAsyncLogic is not a function` | `xstate` resolved to 4 or 5 from CommonJS |
|
|
75
|
+
| `Cannot find module '…/node_modules/xstate/durable'` | `xstate` resolved to 4 or 5 from ESM |
|
|
76
|
+
| `unmet peer dependency "xstate@6.0.0-alpha.69"` (pnpm, npm) or `has incorrect peer dependency "xstate@6.0.0-alpha.69"` (yarn 1) | The install's only warning of the two above |
|
|
77
|
+
|
|
78
|
+
## Agent skills
|
|
79
|
+
|
|
80
|
+
The package ships agent skills in `node_modules/@statelyai/agent/skills/`. Copy them into your coding agent's skills directory (for Claude Code, `.claude/skills/`):
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
mkdir -p .claude/skills
|
|
84
|
+
cp -R node_modules/@statelyai/agent/skills/* .claude/skills/
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
| Skill | What it does |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| [`graph-engineering`](https://github.com/statelyai/agent/blob/next/skills/graph-engineering/SKILL.md) | Finds which step a project is at and routes to the next skill |
|
|
90
|
+
| [`loop-to-machine`](https://github.com/statelyai/agent/blob/next/skills/loop-to-machine/SKILL.md) | Converts existing agent code into a machine and checks parity with `compareRuns` |
|
|
91
|
+
| [`generate-machine`](https://github.com/statelyai/agent/blob/next/skills/generate-machine/SKILL.md) | Authors a JSON policy machine from scratch and runs `verifyAgentConfig` |
|
|
92
|
+
| [`add-traces`](https://github.com/statelyai/agent/blob/next/skills/add-traces/SKILL.md) | Stamps and persists every run so it replays |
|
|
93
|
+
| [`add-evals`](https://github.com/statelyai/agent/blob/next/skills/add-evals/SKILL.md) | Writes evals per state, at the cheapest level that catches the failure |
|
|
94
|
+
| [`improve-machine`](https://github.com/statelyai/agent/blob/next/skills/improve-machine/SKILL.md) | Improves a policy from traces and hands the change to a person as a pull request |
|
|
65
95
|
|
|
66
96
|
## Quick start
|
|
67
97
|
|
|
@@ -159,11 +189,11 @@ const liveResult = await runAgent(refundMachine, {
|
|
|
159
189
|
});
|
|
160
190
|
```
|
|
161
191
|
|
|
162
|
-
`createAiSdkExecutors(refundMachine)` reads the `models` declared in `setupAgent({ models })`, which also type the machine's model refs. `createAiSdkExecutors({ models })` still works when the host owns the map. Executors are always explicit, and core does not import the AI SDK. See [Models and providers](docs/models-and-providers.md) and [Hosts and executors](docs/hosts.md).
|
|
192
|
+
`createAiSdkExecutors(refundMachine)` reads the `models` declared in `setupAgent({ models })`, which also type the machine's model refs. `createAiSdkExecutors({ models })` still works when the host owns the map. Executors are always explicit, and core does not import the AI SDK. See [Models and providers](https://github.com/statelyai/agent/blob/next/docs/models-and-providers.md) and [Hosts and executors](https://github.com/statelyai/agent/blob/next/docs/hosts.md).
|
|
163
193
|
|
|
164
|
-
For a machine with several requests, the executor routes on `request.name`, or `MockLanguageModelV3` from `ai/test` stands in for the provider behind `createAiSdkExecutors`. See [Evals](docs/evals.md#testing-without-a-provider).
|
|
194
|
+
For a machine with several requests, the executor routes on `request.name`, or `MockLanguageModelV3` from `ai/test` stands in for the provider behind `createAiSdkExecutors`. See [Evals](https://github.com/statelyai/agent/blob/next/docs/evals.md#testing-without-a-provider).
|
|
165
195
|
|
|
166
|
-
A host that needs the transition loop itself (a durable object, events pushed mid-run, a custom checkpoint policy) uses `createAgentRuntime` directly. See [Write your own host loop](docs/hosts.md#write-your-own-host-loop).
|
|
196
|
+
A host that needs the transition loop itself (a durable object, events pushed mid-run, a custom checkpoint policy) uses `createAgentRuntime` directly. See [Write your own host loop](https://github.com/statelyai/agent/blob/next/docs/hosts.md#write-your-own-host-loop).
|
|
167
197
|
|
|
168
198
|
## Architecture
|
|
169
199
|
|
|
@@ -181,38 +211,38 @@ The machine never talks to a model directly, so swapping `createAiSdkExecutors`
|
|
|
181
211
|
|
|
182
212
|
The example above has one model decision and two final outcomes. Real machines add approval states, retries, parallel work, child agents, and long-running waits without changing how control flow is represented.
|
|
183
213
|
|
|
184
|
-
The core concepts (machines owning control flow, bounded model decisions, typed requests, host-run executors, and native XState snapshots) are in the [documentation overview](docs/index.md).
|
|
214
|
+
The core concepts (machines owning control flow, bounded model decisions, typed requests, host-run executors, and native XState snapshots) are in the [documentation overview](https://github.com/statelyai/agent/blob/next/docs/index.md).
|
|
185
215
|
|
|
186
216
|
## Examples
|
|
187
217
|
|
|
188
218
|
<!-- starter examples derived from examples/*/metadata.json and examples/index.ts -->
|
|
189
219
|
|
|
190
|
-
- [Twenty Questions](examples/twenty-questions) shows a model choosing legal events in a loop.
|
|
191
|
-
- [Chameleon](examples/chameleon) combines hidden information, sequential turns, and a human vote.
|
|
192
|
-
- [Snapshot migration](examples/snapshot-migration) uses XState's native `version` and `migrate` contract.
|
|
193
|
-
- [Portable XState loop](examples/portable-xstate-loop) runs the artifact through native transitions and effects.
|
|
194
|
-
- [Application-owned storage](examples/file-snapshot-store) persists native XState snapshots in application code.
|
|
195
|
-
- [Tool calling](examples/review-tool-calls) keeps tools and message history in the AI SDK's native format.
|
|
196
|
-
- [Ticket triage](examples/triage) returns structured data from a model request.
|
|
197
|
-
- [JSON agent](examples/json-agent) runs a machine defined as data.
|
|
220
|
+
- [Twenty Questions](https://github.com/statelyai/agent/tree/next/examples/twenty-questions) shows a model choosing legal events in a loop.
|
|
221
|
+
- [Chameleon](https://github.com/statelyai/agent/tree/next/examples/chameleon) combines hidden information, sequential turns, and a human vote.
|
|
222
|
+
- [Snapshot migration](https://github.com/statelyai/agent/tree/next/examples/snapshot-migration) uses XState's native `version` and `migrate` contract.
|
|
223
|
+
- [Portable XState loop](https://github.com/statelyai/agent/tree/next/examples/portable-xstate-loop) runs the artifact through native transitions and effects.
|
|
224
|
+
- [Application-owned storage](https://github.com/statelyai/agent/tree/next/examples/file-snapshot-store) persists native XState snapshots in application code.
|
|
225
|
+
- [Tool calling](https://github.com/statelyai/agent/tree/next/examples/review-tool-calls) keeps tools and message history in the AI SDK's native format.
|
|
226
|
+
- [Ticket triage](https://github.com/statelyai/agent/tree/next/examples/triage) returns structured data from a model request.
|
|
227
|
+
- [JSON agent](https://github.com/statelyai/agent/tree/next/examples/json-agent) runs a machine defined as data.
|
|
198
228
|
|
|
199
|
-
See [all examples](examples/README.md).
|
|
229
|
+
See [all examples](https://github.com/statelyai/agent/blob/next/examples/README.md).
|
|
200
230
|
|
|
201
231
|
## Related
|
|
202
232
|
|
|
203
|
-
- [Machines](docs/machines.md)
|
|
204
|
-
- [Text requests](docs/text-requests.md)
|
|
205
|
-
- [Decisions](docs/decisions.md)
|
|
206
|
-
- [Human in the loop](docs/human-in-the-loop.md)
|
|
207
|
-
- [Testing and verification](docs/verify.md)
|
|
208
|
-
- [Evals](docs/evals.md)
|
|
209
|
-
- [Generating machines with an LLM](docs/generate-machines.md)
|
|
210
|
-
- [Hosts and executors](docs/hosts.md)
|
|
211
|
-
- [Models and providers](docs/models-and-providers.md)
|
|
212
|
-
- [Use in any stack](docs/any-stack.md)
|
|
213
|
-
- [Persistence](docs/persistence.md)
|
|
214
|
-
- [Observability](docs/observability.md)
|
|
215
|
-
- [Usage and budgets](docs/usage-and-budgets.md)
|
|
216
|
-
- [Agent patterns](docs/patterns.md)
|
|
217
|
-
- [Migrating from a hand-rolled loop](docs/from-a-loop.md)
|
|
218
|
-
- [Coming from LangGraph](docs/langgraph-comparison.md)
|
|
233
|
+
- [Machines](https://github.com/statelyai/agent/blob/next/docs/machines.md)
|
|
234
|
+
- [Text requests](https://github.com/statelyai/agent/blob/next/docs/text-requests.md)
|
|
235
|
+
- [Decisions](https://github.com/statelyai/agent/blob/next/docs/decisions.md)
|
|
236
|
+
- [Human in the loop](https://github.com/statelyai/agent/blob/next/docs/human-in-the-loop.md)
|
|
237
|
+
- [Testing and verification](https://github.com/statelyai/agent/blob/next/docs/verify.md)
|
|
238
|
+
- [Evals](https://github.com/statelyai/agent/blob/next/docs/evals.md)
|
|
239
|
+
- [Generating machines with an LLM](https://github.com/statelyai/agent/blob/next/docs/generate-machines.md)
|
|
240
|
+
- [Hosts and executors](https://github.com/statelyai/agent/blob/next/docs/hosts.md)
|
|
241
|
+
- [Models and providers](https://github.com/statelyai/agent/blob/next/docs/models-and-providers.md)
|
|
242
|
+
- [Use in any stack](https://github.com/statelyai/agent/blob/next/docs/any-stack.md)
|
|
243
|
+
- [Persistence](https://github.com/statelyai/agent/blob/next/docs/persistence.md)
|
|
244
|
+
- [Observability](https://github.com/statelyai/agent/blob/next/docs/observability.md)
|
|
245
|
+
- [Usage and budgets](https://github.com/statelyai/agent/blob/next/docs/usage-and-budgets.md)
|
|
246
|
+
- [Agent patterns](https://github.com/statelyai/agent/blob/next/docs/patterns.md)
|
|
247
|
+
- [Migrating from a hand-rolled loop](https://github.com/statelyai/agent/blob/next/docs/from-a-loop.md)
|
|
248
|
+
- [Coming from LangGraph](https://github.com/statelyai/agent/blob/next/docs/langgraph-comparison.md)
|