@statelyai/agent 1.1.6 → 2.0.0-alpha.6

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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai-sdk.cjs +249 -0
  3. package/dist/ai-sdk.d.cts +168 -0
  4. package/dist/ai-sdk.d.mts +168 -0
  5. package/dist/ai-sdk.mjs +241 -0
  6. package/dist/cli.cjs +63 -0
  7. package/dist/cli.d.cts +1 -0
  8. package/dist/cli.d.mts +1 -0
  9. package/dist/cli.mjs +64 -0
  10. package/dist/decision-CX3YdwrO.cjs +1239 -0
  11. package/dist/decision-D1654JdD.mjs +940 -0
  12. package/dist/index.cjs +54 -0
  13. package/dist/index.d.cts +1217 -0
  14. package/dist/index.d.mts +1194 -405
  15. package/dist/index.mjs +3 -588
  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/src-CEa947Dm.mjs +2449 -0
  21. package/dist/src-wBfi-kTA.cjs +2568 -0
  22. package/dist/text-logic-1ZQkO3zr.d.cts +682 -0
  23. package/dist/text-logic-2EMJIS-n.d.mts +682 -0
  24. package/dist/types-BHjeDdch.d.cts +208 -0
  25. package/dist/types-Cq1YlAQ6.d.mts +208 -0
  26. package/dist/utils-CWUCa3pF.d.mts +108 -0
  27. package/dist/utils-lK1wnL2i.d.cts +108 -0
  28. package/dist/zod.cjs +31 -0
  29. package/dist/zod.d.cts +30 -0
  30. package/dist/zod.d.mts +30 -0
  31. package/dist/zod.mjs +30 -0
  32. package/package.json +109 -28
  33. package/readme.md +144 -6
  34. package/schemas/agent-workflow.json +527 -0
  35. package/.changeset/README.md +0 -8
  36. package/.changeset/config.json +0 -11
  37. package/.env.template +0 -3
  38. package/.github/actions/ci-setup/action.yml +0 -24
  39. package/.github/workflows/release.yml +0 -46
  40. package/.vscode/launch.json +0 -28
  41. package/CHANGELOG.md +0 -222
  42. package/dist/index.d.ts +0 -428
  43. package/dist/index.js +0 -621
  44. package/examples/chatbot.ts +0 -71
  45. package/examples/cot.ts +0 -89
  46. package/examples/email.ts +0 -118
  47. package/examples/example.ts +0 -81
  48. package/examples/goal.ts +0 -94
  49. package/examples/helpers/helpers.ts +0 -17
  50. package/examples/helpers/loader.ts +0 -32
  51. package/examples/helpers/runner.ts +0 -27
  52. package/examples/joke.ts +0 -225
  53. package/examples/multi.ts +0 -103
  54. package/examples/newspaper.ts +0 -324
  55. package/examples/number.ts +0 -102
  56. package/examples/raffle.ts +0 -105
  57. package/examples/sandbox.ts +0 -28
  58. package/examples/simple.ts +0 -39
  59. package/examples/support.ts +0 -147
  60. package/examples/ticTacToe.ts +0 -224
  61. package/examples/todo.ts +0 -137
  62. package/examples/tutor.ts +0 -100
  63. package/examples/verify.ts +0 -120
  64. package/examples/weather.ts +0 -178
  65. package/examples/wiki.ts +0 -30
  66. package/examples/word.ts +0 -171
  67. package/src/adapters/vercel.ts +0 -7
  68. package/src/agent-experimental.ts +0 -221
  69. package/src/agent.test.ts +0 -506
  70. package/src/agent.ts +0 -300
  71. package/src/decision.test.ts +0 -179
  72. package/src/decision.ts +0 -84
  73. package/src/index.ts +0 -4
  74. package/src/memory.ts +0 -25
  75. package/src/planners/shortestPathPlanner.ts +0 -22
  76. package/src/planners/simplePlanner.ts +0 -139
  77. package/src/schemas.ts +0 -11
  78. package/src/strategies/chain-of-note.ts +0 -155
  79. package/src/templates/defaultText.ts +0 -18
  80. package/src/text.ts +0 -241
  81. package/src/types.ts +0 -499
  82. package/src/utils.ts +0 -72
  83. package/tsconfig.json +0 -109
  84. package/vitest.config.ts +0 -9
package/dist/zod.d.cts ADDED
@@ -0,0 +1,30 @@
1
+ import { t as AgentMessage } from "./types-BHjeDdch.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 { t as AgentMessage } from "./types-Cq1YlAQ6.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.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.6",
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.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",
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.1",
27
- "ts-node": "^10.9.2",
28
- "tsup": "^8.3.0",
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",
29
97
  "typescript": "^5.6.2",
30
- "vitest": "^2.1.1",
31
- "wikipedia": "^2.1.2",
32
- "zod": "^3.23.8"
98
+ "vitest": "^2.1.2",
99
+ "xstate": "6.0.0-alpha.17",
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.1",
40
- "ai": "^3.4.6",
41
- "object-hash": "^3.0.0",
42
- "xstate": "^5.18.2"
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,148 @@
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 runAgent -->
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 { createAiSdkExecutors, defineModels } from '@statelyai/agent/ai-sdk';
34
+ import { runAgent, 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: z.object({}),
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 }) =>
76
+ context.amount <= 100 ? { target: 'refunded' } : undefined,
77
+ REVIEW: { target: 'review' },
78
+ },
79
+ },
80
+ refunded: {
81
+ type: 'final',
82
+ output: () => ({ outcome: 'refunded' }),
83
+ },
84
+ review: {
85
+ type: 'final',
86
+ output: () => ({ outcome: 'review' }),
87
+ },
88
+ },
89
+ });
90
+
91
+ const result = await runAgent(refundMachine, {
92
+ input: {
93
+ request: 'I was charged twice for the same order.',
94
+ amount: 75,
95
+ },
96
+ executors: createAiSdkExecutors({ models }),
97
+ });
98
+
99
+ if (result.status === 'done') {
100
+ console.log(result.output);
101
+ }
102
+ ```
103
+
104
+ When the machine reaches `refunded`, the result is:
105
+
106
+ ```text
107
+ { outcome: 'refunded' }
108
+ ```
109
+
110
+ 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.
111
+
112
+ ## The state machine
113
+
114
+ <!-- Add the state machine illustration here. -->
115
+
116
+ 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.
117
+
118
+ ## Core concepts
119
+
120
+ <!-- core concepts derived from setupAgent, built-in agent actors, runAgent, and XState snapshots -->
121
+
122
+ - **Machines own control flow.** States, events, transitions, and guards define what can happen.
123
+ - **Models make bounded decisions.** `agent.decide` asks a model to choose one of the events accepted by the current state.
124
+ - **Requests are typed.** Inputs, outputs, context, and events use Standard Schema. Zod works out of the box.
125
+ - **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.
126
+ - **Snapshots can be stored.** An agent can stop for human input, save its XState snapshot, and resume later in another process.
127
+ - **Machines can be checked without model calls.** Lint their structure, simulate scripted decisions, and explore paths without an API key.
128
+ - **Agents are XState machines.** Guards, actors, parallel states, inspection, testing, and visualization work as usual.
129
+
130
+ ## Examples
131
+
132
+ <!-- starter examples derived from examples/*/metadata.json and examples/index.ts -->
133
+
134
+ - [Twenty Questions](examples/twenty-questions) shows a model choosing legal events in a loop.
135
+ - [Human in the loop](examples/human-in-the-loop) pauses, stores a snapshot, and resumes after review.
136
+ - [Ticket triage](examples/triage) returns structured data from a model request.
137
+ - [JSON agent](examples/json-agent) runs a machine defined as data.
138
+
139
+ See [all examples](examples/README.md).
140
+
141
+ ## Learn more
142
+
143
+ - [Machines](docs/machines.md)
144
+ - [Text requests](docs/text-requests.md)
145
+ - [Decisions](docs/decisions.md)
146
+ - [Human in the loop](docs/human-in-the-loop.md)
147
+ - [Testing and verification](docs/verify.md)
148
+ - [Running on different hosts](docs/hosts.md)