@statelyai/agent 2.0.0-alpha.10 → 2.0.0-alpha.11

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 (45) hide show
  1. package/dist/adapter.cjs +15 -0
  2. package/dist/adapter.d.cts +4 -0
  3. package/dist/adapter.d.mts +4 -0
  4. package/dist/adapter.mjs +2 -0
  5. package/dist/ai-sdk.cjs +66 -102
  6. package/dist/ai-sdk.d.cts +5 -115
  7. package/dist/ai-sdk.d.mts +5 -115
  8. package/dist/ai-sdk.mjs +64 -91
  9. package/dist/decision-C3k4ve51.mjs +227 -0
  10. package/dist/decision-D8wJrM8W.cjs +286 -0
  11. package/dist/{decision-b-lkcs4L.cjs → events-CRQj3VtP.cjs} +10 -295
  12. package/dist/{decision-CQdrKc8k.mjs → events-JiVPYrct.mjs} +10 -229
  13. package/dist/index.cjs +2521 -52
  14. package/dist/index.d.cts +1029 -9
  15. package/dist/index.d.mts +1029 -9
  16. package/dist/index.mjs +2493 -4
  17. package/dist/openai-compat.cjs +23 -33
  18. package/dist/openai-compat.d.cts +3 -42
  19. package/dist/openai-compat.d.mts +3 -42
  20. package/dist/openai-compat.mjs +20 -24
  21. package/dist/steps-BALp1eZo.d.mts +198 -0
  22. package/dist/steps-CVe54GPP.cjs +420 -0
  23. package/dist/steps-CkyyyuHd.mjs +379 -0
  24. package/dist/steps-MjnQI4aB.d.cts +198 -0
  25. package/dist/steps.cjs +12 -0
  26. package/dist/steps.d.cts +3 -0
  27. package/dist/steps.d.mts +3 -0
  28. package/dist/steps.mjs +3 -0
  29. package/dist/{text-logic-C7WJpCIc.d.mts → text-logic-CaKqgX4Y.d.mts} +8 -8
  30. package/dist/{text-logic-CZjyACzQ.d.cts → text-logic-Ckhr2kKC.d.cts} +8 -8
  31. package/package.json +27 -4
  32. package/readme.md +18 -8
  33. package/schemas/agent-workflow.json +4 -5
  34. package/dist/cli.cjs +0 -64
  35. package/dist/cli.d.cts +0 -1
  36. package/dist/cli.d.mts +0 -1
  37. package/dist/cli.mjs +0 -65
  38. package/dist/run-agent-BFMkuI1F.cjs +0 -1599
  39. package/dist/run-agent-BVMd--1l.d.cts +0 -1103
  40. package/dist/run-agent-BoAOq_0Z.mjs +0 -1540
  41. package/dist/run-agent-DzYJb3CK.d.mts +0 -1103
  42. package/dist/src-D-77Ha5p.cjs +0 -1087
  43. package/dist/src-DUeIFjv-.mjs +0 -1016
  44. /package/dist/{utils-Dri7aeEG.d.cts → utils-BYqT_Dyv.d.cts} +0 -0
  45. /package/dist/{utils-Y6GDRGGE.d.mts → utils-Do5wIJrh.d.mts} +0 -0
@@ -4,8 +4,6 @@ import { AnyMachineSnapshot, AsyncActorLogic, EventObject, LogicActorLogic, Mach
4
4
  //#region src/events.d.ts
5
5
  /** The invoke `src` of an {@link AgentRequest}/{@link AgentDecisionRequest} — a plain string, widened so literal `src` values still narrow in editor hints. */
6
6
  type AgentRequestSource = string & {};
7
- /** Default prefix for the synthetic tool name generated per candidate event (e.g. `send_event_ASK`). Override per-request with {@link AgentEventToolNameResolver}. */
8
- declare const EVENT_TOOL_PREFIX: "send_event_";
9
7
  /** Customizes the tool name generated for a candidate event; see {@link AgentRequestOptions.eventToolName}. */
10
8
  type AgentEventToolNameResolver = (args: {
11
9
  eventType: string;
@@ -648,13 +646,15 @@ type AgentRequestExecutor<TResult extends AgentRequestExecutorResult = AgentRequ
648
646
  /**
649
647
  * The full set of host executors a machine's agent actors are resolved
650
648
  * with — passed to `runAgent`, `executeAgentRequest`, and
651
- * `TextLogic.execute`. `generateText` is required; `streamText` is only
652
- * needed if the machine has a `mode: 'stream'` text request, and `decide`
653
- * only if it uses a decision omitting either is a bind-time error when the
654
- * machine actually needs it (see `runAgent`).
649
+ * `TextLogic.execute`. Every slot is optional: `generateText` is needed only
650
+ * if the machine has a `mode: 'generate'` text request, `streamText` only for
651
+ * a `mode: 'stream'` request, and `decide` only for a decision/plan omitting
652
+ * a slot the machine actually needs is a clear bind-time error (see `runAgent`
653
+ * and `provideExecutors`). Adapter result sets (`AiSdkExecutors`,
654
+ * `OpenAiCompatExecutors`) re-require all three.
655
655
  */
656
656
  interface AgentRequestExecutors<TGenerateResult extends AgentRequestExecutorResult = AgentRequestExecutorResult, TStreamResult extends AgentRequestExecutorResult = AgentRequestExecutorResult> {
657
- generateText: AgentRequestExecutor<TGenerateResult>;
657
+ generateText?: AgentRequestExecutor<TGenerateResult>;
658
658
  streamText?: AgentRequestExecutor<TStreamResult>;
659
659
  decide?: AgentDecisionExecutor;
660
660
  }
@@ -707,4 +707,4 @@ declare function buildEnvelopeSchema(inner: StandardSchemaV1, options?: {
707
707
  */
708
708
  declare function parseStructuredEnvelope(request: Pick<AgentTextRequest, "outputSchema" | "reasoning">, value: unknown): StructuredOutputEnvelope;
709
709
  //#endregion
710
- export { AgentDecisionInput as A, renderDecisionAttempts as B, createTextLogic as C, parseOutput as D, parseModelRef as E, DecisionExhaustedError as F, AgentRequestSource as G, AgentEventDescriptor as H, DecisionLogic as I, matchesEventPattern as J, EVENT_TOOL_PREFIX as K, DecisionLogicConfig as L, AgentPlanInput as M, AgentPlanOutput as N, parseStructuredEnvelope as O, DecisionAttempt as P, PLAN_DONE_EVENT_TYPE as R, buildEnvelopeSchema as S, isStructuredOutputSchema as T, AgentEventToolNameResolver as U, resolveDecision as V, AgentRequestOptions as W, parseAgentEvent as Y, TextLogicExecuteArgs as _, AgentRequestExecutorInfo as a, TextLogicOutput as b, AgentRequestMode as c, AiSdkShapedStreamResult as d, AiSdkShapedTextResult as f, TextLogicConfig as g, TextLogic as h, AgentRequestExecutor as i, AgentDecisionRequest as j, AgentDecisionExecutor as k, AgentTextRequest as l, StructuredOutputEnvelope as m, AgentModelRef as n, AgentRequestExecutorResult as o, BuiltinAgentActors as p, getAcceptedEvents as q, AgentOutputMode as r, AgentRequestExecutors as s, AgentModelMap as t, AgentUserInput as u, TextLogicExecutor as v, getAgentOutputMode as w, bindRequestExecutor as x, TextLogicInput as y, ResolveDecisionOptions as z };
710
+ export { AgentDecisionInput as A, ResolveDecisionOptions as B, createTextLogic as C, parseOutput as D, parseModelRef as E, DecisionExhaustedError as F, AgentRequestOptions as G, resolveDecision as H, DecisionLogic as I, matchesEventPattern as J, AgentRequestSource as K, DecisionLogicConfig as L, AgentPlanInput as M, AgentPlanOutput as N, parseStructuredEnvelope as O, DecisionAttempt as P, PLAN_DONE_EVENT_TYPE as R, buildEnvelopeSchema as S, isStructuredOutputSchema as T, AgentEventDescriptor as U, renderDecisionAttempts as V, AgentEventToolNameResolver as W, parseAgentEvent as Y, TextLogicExecuteArgs as _, AgentRequestExecutorInfo as a, TextLogicOutput as b, AgentRequestMode as c, AiSdkShapedStreamResult as d, AiSdkShapedTextResult as f, TextLogicConfig as g, TextLogic as h, AgentRequestExecutor as i, AgentDecisionRequest as j, AgentDecisionExecutor as k, AgentTextRequest as l, StructuredOutputEnvelope as m, AgentModelRef as n, AgentRequestExecutorResult as o, BuiltinAgentActors as p, getAcceptedEvents as q, AgentOutputMode as r, AgentRequestExecutors as s, AgentModelMap as t, AgentUserInput as u, TextLogicExecutor as v, getAgentOutputMode as w, bindRequestExecutor as x, TextLogicInput as y, PlanLogic as z };
package/package.json CHANGED
@@ -1,14 +1,11 @@
1
1
  {
2
2
  "name": "@statelyai/agent",
3
- "version": "2.0.0-alpha.10",
3
+ "version": "2.0.0-alpha.11",
4
4
  "description": "State-machine authoring layer for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.mjs",
8
8
  "types": "dist/index.d.mts",
9
- "bin": {
10
- "statelyai-agent": "dist/cli.mjs"
11
- },
12
9
  "exports": {
13
10
  ".": {
14
11
  "import": {
@@ -40,6 +37,26 @@
40
37
  "default": "./dist/openai-compat.cjs"
41
38
  }
42
39
  },
40
+ "./steps": {
41
+ "import": {
42
+ "types": "./dist/steps.d.mts",
43
+ "default": "./dist/steps.mjs"
44
+ },
45
+ "require": {
46
+ "types": "./dist/steps.d.cts",
47
+ "default": "./dist/steps.cjs"
48
+ }
49
+ },
50
+ "./adapter": {
51
+ "import": {
52
+ "types": "./dist/adapter.d.mts",
53
+ "default": "./dist/adapter.mjs"
54
+ },
55
+ "require": {
56
+ "types": "./dist/adapter.d.cts",
57
+ "default": "./dist/adapter.cjs"
58
+ }
59
+ },
43
60
  "./zod": {
44
61
  "import": {
45
62
  "types": "./dist/zod.d.mts",
@@ -83,15 +100,20 @@
83
100
  "@cloudflare/workers-types": "^4.20260702.1",
84
101
  "@inquirer/prompts": "^8.5.2",
85
102
  "@statelyai/inspect": "^0.7.2",
103
+ "@types/express": "^5.0.6",
86
104
  "@types/node": "^20.16.10",
105
+ "@types/react": "^19.2.17",
87
106
  "agents": "0.11.5",
88
107
  "ai": "^6.0.67",
89
108
  "ajv": "^8.20.0",
90
109
  "dotenv": "^16.4.5",
110
+ "express": "^5.2.1",
111
+ "hono": "^4.12.30",
91
112
  "knip": "6.24.0",
92
113
  "openai": "^6.45.0",
93
114
  "oxfmt": "0.57.0",
94
115
  "oxlint": "1.72.0",
116
+ "react": "^19.2.7",
95
117
  "tsdown": "^0.21.7",
96
118
  "tsx": "^4.21.0",
97
119
  "typescript": "^5.6.2",
@@ -126,6 +148,7 @@
126
148
  "format:check": "oxfmt --check src examples",
127
149
  "knip": "knip",
128
150
  "check": "pnpm run typecheck && pnpm run lint && pnpm run format:check && pnpm run knip",
151
+ "check:dts": "tsc -p fixtures/dts-consumer/tsconfig.json",
129
152
  "test": "vitest",
130
153
  "test:ci": "vitest --run",
131
154
  "changeset": "changeset",
package/readme.md CHANGED
@@ -2,25 +2,31 @@
2
2
 
3
3
  **The logic layer for AI agents.**
4
4
 
5
- Build agents as state machines, with explicit control flow you can inspect, test, visualize, and run anywhere.
5
+ Build agents as state machines to control exactly what the agent can do. The machine owns control flow; the model only ever picks a legal event. Testing, inspection, and visualization fall out for free.
6
6
 
7
7
  Stately Agent adds model requests and decisions to XState. The state machine defines what the agent can do. Your application chooses the model, runs the requests, and stores the state.
8
8
 
9
- Any agent workflow or loop can be modeled as a state machine. Model calls and tools run as effects inside it. The model proposes an event. The machine decides whether it is allowed and what happens next.
9
+ Any agent workflow or loop can be modeled as a state machine. Model calls and tools run as effects inside it. The model proposes an event. The machine decides whether it is allowed and what happens next. See [how this compares to LangGraph and hand-rolling a loop](docs/comparison.md).
10
10
 
11
11
  Stately Agent 2 is in alpha. APIs may change before the stable release.
12
12
 
13
13
  [Documentation](https://stately.ai/docs/agents) · [Examples](examples/README.md) · [XState](https://github.com/statelyai/xstate)
14
14
 
15
+ ## Three ways to start
16
+
17
+ - **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 eject to any framework or runtime with zero machine changes. See the [Quickstart](docs/quickstart.md) and [Eject to your stack](docs/eject.md).
18
+ - **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 loop](docs/from-a-loop.md).
19
+ - **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).
20
+
15
21
  ## Install
16
22
 
17
23
  <!-- install command matching the package prerelease channel and package.json peers -->
18
24
 
19
25
  ```sh
20
- pnpm add @statelyai/agent@alpha xstate@alpha zod ai @ai-sdk/openai
26
+ pnpm add @statelyai/agent@alpha xstate@alpha zod ai@^6 @ai-sdk/openai@^3
21
27
  ```
22
28
 
23
- Node 22.18 or newer is required.
29
+ Node 22.18 or newer is required. The package is ESM-only; the library targets XState v6 alpha and stays compatible with XState v5. Provider packages must match your `ai` major: `@ai-sdk/openai@^3` pairs with `ai@^6` (a bare `@ai-sdk/openai` resolves to `@latest`, which can mismatch the `ai` peer).
24
30
 
25
31
  ## Quick start
26
32
 
@@ -30,15 +36,15 @@ This agent reviews refund requests. The model may propose an automatic refund, b
30
36
 
31
37
  ```ts
32
38
  import { openai } from "@ai-sdk/openai";
33
- import { defineModels, runAgent } from "@statelyai/agent/ai-sdk";
34
- import { setupAgent } from "@statelyai/agent";
39
+ import { runAgent, setupAgent } from "@statelyai/agent";
40
+ import { createAiSdkExecutors, defineModels } from "@statelyai/agent/ai-sdk";
35
41
  import { z } from "zod";
36
42
 
37
43
  const models = defineModels({
38
44
  fast: openai("gpt-5.4-mini"),
39
45
  });
40
46
 
41
- const agent = setupAgent({
47
+ const agentSetup = setupAgent({
42
48
  models,
43
49
  context: z.object({
44
50
  request: z.string(),
@@ -57,7 +63,7 @@ const agent = setupAgent({
57
63
  },
58
64
  });
59
65
 
60
- const refundMachine = agent.createMachine({
66
+ const refundMachine = agentSetup.createMachine({
61
67
  context: ({ input }) => input,
62
68
  initial: "deciding",
63
69
  states: {
@@ -92,6 +98,7 @@ const result = await runAgent(refundMachine, {
92
98
  request: "I was charged twice for the same order.",
93
99
  amount: 75,
94
100
  },
101
+ executors: createAiSdkExecutors({ models }),
95
102
  });
96
103
 
97
104
  if (result.status === "done") {
@@ -145,3 +152,6 @@ See [all examples](examples/README.md).
145
152
  - [Human in the loop](docs/human-in-the-loop.md)
146
153
  - [Testing and verification](docs/verify.md)
147
154
  - [Running on different hosts](docs/hosts.md)
155
+ - [Eject to your stack](docs/eject.md)
156
+ - [Agent patterns](docs/patterns.md)
157
+ - [Migrating from a loop](docs/from-a-loop.md)
@@ -6,6 +6,10 @@
6
6
  "type": "object",
7
7
  "required": ["initial", "states"],
8
8
  "properties": {
9
+ "$schema": {
10
+ "description": "JSON Schema reference an editor attaches to the config file. Ignored by the lowering.",
11
+ "type": "string"
12
+ },
9
13
  "key": {
10
14
  "description": "Stable workflow key used by tools, storage, and visual editors.",
11
15
  "type": "string",
@@ -23,11 +27,6 @@
23
27
  "description": {
24
28
  "type": "string"
25
29
  },
26
- "queryLanguage": {
27
- "description": "Expression language used inside {{ }} expressions. The built-in setupAgent.fromConfig lowering currently supports simple dot-path expressions over input, context, and event.",
28
- "type": "string",
29
- "default": "path"
30
- },
31
30
  "schemas": {
32
31
  "$ref": "#/$defs/AgentSchemas"
33
32
  },
package/dist/cli.cjs DELETED
@@ -1,64 +0,0 @@
1
- #!/usr/bin/env node
2
- const require_run_agent = require("./run-agent-BFMkuI1F.cjs");
3
- const require_src = require("./src-D-77Ha5p.cjs");
4
- let node_fs = require("node:fs");
5
- //#region src/cli.ts
6
- /**
7
- * `statelyai-agent lint <workflow.json>` — keyless static verification for an
8
- * agent machine authored as data (an {@link AgentWorkflowConfig} JSON file).
9
- *
10
- * The library bundles no JSON Schema engine, so the CLI lints STRUCTURE ONLY:
11
- * it compiles the config with a permissive pass-through schema compiler (each
12
- * JSON Schema is kept as-is for structural checks, validation is a no-op) and
13
- * runs {@link lintAgentMachine}. Exits `1` on any error-severity finding.
14
- *
15
- * For full schema-aware linting, import the API and compile with a real engine:
16
- * `lintAgentMachine(setupAgent.fromConfig(config, { compileSchema }))`.
17
- *
18
- * @module
19
- */
20
- function stubCompileSchema(jsonSchema) {
21
- return { "~standard": {
22
- version: 1,
23
- vendor: "statelyai-agent-cli",
24
- validate: (value) => ({ value }),
25
- jsonSchema: { input: () => jsonSchema }
26
- } };
27
- }
28
- function printUsage() {
29
- process.stderr.write("Usage: statelyai-agent lint <workflow.json> [--no-schemas]\n\n Statically verifies an agent-machine JSON config (structure-only).\n Exits 1 on any error-severity finding.\n");
30
- }
31
- function main(argv) {
32
- const args = argv.slice(2);
33
- const command = args[0];
34
- const file = args.find((arg, index) => index > 0 && !arg.startsWith("-"));
35
- if (command !== "lint" || !file) {
36
- printUsage();
37
- return 2;
38
- }
39
- let config;
40
- try {
41
- config = JSON.parse((0, node_fs.readFileSync)(file, "utf8"));
42
- } catch (error) {
43
- process.stderr.write(`statelyai-agent: could not read/parse '${file}': ${error instanceof Error ? error.message : String(error)}\n`);
44
- return 2;
45
- }
46
- let machine;
47
- try {
48
- machine = require_run_agent.setupAgent.fromConfig(config, { compileSchema: stubCompileSchema });
49
- } catch (error) {
50
- process.stderr.write(`statelyai-agent: '${file}' is not a valid agent-machine config: ${error instanceof Error ? error.message : String(error)}\n`);
51
- return 2;
52
- }
53
- const diagnostics = require_src.lintAgentMachine(machine);
54
- const errors = diagnostics.filter((d) => d.severity === "error");
55
- const warnings = diagnostics.filter((d) => d.severity === "warning");
56
- for (const d of diagnostics) {
57
- const label = d.severity === "error" ? "error" : "warn ";
58
- process.stdout.write(` ${label} ${d.code} ${d.path}\n ${d.message}\n`);
59
- }
60
- process.stdout.write(`\n${file}: ${errors.length} error(s), ${warnings.length} warning(s) (structure-only; schemas not compiled).\n`);
61
- return errors.length > 0 ? 1 : 0;
62
- }
63
- process.exit(main(process.argv));
64
- //#endregion
package/dist/cli.d.cts DELETED
@@ -1 +0,0 @@
1
- export { };
package/dist/cli.d.mts DELETED
@@ -1 +0,0 @@
1
- export { };
package/dist/cli.mjs DELETED
@@ -1,65 +0,0 @@
1
- #!/usr/bin/env node
2
- import { c as setupAgent } from "./run-agent-BoAOq_0Z.mjs";
3
- import { a as lintAgentMachine } from "./src-DUeIFjv-.mjs";
4
- import { readFileSync } from "node:fs";
5
- //#region src/cli.ts
6
- /**
7
- * `statelyai-agent lint <workflow.json>` — keyless static verification for an
8
- * agent machine authored as data (an {@link AgentWorkflowConfig} JSON file).
9
- *
10
- * The library bundles no JSON Schema engine, so the CLI lints STRUCTURE ONLY:
11
- * it compiles the config with a permissive pass-through schema compiler (each
12
- * JSON Schema is kept as-is for structural checks, validation is a no-op) and
13
- * runs {@link lintAgentMachine}. Exits `1` on any error-severity finding.
14
- *
15
- * For full schema-aware linting, import the API and compile with a real engine:
16
- * `lintAgentMachine(setupAgent.fromConfig(config, { compileSchema }))`.
17
- *
18
- * @module
19
- */
20
- function stubCompileSchema(jsonSchema) {
21
- return { "~standard": {
22
- version: 1,
23
- vendor: "statelyai-agent-cli",
24
- validate: (value) => ({ value }),
25
- jsonSchema: { input: () => jsonSchema }
26
- } };
27
- }
28
- function printUsage() {
29
- process.stderr.write("Usage: statelyai-agent lint <workflow.json> [--no-schemas]\n\n Statically verifies an agent-machine JSON config (structure-only).\n Exits 1 on any error-severity finding.\n");
30
- }
31
- function main(argv) {
32
- const args = argv.slice(2);
33
- const command = args[0];
34
- const file = args.find((arg, index) => index > 0 && !arg.startsWith("-"));
35
- if (command !== "lint" || !file) {
36
- printUsage();
37
- return 2;
38
- }
39
- let config;
40
- try {
41
- config = JSON.parse(readFileSync(file, "utf8"));
42
- } catch (error) {
43
- process.stderr.write(`statelyai-agent: could not read/parse '${file}': ${error instanceof Error ? error.message : String(error)}\n`);
44
- return 2;
45
- }
46
- let machine;
47
- try {
48
- machine = setupAgent.fromConfig(config, { compileSchema: stubCompileSchema });
49
- } catch (error) {
50
- process.stderr.write(`statelyai-agent: '${file}' is not a valid agent-machine config: ${error instanceof Error ? error.message : String(error)}\n`);
51
- return 2;
52
- }
53
- const diagnostics = lintAgentMachine(machine);
54
- const errors = diagnostics.filter((d) => d.severity === "error");
55
- const warnings = diagnostics.filter((d) => d.severity === "warning");
56
- for (const d of diagnostics) {
57
- const label = d.severity === "error" ? "error" : "warn ";
58
- process.stdout.write(` ${label} ${d.code} ${d.path}\n ${d.message}\n`);
59
- }
60
- process.stdout.write(`\n${file}: ${errors.length} error(s), ${warnings.length} warning(s) (structure-only; schemas not compiled).\n`);
61
- return errors.length > 0 ? 1 : 0;
62
- }
63
- process.exit(main(process.argv));
64
- //#endregion
65
- export {};