@statelyai/agent 1.1.5 → 2.0.0-alpha.10

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 (88) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai-sdk.cjs +342 -0
  3. package/dist/ai-sdk.d.cts +206 -0
  4. package/dist/ai-sdk.d.mts +206 -0
  5. package/dist/ai-sdk.mjs +331 -0
  6. package/dist/cli.cjs +64 -0
  7. package/dist/cli.d.cts +1 -0
  8. package/dist/cli.d.mts +1 -0
  9. package/dist/cli.mjs +65 -0
  10. package/dist/decision-CQdrKc8k.mjs +978 -0
  11. package/dist/decision-b-lkcs4L.cjs +1295 -0
  12. package/dist/index.cjs +59 -0
  13. package/dist/index.d.cts +212 -0
  14. package/dist/index.d.mts +201 -417
  15. package/dist/index.mjs +4 -583
  16. package/dist/openai-compat.cjs +319 -0
  17. package/dist/openai-compat.d.cts +98 -0
  18. package/dist/openai-compat.d.mts +98 -0
  19. package/dist/openai-compat.mjs +312 -0
  20. package/dist/run-agent-BFMkuI1F.cjs +1599 -0
  21. package/dist/run-agent-BVMd--1l.d.cts +1103 -0
  22. package/dist/run-agent-BoAOq_0Z.mjs +1540 -0
  23. package/dist/run-agent-DzYJb3CK.d.mts +1103 -0
  24. package/dist/src-D-77Ha5p.cjs +1087 -0
  25. package/dist/src-DUeIFjv-.mjs +1016 -0
  26. package/dist/text-logic-C7WJpCIc.d.mts +710 -0
  27. package/dist/text-logic-CZjyACzQ.d.cts +710 -0
  28. package/dist/types-C9QiMjre.d.cts +219 -0
  29. package/dist/types-qm00QF91.d.mts +219 -0
  30. package/dist/utils-Dri7aeEG.d.cts +108 -0
  31. package/dist/utils-Y6GDRGGE.d.mts +108 -0
  32. package/dist/zod.cjs +31 -0
  33. package/dist/zod.d.cts +30 -0
  34. package/dist/zod.d.mts +30 -0
  35. package/dist/zod.mjs +30 -0
  36. package/package.json +110 -29
  37. package/readme.md +143 -6
  38. package/schemas/agent-workflow.json +527 -0
  39. package/.changeset/README.md +0 -8
  40. package/.changeset/config.json +0 -11
  41. package/.env.template +0 -3
  42. package/.github/actions/ci-setup/action.yml +0 -24
  43. package/.github/workflows/release.yml +0 -46
  44. package/.vscode/launch.json +0 -28
  45. package/CHANGELOG.md +0 -215
  46. package/dist/index.d.ts +0 -428
  47. package/dist/index.js +0 -616
  48. package/examples/chatbot.ts +0 -71
  49. package/examples/cot.ts +0 -89
  50. package/examples/email.ts +0 -118
  51. package/examples/example.ts +0 -81
  52. package/examples/goal.ts +0 -94
  53. package/examples/helpers/helpers.ts +0 -17
  54. package/examples/helpers/loader.ts +0 -32
  55. package/examples/helpers/runner.ts +0 -27
  56. package/examples/joke.ts +0 -225
  57. package/examples/multi.ts +0 -103
  58. package/examples/newspaper.ts +0 -324
  59. package/examples/number.ts +0 -102
  60. package/examples/raffle.ts +0 -105
  61. package/examples/sandbox.ts +0 -28
  62. package/examples/simple.ts +0 -39
  63. package/examples/support.ts +0 -147
  64. package/examples/ticTacToe.ts +0 -224
  65. package/examples/todo.ts +0 -137
  66. package/examples/tutor.ts +0 -100
  67. package/examples/verify.ts +0 -120
  68. package/examples/weather.ts +0 -178
  69. package/examples/wiki.ts +0 -30
  70. package/examples/word.ts +0 -171
  71. package/src/adapters/vercel.ts +0 -7
  72. package/src/agent-experimental.ts +0 -221
  73. package/src/agent.test.ts +0 -506
  74. package/src/agent.ts +0 -300
  75. package/src/decision.test.ts +0 -179
  76. package/src/decision.ts +0 -84
  77. package/src/index.ts +0 -4
  78. package/src/memory.ts +0 -25
  79. package/src/planners/shortestPathPlanner.ts +0 -22
  80. package/src/planners/simplePlanner.ts +0 -139
  81. package/src/schemas.ts +0 -11
  82. package/src/strategies/chain-of-note.ts +0 -155
  83. package/src/templates/defaultText.ts +0 -18
  84. package/src/text.ts +0 -236
  85. package/src/types.ts +0 -499
  86. package/src/utils.ts +0 -72
  87. package/tsconfig.json +0 -109
  88. 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,133 @@
1
1
  {
2
2
  "name": "@statelyai/agent",
3
- "version": "1.1.5",
4
- "description": "Stateful agents that make decisions based on finite-state machine models",
5
- "main": "dist/index.js",
3
+ "version": "2.0.0-alpha.10",
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
+ "bin": {
10
+ "statelyai-agent": "dist/cli.mjs"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "import": {
15
+ "types": "./dist/index.d.mts",
16
+ "default": "./dist/index.mjs"
17
+ },
18
+ "require": {
19
+ "types": "./dist/index.d.cts",
20
+ "default": "./dist/index.cjs"
21
+ }
22
+ },
23
+ "./ai-sdk": {
24
+ "import": {
25
+ "types": "./dist/ai-sdk.d.mts",
26
+ "default": "./dist/ai-sdk.mjs"
27
+ },
28
+ "require": {
29
+ "types": "./dist/ai-sdk.d.cts",
30
+ "default": "./dist/ai-sdk.cjs"
31
+ }
32
+ },
33
+ "./openai-compat": {
34
+ "import": {
35
+ "types": "./dist/openai-compat.d.mts",
36
+ "default": "./dist/openai-compat.mjs"
37
+ },
38
+ "require": {
39
+ "types": "./dist/openai-compat.d.cts",
40
+ "default": "./dist/openai-compat.cjs"
41
+ }
42
+ },
43
+ "./zod": {
44
+ "import": {
45
+ "types": "./dist/zod.d.mts",
46
+ "default": "./dist/zod.mjs"
47
+ },
48
+ "require": {
49
+ "types": "./dist/zod.d.cts",
50
+ "default": "./dist/zod.cjs"
51
+ }
52
+ },
53
+ "./agent-workflow.json": "./schemas/agent-workflow.json"
54
+ },
55
+ "files": [
56
+ "dist",
57
+ "schemas"
58
+ ],
8
59
  "keywords": [
9
60
  "ai",
10
61
  "state machine",
11
62
  "agent",
12
- "rl",
13
- "reinforcement learning"
63
+ "statechart"
14
64
  ],
15
- "author": "",
65
+ "author": "David Khourshid <david@stately.ai>",
16
66
  "license": "MIT",
67
+ "repository": {
68
+ "type": "git",
69
+ "url": "git+https://github.com/statelyai/agent.git"
70
+ },
71
+ "homepage": "https://github.com/statelyai/agent#readme",
72
+ "bugs": {
73
+ "url": "https://github.com/statelyai/agent/issues"
74
+ },
75
+ "engines": {
76
+ "node": ">=22.18.0"
77
+ },
17
78
  "devDependencies": {
79
+ "@ai-sdk/openai": "^3.0.25",
80
+ "@anthropic-ai/sdk": "^0.109.1",
18
81
  "@changesets/changelog-github": "^0.5.0",
19
- "@changesets/cli": "^2.27.7",
20
- "@langchain/community": "^0.0.53",
21
- "@langchain/core": "^0.1.63",
22
- "@langchain/openai": "^0.0.28",
23
- "@types/node": "^20.14.14",
24
- "@types/object-hash": "^3.0.6",
82
+ "@changesets/cli": "^2.27.9",
83
+ "@cloudflare/workers-types": "^4.20260702.1",
84
+ "@inquirer/prompts": "^8.5.2",
85
+ "@statelyai/inspect": "^0.7.2",
86
+ "@types/node": "^20.16.10",
87
+ "agents": "0.11.5",
88
+ "ai": "^6.0.67",
89
+ "ajv": "^8.20.0",
25
90
  "dotenv": "^16.4.5",
26
- "json-schema-to-ts": "^3.1.0",
27
- "ts-node": "^10.9.2",
28
- "tsup": "^8.2.4",
29
- "typescript": "^5.5.4",
30
- "vitest": "^2.0.5",
31
- "wikipedia": "^2.1.2",
32
- "zod": "^3.23.8"
91
+ "knip": "6.24.0",
92
+ "openai": "^6.45.0",
93
+ "oxfmt": "0.57.0",
94
+ "oxlint": "1.72.0",
95
+ "tsdown": "^0.21.7",
96
+ "tsx": "^4.21.0",
97
+ "typescript": "^5.6.2",
98
+ "vitest": "^2.1.2",
99
+ "xstate": "6.0.0-alpha.21",
100
+ "zod": "^4.3.6"
33
101
  },
34
102
  "publishConfig": {
35
103
  "access": "public"
36
104
  },
37
- "dependencies": {
38
- "@ai-sdk/openai": "^0.0.40",
39
- "@xstate/graph": "^2.0.0",
40
- "ai": "^3.3.2",
41
- "object-hash": "^3.0.0",
42
- "xstate": "^5.17.1"
105
+ "peerDependencies": {
106
+ "ai": "^6.0.67",
107
+ "xstate": ">=6.0.0-alpha.16 <6.0.0",
108
+ "zod": "^3.25.0 || ^4.0.0"
109
+ },
110
+ "peerDependenciesMeta": {
111
+ "ai": {
112
+ "optional": true
113
+ },
114
+ "zod": {
115
+ "optional": true
116
+ }
43
117
  },
44
118
  "scripts": {
45
- "build": "tsup src/index.ts --format cjs,esm --dts",
46
- "lint": "tsc --noEmit",
119
+ "build": "tsdown",
120
+ "proto:prefabs": "tsx .scratch/prefabs/demo.ts",
121
+ "typecheck": "pnpm run typecheck:src && pnpm run typecheck:examples",
122
+ "typecheck:src": "tsc --noEmit",
123
+ "typecheck:examples": "tsc -p examples/tsconfig.json --noEmit",
124
+ "lint": "oxlint",
125
+ "format": "oxfmt src examples",
126
+ "format:check": "oxfmt --check src examples",
127
+ "knip": "knip",
128
+ "check": "pnpm run typecheck && pnpm run lint && pnpm run format:check && pnpm run knip",
47
129
  "test": "vitest",
48
130
  "test:ci": "vitest --run",
49
- "example": "ts-node examples/helpers/runner.ts",
50
131
  "changeset": "changeset",
51
132
  "release": "changeset publish",
52
133
  "version": "changeset version"
package/readme.md CHANGED
@@ -1,10 +1,147 @@
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, with explicit control flow you can inspect, test, visualize, and run anywhere.
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.
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
+ ## Install
16
+
17
+ <!-- install command matching the package prerelease channel and package.json peers -->
18
+
19
+ ```sh
20
+ pnpm add @statelyai/agent@alpha xstate@alpha zod ai @ai-sdk/openai
21
+ ```
22
+
23
+ Node 22.18 or newer is required.
24
+
25
+ ## Quick start
26
+
27
+ <!-- refund decision example using setupAgent, agent.decide, a machine guard, and the AI SDK runAgent host -->
28
+
29
+ This agent reviews refund requests. The model may propose an automatic refund, but the state machine owns the $100 limit.
30
+
31
+ ```ts
32
+ import { openai } from "@ai-sdk/openai";
33
+ import { defineModels, runAgent } from "@statelyai/agent/ai-sdk";
34
+ import { setupAgent } from "@statelyai/agent";
35
+ import { z } from "zod";
36
+
37
+ const models = defineModels({
38
+ fast: openai("gpt-5.4-mini"),
39
+ });
40
+
41
+ const agent = setupAgent({
42
+ models,
43
+ context: z.object({
44
+ request: z.string(),
45
+ amount: z.number(),
46
+ }),
47
+ input: z.object({
48
+ request: z.string(),
49
+ amount: z.number(),
50
+ }),
51
+ output: z.object({
52
+ outcome: z.enum(["refunded", "review"]),
53
+ }),
54
+ events: {
55
+ AUTO_REFUND: {},
56
+ REVIEW: z.object({ reason: z.string() }),
57
+ },
58
+ });
59
+
60
+ const refundMachine = agent.createMachine({
61
+ context: ({ input }) => input,
62
+ initial: "deciding",
63
+ states: {
64
+ deciding: {
65
+ invoke: {
66
+ src: "agent.decide",
67
+ input: ({ context }) => ({
68
+ model: "fast",
69
+ system: "Choose AUTO_REFUND for eligible requests. Otherwise choose REVIEW.",
70
+ prompt: `${context.request}\nAmount: $${context.amount}`,
71
+ allowedEvents: ["AUTO_REFUND", "REVIEW"],
72
+ }),
73
+ },
74
+ on: {
75
+ AUTO_REFUND: ({ context }) => (context.amount <= 100 ? { target: "refunded" } : undefined),
76
+ REVIEW: { target: "review" },
77
+ },
78
+ },
79
+ refunded: {
80
+ type: "final",
81
+ output: () => ({ outcome: "refunded" }),
82
+ },
83
+ review: {
84
+ type: "final",
85
+ output: () => ({ outcome: "review" }),
86
+ },
87
+ },
88
+ });
89
+
90
+ const result = await runAgent(refundMachine, {
91
+ input: {
92
+ request: "I was charged twice for the same order.",
93
+ amount: 75,
94
+ },
95
+ });
96
+
97
+ if (result.status === "done") {
98
+ console.log(result.output);
99
+ }
100
+ ```
101
+
102
+ When the machine reaches `refunded`, the result is:
103
+
104
+ ```text
105
+ { outcome: 'refunded' }
106
+ ```
107
+
108
+ 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.
109
+
110
+ ## The state machine
111
+
112
+ <!-- Add the state machine illustration here. -->
113
+
114
+ 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.
115
+
116
+ ## Core concepts
117
+
118
+ <!-- core concepts derived from setupAgent, built-in agent actors, runAgent, and XState snapshots -->
119
+
120
+ - **Machines own control flow.** States, events, transitions, and guards define what can happen.
121
+ - **Models make bounded decisions.** `agent.decide` asks a model to choose one of the events accepted by the current state.
122
+ - **Requests are typed.** Inputs, outputs, context, and events use Standard Schema. Zod works out of the box.
123
+ - **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.
124
+ - **Snapshots can be stored.** An agent can stop for human input, save its XState snapshot, and resume later in another process.
125
+ - **Machines can be checked without model calls.** Lint their structure, simulate scripted decisions, and explore paths without an API key.
126
+ - **Agents are XState machines.** Guards, actors, parallel states, inspection, testing, and visualization work as usual.
127
+
128
+ ## Examples
129
+
130
+ <!-- starter examples derived from examples/*/metadata.json and examples/index.ts -->
131
+
132
+ - [Twenty Questions](examples/twenty-questions) shows a model choosing legal events in a loop.
133
+ - [Go Fish](examples/go-fish) pits a model against a human while the machine enforces hidden-information game rules.
134
+ - [Human in the loop](examples/human-in-the-loop) pauses, stores a snapshot, and resumes after review.
135
+ - [Ticket triage](examples/triage) returns structured data from a model request.
136
+ - [JSON agent](examples/json-agent) runs a machine defined as data.
137
+
138
+ See [all examples](examples/README.md).
139
+
140
+ ## Learn more
141
+
142
+ - [Machines](docs/machines.md)
143
+ - [Text requests](docs/text-requests.md)
144
+ - [Decisions](docs/decisions.md)
145
+ - [Human in the loop](docs/human-in-the-loop.md)
146
+ - [Testing and verification](docs/verify.md)
147
+ - [Running on different hosts](docs/hosts.md)