@statelyai/agent 1.1.6 → 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 (92) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapter.cjs +15 -0
  3. package/dist/adapter.d.cts +4 -0
  4. package/dist/adapter.d.mts +4 -0
  5. package/dist/adapter.mjs +2 -0
  6. package/dist/ai-sdk.cjs +306 -0
  7. package/dist/ai-sdk.d.cts +96 -0
  8. package/dist/ai-sdk.d.mts +96 -0
  9. package/dist/ai-sdk.mjs +304 -0
  10. package/dist/decision-C3k4ve51.mjs +227 -0
  11. package/dist/decision-D8wJrM8W.cjs +286 -0
  12. package/dist/events-CRQj3VtP.cjs +1010 -0
  13. package/dist/events-JiVPYrct.mjs +759 -0
  14. package/dist/index.cjs +2528 -0
  15. package/dist/index.d.cts +1232 -0
  16. package/dist/index.d.mts +1217 -413
  17. package/dist/index.mjs +2489 -584
  18. package/dist/openai-compat.cjs +309 -0
  19. package/dist/openai-compat.d.cts +59 -0
  20. package/dist/openai-compat.d.mts +59 -0
  21. package/dist/openai-compat.mjs +308 -0
  22. package/dist/steps-BALp1eZo.d.mts +198 -0
  23. package/dist/steps-CVe54GPP.cjs +420 -0
  24. package/dist/steps-CkyyyuHd.mjs +379 -0
  25. package/dist/steps-MjnQI4aB.d.cts +198 -0
  26. package/dist/steps.cjs +12 -0
  27. package/dist/steps.d.cts +3 -0
  28. package/dist/steps.d.mts +3 -0
  29. package/dist/steps.mjs +3 -0
  30. package/dist/text-logic-CaKqgX4Y.d.mts +710 -0
  31. package/dist/text-logic-Ckhr2kKC.d.cts +710 -0
  32. package/dist/types-C9QiMjre.d.cts +219 -0
  33. package/dist/types-qm00QF91.d.mts +219 -0
  34. package/dist/utils-BYqT_Dyv.d.cts +108 -0
  35. package/dist/utils-Do5wIJrh.d.mts +108 -0
  36. package/dist/zod.cjs +31 -0
  37. package/dist/zod.d.cts +30 -0
  38. package/dist/zod.d.mts +30 -0
  39. package/dist/zod.mjs +30 -0
  40. package/package.json +132 -28
  41. package/readme.md +153 -6
  42. package/schemas/agent-workflow.json +526 -0
  43. package/.changeset/README.md +0 -8
  44. package/.changeset/config.json +0 -11
  45. package/.env.template +0 -3
  46. package/.github/actions/ci-setup/action.yml +0 -24
  47. package/.github/workflows/release.yml +0 -46
  48. package/.vscode/launch.json +0 -28
  49. package/CHANGELOG.md +0 -222
  50. package/dist/index.d.ts +0 -428
  51. package/dist/index.js +0 -621
  52. package/examples/chatbot.ts +0 -71
  53. package/examples/cot.ts +0 -89
  54. package/examples/email.ts +0 -118
  55. package/examples/example.ts +0 -81
  56. package/examples/goal.ts +0 -94
  57. package/examples/helpers/helpers.ts +0 -17
  58. package/examples/helpers/loader.ts +0 -32
  59. package/examples/helpers/runner.ts +0 -27
  60. package/examples/joke.ts +0 -225
  61. package/examples/multi.ts +0 -103
  62. package/examples/newspaper.ts +0 -324
  63. package/examples/number.ts +0 -102
  64. package/examples/raffle.ts +0 -105
  65. package/examples/sandbox.ts +0 -28
  66. package/examples/simple.ts +0 -39
  67. package/examples/support.ts +0 -147
  68. package/examples/ticTacToe.ts +0 -224
  69. package/examples/todo.ts +0 -137
  70. package/examples/tutor.ts +0 -100
  71. package/examples/verify.ts +0 -120
  72. package/examples/weather.ts +0 -178
  73. package/examples/wiki.ts +0 -30
  74. package/examples/word.ts +0 -171
  75. package/src/adapters/vercel.ts +0 -7
  76. package/src/agent-experimental.ts +0 -221
  77. package/src/agent.test.ts +0 -506
  78. package/src/agent.ts +0 -300
  79. package/src/decision.test.ts +0 -179
  80. package/src/decision.ts +0 -84
  81. package/src/index.ts +0 -4
  82. package/src/memory.ts +0 -25
  83. package/src/planners/shortestPathPlanner.ts +0 -22
  84. package/src/planners/simplePlanner.ts +0 -139
  85. package/src/schemas.ts +0 -11
  86. package/src/strategies/chain-of-note.ts +0 -155
  87. package/src/templates/defaultText.ts +0 -18
  88. package/src/text.ts +0 -241
  89. package/src/types.ts +0 -499
  90. package/src/utils.ts +0 -72
  91. package/tsconfig.json +0 -109
  92. package/vitest.config.ts +0 -9
package/dist/zod.cjs ADDED
@@ -0,0 +1,31 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let zod = require("zod");
3
+ //#region src/zod/index.ts
4
+ /**
5
+ * A zod schema for an `AgentMessage[]` context/input field — the typed,
6
+ * dependency-light replacement for the hand-rolled
7
+ * `z.custom<AgentMessage[]>((value) => Array.isArray(value))` recipe repeated
8
+ * across machines that carry a message transcript in context.
9
+ *
10
+ * `AgentMessage` is a structural union (see `src/types.ts`), not something to
11
+ * re-declare as a zod object, so this stays a `z.custom` under the hood while
12
+ * exposing the precise `z.ZodType<AgentMessage[]>` type. Validation checks that
13
+ * the value is an array; element shape is trusted (the library's own message
14
+ * builders and adapters produce well-formed `AgentMessage`s).
15
+ *
16
+ * `zod` is an optional peer of `@statelyai/agent` — this subpath is the only
17
+ * place it's imported, mirroring how `./ai-sdk` gates on `ai`.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { z } from 'zod';
22
+ * import { zodAgentMessages } from '@statelyai/agent/zod';
23
+ *
24
+ * const context = z.object({ messages: zodAgentMessages() });
25
+ * ```
26
+ */
27
+ function zodAgentMessages() {
28
+ return zod.z.custom((value) => Array.isArray(value));
29
+ }
30
+ //#endregion
31
+ exports.zodAgentMessages = zodAgentMessages;
package/dist/zod.d.cts ADDED
@@ -0,0 +1,30 @@
1
+ import { r as AgentMessage } from "./types-C9QiMjre.cjs";
2
+ import { z } from "zod";
3
+
4
+ //#region src/zod/index.d.ts
5
+ /**
6
+ * A zod schema for an `AgentMessage[]` context/input field — the typed,
7
+ * dependency-light replacement for the hand-rolled
8
+ * `z.custom<AgentMessage[]>((value) => Array.isArray(value))` recipe repeated
9
+ * across machines that carry a message transcript in context.
10
+ *
11
+ * `AgentMessage` is a structural union (see `src/types.ts`), not something to
12
+ * re-declare as a zod object, so this stays a `z.custom` under the hood while
13
+ * exposing the precise `z.ZodType<AgentMessage[]>` type. Validation checks that
14
+ * the value is an array; element shape is trusted (the library's own message
15
+ * builders and adapters produce well-formed `AgentMessage`s).
16
+ *
17
+ * `zod` is an optional peer of `@statelyai/agent` — this subpath is the only
18
+ * place it's imported, mirroring how `./ai-sdk` gates on `ai`.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { z } from 'zod';
23
+ * import { zodAgentMessages } from '@statelyai/agent/zod';
24
+ *
25
+ * const context = z.object({ messages: zodAgentMessages() });
26
+ * ```
27
+ */
28
+ declare function zodAgentMessages(): z.ZodType<AgentMessage[]>;
29
+ //#endregion
30
+ export { zodAgentMessages };
package/dist/zod.d.mts ADDED
@@ -0,0 +1,30 @@
1
+ import { r as AgentMessage } from "./types-qm00QF91.mjs";
2
+ import { z } from "zod";
3
+
4
+ //#region src/zod/index.d.ts
5
+ /**
6
+ * A zod schema for an `AgentMessage[]` context/input field — the typed,
7
+ * dependency-light replacement for the hand-rolled
8
+ * `z.custom<AgentMessage[]>((value) => Array.isArray(value))` recipe repeated
9
+ * across machines that carry a message transcript in context.
10
+ *
11
+ * `AgentMessage` is a structural union (see `src/types.ts`), not something to
12
+ * re-declare as a zod object, so this stays a `z.custom` under the hood while
13
+ * exposing the precise `z.ZodType<AgentMessage[]>` type. Validation checks that
14
+ * the value is an array; element shape is trusted (the library's own message
15
+ * builders and adapters produce well-formed `AgentMessage`s).
16
+ *
17
+ * `zod` is an optional peer of `@statelyai/agent` — this subpath is the only
18
+ * place it's imported, mirroring how `./ai-sdk` gates on `ai`.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { z } from 'zod';
23
+ * import { zodAgentMessages } from '@statelyai/agent/zod';
24
+ *
25
+ * const context = z.object({ messages: zodAgentMessages() });
26
+ * ```
27
+ */
28
+ declare function zodAgentMessages(): z.ZodType<AgentMessage[]>;
29
+ //#endregion
30
+ export { zodAgentMessages };
package/dist/zod.mjs ADDED
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ //#region src/zod/index.ts
3
+ /**
4
+ * A zod schema for an `AgentMessage[]` context/input field — the typed,
5
+ * dependency-light replacement for the hand-rolled
6
+ * `z.custom<AgentMessage[]>((value) => Array.isArray(value))` recipe repeated
7
+ * across machines that carry a message transcript in context.
8
+ *
9
+ * `AgentMessage` is a structural union (see `src/types.ts`), not something to
10
+ * re-declare as a zod object, so this stays a `z.custom` under the hood while
11
+ * exposing the precise `z.ZodType<AgentMessage[]>` type. Validation checks that
12
+ * the value is an array; element shape is trusted (the library's own message
13
+ * builders and adapters produce well-formed `AgentMessage`s).
14
+ *
15
+ * `zod` is an optional peer of `@statelyai/agent` — this subpath is the only
16
+ * place it's imported, mirroring how `./ai-sdk` gates on `ai`.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { z } from 'zod';
21
+ * import { zodAgentMessages } from '@statelyai/agent/zod';
22
+ *
23
+ * const context = z.object({ messages: zodAgentMessages() });
24
+ * ```
25
+ */
26
+ function zodAgentMessages() {
27
+ return z.custom((value) => Array.isArray(value));
28
+ }
29
+ //#endregion
30
+ export { zodAgentMessages };
package/package.json CHANGED
@@ -1,52 +1,156 @@
1
1
  {
2
2
  "name": "@statelyai/agent",
3
- "version": "1.1.6",
4
- "description": "Stateful agents that make decisions based on finite-state machine models",
5
- "main": "dist/index.js",
3
+ "version": "2.0.0-alpha.11",
4
+ "description": "State-machine authoring layer for AI agents",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
6
7
  "module": "dist/index.mjs",
7
- "types": "dist/index.d.ts",
8
+ "types": "dist/index.d.mts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.mts",
13
+ "default": "./dist/index.mjs"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "./ai-sdk": {
21
+ "import": {
22
+ "types": "./dist/ai-sdk.d.mts",
23
+ "default": "./dist/ai-sdk.mjs"
24
+ },
25
+ "require": {
26
+ "types": "./dist/ai-sdk.d.cts",
27
+ "default": "./dist/ai-sdk.cjs"
28
+ }
29
+ },
30
+ "./openai-compat": {
31
+ "import": {
32
+ "types": "./dist/openai-compat.d.mts",
33
+ "default": "./dist/openai-compat.mjs"
34
+ },
35
+ "require": {
36
+ "types": "./dist/openai-compat.d.cts",
37
+ "default": "./dist/openai-compat.cjs"
38
+ }
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
+ },
60
+ "./zod": {
61
+ "import": {
62
+ "types": "./dist/zod.d.mts",
63
+ "default": "./dist/zod.mjs"
64
+ },
65
+ "require": {
66
+ "types": "./dist/zod.d.cts",
67
+ "default": "./dist/zod.cjs"
68
+ }
69
+ },
70
+ "./agent-workflow.json": "./schemas/agent-workflow.json"
71
+ },
72
+ "files": [
73
+ "dist",
74
+ "schemas"
75
+ ],
8
76
  "keywords": [
9
77
  "ai",
10
78
  "state machine",
11
79
  "agent",
12
- "rl",
13
- "reinforcement learning"
80
+ "statechart"
14
81
  ],
15
- "author": "",
82
+ "author": "David Khourshid <david@stately.ai>",
16
83
  "license": "MIT",
84
+ "repository": {
85
+ "type": "git",
86
+ "url": "git+https://github.com/statelyai/agent.git"
87
+ },
88
+ "homepage": "https://github.com/statelyai/agent#readme",
89
+ "bugs": {
90
+ "url": "https://github.com/statelyai/agent/issues"
91
+ },
92
+ "engines": {
93
+ "node": ">=22.18.0"
94
+ },
17
95
  "devDependencies": {
96
+ "@ai-sdk/openai": "^3.0.25",
97
+ "@anthropic-ai/sdk": "^0.109.1",
18
98
  "@changesets/changelog-github": "^0.5.0",
19
- "@changesets/cli": "^2.27.8",
20
- "@langchain/community": "^0.0.53",
21
- "@langchain/core": "^0.1.63",
22
- "@langchain/openai": "^0.0.28",
23
- "@types/node": "^20.16.9",
24
- "@types/object-hash": "^3.0.6",
99
+ "@changesets/cli": "^2.27.9",
100
+ "@cloudflare/workers-types": "^4.20260702.1",
101
+ "@inquirer/prompts": "^8.5.2",
102
+ "@statelyai/inspect": "^0.7.2",
103
+ "@types/express": "^5.0.6",
104
+ "@types/node": "^20.16.10",
105
+ "@types/react": "^19.2.17",
106
+ "agents": "0.11.5",
107
+ "ai": "^6.0.67",
108
+ "ajv": "^8.20.0",
25
109
  "dotenv": "^16.4.5",
26
- "json-schema-to-ts": "^3.1.1",
27
- "ts-node": "^10.9.2",
28
- "tsup": "^8.3.0",
110
+ "express": "^5.2.1",
111
+ "hono": "^4.12.30",
112
+ "knip": "6.24.0",
113
+ "openai": "^6.45.0",
114
+ "oxfmt": "0.57.0",
115
+ "oxlint": "1.72.0",
116
+ "react": "^19.2.7",
117
+ "tsdown": "^0.21.7",
118
+ "tsx": "^4.21.0",
29
119
  "typescript": "^5.6.2",
30
- "vitest": "^2.1.1",
31
- "wikipedia": "^2.1.2",
32
- "zod": "^3.23.8"
120
+ "vitest": "^2.1.2",
121
+ "xstate": "6.0.0-alpha.21",
122
+ "zod": "^4.3.6"
33
123
  },
34
124
  "publishConfig": {
35
125
  "access": "public"
36
126
  },
37
- "dependencies": {
38
- "@ai-sdk/openai": "^0.0.40",
39
- "@xstate/graph": "^2.0.1",
40
- "ai": "^3.4.6",
41
- "object-hash": "^3.0.0",
42
- "xstate": "^5.18.2"
127
+ "peerDependencies": {
128
+ "ai": "^6.0.67",
129
+ "xstate": ">=6.0.0-alpha.16 <6.0.0",
130
+ "zod": "^3.25.0 || ^4.0.0"
131
+ },
132
+ "peerDependenciesMeta": {
133
+ "ai": {
134
+ "optional": true
135
+ },
136
+ "zod": {
137
+ "optional": true
138
+ }
43
139
  },
44
140
  "scripts": {
45
- "build": "tsup src/index.ts --format cjs,esm --dts",
46
- "lint": "tsc --noEmit",
141
+ "build": "tsdown",
142
+ "proto:prefabs": "tsx .scratch/prefabs/demo.ts",
143
+ "typecheck": "pnpm run typecheck:src && pnpm run typecheck:examples",
144
+ "typecheck:src": "tsc --noEmit",
145
+ "typecheck:examples": "tsc -p examples/tsconfig.json --noEmit",
146
+ "lint": "oxlint",
147
+ "format": "oxfmt src examples",
148
+ "format:check": "oxfmt --check src examples",
149
+ "knip": "knip",
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",
47
152
  "test": "vitest",
48
153
  "test:ci": "vitest --run",
49
- "example": "ts-node examples/helpers/runner.ts",
50
154
  "changeset": "changeset",
51
155
  "release": "changeset publish",
52
156
  "version": "changeset version"
package/readme.md CHANGED
@@ -1,10 +1,157 @@
1
1
  # Stately Agent
2
2
 
3
- Stately Agent is a flexible framework for building AI agents using state machines. Stately agents go beyond normal LLM-based AI agents by:
3
+ **The logic layer for AI agents.**
4
4
 
5
- - Using state machines to guide the agent's behavior, powered by [XState](https://stately.ai/docs/xstate)
6
- - Incorporating **observations**, **message history**, and **feedback** to the agent decision-making and text-generation processes, as needed
7
- - Enabling custom **planning** abilities for agents to achieve specific goals based on state machine logic, observations, and feedback
8
- - Wrapping the [Vercel AI SDK](https://sdk.vercel.ai/) to easily support multiple model providers, such as OpenAI, Anthropic, Google, Mistral, Groq, Perplexity, and more
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.
9
6
 
10
- **Read the documentation: [stately.ai/docs/agents](https://stately.ai/docs/agents)**
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
+
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
+
11
+ Stately Agent 2 is in alpha. APIs may change before the stable release.
12
+
13
+ [Documentation](https://stately.ai/docs/agents) · [Examples](examples/README.md) · [XState](https://github.com/statelyai/xstate)
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
+
21
+ ## Install
22
+
23
+ <!-- install command matching the package prerelease channel and package.json peers -->
24
+
25
+ ```sh
26
+ pnpm add @statelyai/agent@alpha xstate@alpha zod ai@^6 @ai-sdk/openai@^3
27
+ ```
28
+
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).
30
+
31
+ ## Quick start
32
+
33
+ <!-- refund decision example using setupAgent, agent.decide, a machine guard, and the AI SDK runAgent host -->
34
+
35
+ This agent reviews refund requests. The model may propose an automatic refund, but the state machine owns the $100 limit.
36
+
37
+ ```ts
38
+ import { openai } from "@ai-sdk/openai";
39
+ import { runAgent, setupAgent } from "@statelyai/agent";
40
+ import { createAiSdkExecutors, defineModels } from "@statelyai/agent/ai-sdk";
41
+ import { z } from "zod";
42
+
43
+ const models = defineModels({
44
+ fast: openai("gpt-5.4-mini"),
45
+ });
46
+
47
+ const agentSetup = setupAgent({
48
+ models,
49
+ context: z.object({
50
+ request: z.string(),
51
+ amount: z.number(),
52
+ }),
53
+ input: z.object({
54
+ request: z.string(),
55
+ amount: z.number(),
56
+ }),
57
+ output: z.object({
58
+ outcome: z.enum(["refunded", "review"]),
59
+ }),
60
+ events: {
61
+ AUTO_REFUND: {},
62
+ REVIEW: z.object({ reason: z.string() }),
63
+ },
64
+ });
65
+
66
+ const refundMachine = agentSetup.createMachine({
67
+ context: ({ input }) => input,
68
+ initial: "deciding",
69
+ states: {
70
+ deciding: {
71
+ invoke: {
72
+ src: "agent.decide",
73
+ input: ({ context }) => ({
74
+ model: "fast",
75
+ system: "Choose AUTO_REFUND for eligible requests. Otherwise choose REVIEW.",
76
+ prompt: `${context.request}\nAmount: $${context.amount}`,
77
+ allowedEvents: ["AUTO_REFUND", "REVIEW"],
78
+ }),
79
+ },
80
+ on: {
81
+ AUTO_REFUND: ({ context }) => (context.amount <= 100 ? { target: "refunded" } : undefined),
82
+ REVIEW: { target: "review" },
83
+ },
84
+ },
85
+ refunded: {
86
+ type: "final",
87
+ output: () => ({ outcome: "refunded" }),
88
+ },
89
+ review: {
90
+ type: "final",
91
+ output: () => ({ outcome: "review" }),
92
+ },
93
+ },
94
+ });
95
+
96
+ const result = await runAgent(refundMachine, {
97
+ input: {
98
+ request: "I was charged twice for the same order.",
99
+ amount: 75,
100
+ },
101
+ executors: createAiSdkExecutors({ models }),
102
+ });
103
+
104
+ if (result.status === "done") {
105
+ console.log(result.output);
106
+ }
107
+ ```
108
+
109
+ When the machine reaches `refunded`, the result is:
110
+
111
+ ```text
112
+ { outcome: 'refunded' }
113
+ ```
114
+
115
+ The model chooses between the events allowed in `deciding`. The `AUTO_REFUND` transition only works when the amount is at most $100. If the model chooses it for a larger amount, the guard rejects the choice and the decision is tried again.
116
+
117
+ ## The state machine
118
+
119
+ <!-- Add the state machine illustration here. -->
120
+
121
+ The example has one model decision and two final outcomes. Real machines can add approval states, retries, parallel work, child agents, and long-running waits without changing how the control flow is represented.
122
+
123
+ ## Core concepts
124
+
125
+ <!-- core concepts derived from setupAgent, built-in agent actors, runAgent, and XState snapshots -->
126
+
127
+ - **Machines own control flow.** States, events, transitions, and guards define what can happen.
128
+ - **Models make bounded decisions.** `agent.decide` asks a model to choose one of the events accepted by the current state.
129
+ - **Requests are typed.** Inputs, outputs, context, and events use Standard Schema. Zod works out of the box.
130
+ - **Your code runs the model.** `runAgent` accepts executor functions. The example uses the Vercel AI SDK adapter, but the machine does not depend on a provider.
131
+ - **Snapshots can be stored.** An agent can stop for human input, save its XState snapshot, and resume later in another process.
132
+ - **Machines can be checked without model calls.** Lint their structure, simulate scripted decisions, and explore paths without an API key.
133
+ - **Agents are XState machines.** Guards, actors, parallel states, inspection, testing, and visualization work as usual.
134
+
135
+ ## Examples
136
+
137
+ <!-- starter examples derived from examples/*/metadata.json and examples/index.ts -->
138
+
139
+ - [Twenty Questions](examples/twenty-questions) shows a model choosing legal events in a loop.
140
+ - [Go Fish](examples/go-fish) pits a model against a human while the machine enforces hidden-information game rules.
141
+ - [Human in the loop](examples/human-in-the-loop) pauses, stores a snapshot, and resumes after review.
142
+ - [Ticket triage](examples/triage) returns structured data from a model request.
143
+ - [JSON agent](examples/json-agent) runs a machine defined as data.
144
+
145
+ See [all examples](examples/README.md).
146
+
147
+ ## Learn more
148
+
149
+ - [Machines](docs/machines.md)
150
+ - [Text requests](docs/text-requests.md)
151
+ - [Decisions](docs/decisions.md)
152
+ - [Human in the loop](docs/human-in-the-loop.md)
153
+ - [Testing and verification](docs/verify.md)
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)