@statelyai/agent 2.0.0-alpha.22 → 2.0.0-alpha.23

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 (48) hide show
  1. package/dist/ai-sdk.cjs +53 -25
  2. package/dist/ai-sdk.d.cts +20 -12
  3. package/dist/ai-sdk.d.mts +20 -12
  4. package/dist/ai-sdk.mjs +53 -25
  5. package/dist/{decision-DxSTqzgZ.mjs → decision-BBZ2jMO1.mjs} +444 -79
  6. package/dist/{decision-1o45_ZrS.cjs → decision-Cv6SfNWl.cjs} +525 -94
  7. package/dist/index.cjs +2224 -1032
  8. package/dist/index.d.cts +413 -275
  9. package/dist/index.d.mts +413 -275
  10. package/dist/index.mjs +2163 -983
  11. package/dist/machines.cjs +30 -2
  12. package/dist/machines.d.cts +1 -1
  13. package/dist/machines.d.mts +1 -1
  14. package/dist/machines.mjs +30 -2
  15. package/dist/openai.cjs +447 -0
  16. package/dist/openai.d.cts +177 -0
  17. package/dist/openai.d.mts +177 -0
  18. package/dist/openai.mjs +437 -0
  19. package/dist/otel.cjs +3 -6
  20. package/dist/otel.d.cts +1 -1
  21. package/dist/otel.d.mts +1 -1
  22. package/dist/otel.mjs +3 -6
  23. package/dist/run-agent-Ck7Sa3Tb.d.mts +968 -0
  24. package/dist/run-agent-DWqA8KiI.d.cts +968 -0
  25. package/dist/setup-agent-CeO2fARv.mjs +639 -0
  26. package/dist/setup-agent-Dl2VELLi.cjs +663 -0
  27. package/dist/{text-logic-BaxPrcLk.d.cts → text-logic-C7bSnH_B.d.cts} +195 -44
  28. package/dist/{text-logic-DhfFWzu9.d.mts → text-logic-DJBK3LbG.d.mts} +195 -44
  29. package/dist/{types-DSdj2tGs.d.cts → types-CjHk5OdH.d.cts} +4 -19
  30. package/dist/{types-CvWRGFxP.d.mts → types-DWA6X9R-.d.mts} +4 -19
  31. package/package.json +17 -21
  32. package/readme.md +32 -17
  33. package/dist/errors-BQRk9eiZ.d.cts +0 -19
  34. package/dist/errors-C9rxnWbX.d.mts +0 -19
  35. package/dist/errors-CeSXQx0v.mjs +0 -23
  36. package/dist/errors-DUBBzRLP.cjs +0 -28
  37. package/dist/event-log-store-Bz7HDBkE.d.cts +0 -145
  38. package/dist/event-log-store-DmIDosD6.mjs +0 -427
  39. package/dist/event-log-store-a_TKy1gk.cjs +0 -468
  40. package/dist/event-log-store-hrA1vqtN.d.mts +0 -145
  41. package/dist/run-agent-0fpEZ1wJ.d.mts +0 -1098
  42. package/dist/run-agent-Zbkx7XP8.d.cts +0 -1098
  43. package/dist/setup-agent-DkCTy5Eu.cjs +0 -1707
  44. package/dist/setup-agent-nSFYrNTP.mjs +0 -1587
  45. package/dist/sqlite.cjs +0 -129
  46. package/dist/sqlite.d.cts +0 -57
  47. package/dist/sqlite.d.mts +0 -57
  48. package/dist/sqlite.mjs +0 -127
package/readme.md CHANGED
@@ -25,7 +25,19 @@ Stately Agent 2 is in alpha. APIs may change before the stable release.
25
25
  <!-- install command matching the package prerelease channel and package.json peers -->
26
26
 
27
27
  ```sh
28
- pnpm add @statelyai/agent@alpha xstate@alpha zod ai@^7 @ai-sdk/openai@^4
28
+ pnpm add @statelyai/agent@alpha xstate@alpha zod
29
+ ```
30
+
31
+ For the optional Vercel AI SDK executor:
32
+
33
+ ```sh
34
+ pnpm add ai@^7 @ai-sdk/openai@^4
35
+ ```
36
+
37
+ For the optional raw OpenAI SDK executor (`@statelyai/agent/openai`):
38
+
39
+ ```sh
40
+ pnpm add openai
29
41
  ```
30
42
 
31
43
  Requirements:
@@ -41,17 +53,10 @@ Requirements:
41
53
  This agent reviews refund requests. The model may propose an automatic refund, but the state machine owns the $100 limit.
42
54
 
43
55
  ```ts
44
- import { openai } from "@ai-sdk/openai";
45
56
  import { runAgent, setupAgent } from "@statelyai/agent";
46
- import { createAiSdkExecutors, defineModels } from "@statelyai/agent/ai-sdk";
47
57
  import { z } from "zod";
48
58
 
49
- const models = defineModels({
50
- fast: openai("gpt-5.4-mini"),
51
- });
52
-
53
59
  const agentSetup = setupAgent({
54
- models,
55
60
  context: z.object({
56
61
  request: z.string(),
57
62
  amount: z.number(),
@@ -104,7 +109,9 @@ const result = await runAgent(refundMachine, {
104
109
  request: "I was charged twice for the same order.",
105
110
  amount: 75,
106
111
  },
107
- executors: createAiSdkExecutors({ models }),
112
+ // An executor is a plain function, so this run needs no API key and no
113
+ // provider package.
114
+ executors: { decide: async () => ({ event: { type: "AUTO_REFUND" } }) },
108
115
  });
109
116
 
110
117
  if (result.status === "done") {
@@ -120,16 +127,21 @@ When the machine reaches `refunded`, the result is:
120
127
 
121
128
  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.
122
129
 
130
+ To call a real model, leave the machine unchanged and swap the executors:
131
+
123
132
  ```ts
124
- import { createScriptedExecutors } from "@statelyai/agent";
133
+ import { openai } from "@ai-sdk/openai";
134
+ import { createAiSdkExecutors } from "@statelyai/agent/ai-sdk";
125
135
 
126
- const result = await runAgent(refundMachine, {
136
+ const liveResult = await runAgent(refundMachine, {
127
137
  input: { request: "I was charged twice for the same order.", amount: 75 },
128
- executors: createScriptedExecutors({ decisions: [{ type: "AUTO_REFUND" }] }),
138
+ executors: createAiSdkExecutors({ models: { fast: openai("gpt-5.4-mini") } }),
129
139
  });
130
140
  ```
131
141
 
132
- Scripted executors run the machine above end to end with no API key; swap in `createAiSdkExecutors({ models })` for a real model. See [Hosts and executors](docs/hosts.md).
142
+ For a machine with several requests, `createScriptedExecutors` holds ordered answers keyed by request name. See [Evals](docs/evals.md#scripted-executors).
143
+
144
+ Passing a `defineModels` registry to `setupAgent({ models })` types the machine's model refs and supplies the AI SDK executor by default; explicit `executors` override it. Core does not import the AI SDK. See [Hosts and executors](docs/hosts.md).
133
145
 
134
146
  ## Architecture
135
147
 
@@ -147,15 +159,18 @@ The machine never talks to a model directly, so swapping `createAiSdkExecutors`
147
159
 
148
160
  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.
149
161
 
150
- The core concepts (machines owning control flow, bounded model decisions, typed requests, host-run executors, storable snapshots, verified replay entries) are in the [documentation overview](docs/index.md).
162
+ 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).
151
163
 
152
164
  ## Examples
153
165
 
154
166
  <!-- starter examples derived from examples/*/metadata.json and examples/index.ts -->
155
167
 
156
168
  - [Twenty Questions](examples/twenty-questions) shows a model choosing legal events in a loop.
157
- - [Go Fish](examples/go-fish) pits a model against a human while the machine enforces hidden-information game rules.
158
- - [Human in the loop](examples/human-in-the-loop) pauses, stores a snapshot, and resumes after review.
169
+ - [Chameleon](examples/chameleon) combines hidden information, sequential turns, and a human vote.
170
+ - [Snapshot migration](examples/snapshot-migration) uses XState's native `version` and `migrate` contract.
171
+ - [Portable XState loop](examples/portable-xstate-loop) runs the artifact through native transitions and effects.
172
+ - [Framework-owned storage](examples/file-snapshot-store) persists native XState snapshots in application code.
173
+ - [Tool calling](examples/review-tool-calls) keeps tools and message history in the AI SDK's native format.
159
174
  - [Ticket triage](examples/triage) returns structured data from a model request.
160
175
  - [JSON agent](examples/json-agent) runs a machine defined as data.
161
176
 
@@ -173,7 +188,7 @@ See [all examples](examples/README.md).
173
188
  - [Hosts and executors](docs/hosts.md)
174
189
  - [Models and providers](docs/models-and-providers.md)
175
190
  - [Use in any stack](docs/any-stack.md)
176
- - [The event log](docs/event-log.md)
191
+ - [Persistence](docs/persistence.md)
177
192
  - [Observability](docs/observability.md)
178
193
  - [Usage and budgets](docs/usage-and-budgets.md)
179
194
  - [Agent patterns](docs/patterns.md)
@@ -1,19 +0,0 @@
1
- //#region src/errors.d.ts
2
- /**
3
- * Base class for every error this package throws. Carries a stable, kebab-case
4
- * `code` so hosts can branch on the failure without `instanceof` (useful across
5
- * bundle/realm boundaries and after serialization).
6
- *
7
- * @example
8
- * ```ts
9
- * catch (error) {
10
- * if (error instanceof AgentError && error.code === 'agent-idle') { ... }
11
- * }
12
- * ```
13
- */
14
- declare class AgentError extends Error {
15
- readonly code: string;
16
- constructor(code: string, message: string, options?: ErrorOptions);
17
- }
18
- //#endregion
19
- export { AgentError as t };
@@ -1,19 +0,0 @@
1
- //#region src/errors.d.ts
2
- /**
3
- * Base class for every error this package throws. Carries a stable, kebab-case
4
- * `code` so hosts can branch on the failure without `instanceof` (useful across
5
- * bundle/realm boundaries and after serialization).
6
- *
7
- * @example
8
- * ```ts
9
- * catch (error) {
10
- * if (error instanceof AgentError && error.code === 'agent-idle') { ... }
11
- * }
12
- * ```
13
- */
14
- declare class AgentError extends Error {
15
- readonly code: string;
16
- constructor(code: string, message: string, options?: ErrorOptions);
17
- }
18
- //#endregion
19
- export { AgentError as t };
@@ -1,23 +0,0 @@
1
- //#region src/errors.ts
2
- /**
3
- * Base class for every error this package throws. Carries a stable, kebab-case
4
- * `code` so hosts can branch on the failure without `instanceof` (useful across
5
- * bundle/realm boundaries and after serialization).
6
- *
7
- * @example
8
- * ```ts
9
- * catch (error) {
10
- * if (error instanceof AgentError && error.code === 'agent-idle') { ... }
11
- * }
12
- * ```
13
- */
14
- var AgentError = class extends Error {
15
- code;
16
- constructor(code, message, options) {
17
- super(message, options);
18
- this.name = "AgentError";
19
- this.code = code;
20
- }
21
- };
22
- //#endregion
23
- export { AgentError as t };
@@ -1,28 +0,0 @@
1
- //#region src/errors.ts
2
- /**
3
- * Base class for every error this package throws. Carries a stable, kebab-case
4
- * `code` so hosts can branch on the failure without `instanceof` (useful across
5
- * bundle/realm boundaries and after serialization).
6
- *
7
- * @example
8
- * ```ts
9
- * catch (error) {
10
- * if (error instanceof AgentError && error.code === 'agent-idle') { ... }
11
- * }
12
- * ```
13
- */
14
- var AgentError = class extends Error {
15
- code;
16
- constructor(code, message, options) {
17
- super(message, options);
18
- this.name = "AgentError";
19
- this.code = code;
20
- }
21
- };
22
- //#endregion
23
- Object.defineProperty(exports, "AgentError", {
24
- enumerable: true,
25
- get: function() {
26
- return AgentError;
27
- }
28
- });
@@ -1,145 +0,0 @@
1
- import { t as AgentError } from "./errors-BQRk9eiZ.cjs";
2
- import { EventObject } from "xstate";
3
-
4
- //#region src/event-log-store-conformance.d.ts
5
- /** Produces a fresh, empty store for one assertion. */
6
- type CreateStore = () => Promise<AgentEventLogStore> | AgentEventLogStore;
7
- /**
8
- * Validates a store against the reference's semantics: empty read + zero length
9
- * for unknown threads; single and multi-entry append; contiguity misuse guard;
10
- * stale-`expectedIndex` conflict with correct fields; an interleaved concurrent
11
- * append race (exactly one winner); event-id uniqueness; `read({ from })`
12
- * incremental correctness; thread isolation; metadata round-trip; deep-copy
13
- * isolation on append and read; and the full fork contract.
14
- */
15
- declare function assertEventLogStoreConformance(create: CreateStore): Promise<void>;
16
- //#endregion
17
- //#region src/event-log-store.d.ts
18
- /** The durable replay-entry envelope version. */
19
- declare const AGENT_EVENT_SCHEMA_VERSION: 1;
20
- /** Values that round-trip through JSON without adapters or silent coercion. */
21
- type JsonValue = null | boolean | number | string | JsonValue[] | {
22
- [key: string]: JsonValue;
23
- };
24
- interface AgentLogVerification {
25
- /** Hash of the logical machine projection after this entry is applied. */
26
- stateHash: string;
27
- /** Hash of the serializable effects owed at that frontier. */
28
- effectsHash: string;
29
- }
30
- /**
31
- * One journaled entry: an EXTERNAL input to the machine — an effect completion
32
- * (a `done`/`error` event carrying its output inline), a user-sent event, or a
33
- * timer firing. Never a raised/internal event: deterministic replay re-derives
34
- * those from the machine's own logic, so journaling them would double-apply.
35
- * JSON-safe, stored verbatim.
36
- */
37
- interface AgentLogEntry {
38
- /** Version of this outer envelope, independent of the machine event type. */
39
- schemaVersion: typeof AGENT_EVENT_SCHEMA_VERSION;
40
- /** Stable identity within the thread. Forked prefixes retain their ids. */
41
- id: string;
42
- /** 0-based position in the thread's log. */
43
- index: number;
44
- /** RFC 3339 wall-clock time when the host accepted the entry. Metadata only. */
45
- recordedAt: string;
46
- /** The authored XState machine id. */
47
- machineId: string;
48
- /** Explicit version or structural hash of the machine that accepted the event. */
49
- machineVersion: string;
50
- event: EventObject;
51
- /** Optional causal parent entry id, scoped to the same thread. */
52
- causationId?: string;
53
- /** Optional host-owned correlation id spanning threads/runs. */
54
- correlationId?: string;
55
- /** Recorded projection hashes used by strict replay verification. */
56
- verification?: AgentLogVerification;
57
- /** Host-owned, JSON-safe; stored verbatim, never interpreted. */
58
- metadata?: Record<string, JsonValue>;
59
- }
60
- /** A precise failure when an entry would not survive a JSON round-trip. */
61
- declare class NonSerializableAgentEventError extends AgentError {
62
- readonly path: string;
63
- readonly valueType: string;
64
- constructor(path: string, valueType: string);
65
- }
66
- /**
67
- * Rejects values JSON would drop or coerce. Unlike `JSON.stringify`, this does
68
- * not silently erase `undefined`/functions or turn non-finite numbers into
69
- * `null`; durable entries contain only plain JSON values.
70
- */
71
- declare function assertJsonSerializable(value: unknown, path?: string, ancestors?: WeakSet<object>): asserts value is JsonValue;
72
- /** Validates the complete durable envelope before append/export/replay. */
73
- declare function assertAgentLogEntry(entry: unknown): asserts entry is AgentLogEntry;
74
- /**
75
- * An append-only event log: the authoritative durability artifact of a thread.
76
- * The journal of external inputs IS the source of truth — deterministic machine
77
- * replay derives every snapshot from it, a fork is a copied log prefix, and the
78
- * type-only {@link AgentSnapshotStore} is a mere idle-point compaction cache
79
- * over what the log already implies.
80
- *
81
- * Userland stores (a Postgres table with a `(thread_id, index)` primary key, an
82
- * append-only object in blob storage, …) implement this one shape so they
83
- * interoperate; {@link createInMemoryEventLogStore} is the in-memory reference.
84
- */
85
- interface AgentEventLogStore {
86
- /**
87
- * Append `entries` starting at `expectedIndex` (the current length of the
88
- * thread's log; 0 for a new thread). Atomic — all entries land or none do.
89
- * Rejects with {@link AgentEventLogConflictError} when the thread's length
90
- * differs from `expectedIndex`: a concurrent writer appended first. Each
91
- * entry's `index` must be contiguous from `expectedIndex` (a plain `Error`
92
- * otherwise: that is caller misuse, not a race).
93
- */
94
- append(input: {
95
- threadId: string;
96
- expectedIndex: number;
97
- entries: AgentLogEntry[];
98
- }): Promise<void>;
99
- /**
100
- * Read a thread's entries in log order. `from` (default 0) skips entries
101
- * below that index for incremental catch-up. An unknown thread reads as an
102
- * empty array.
103
- */
104
- read(threadId: string, options?: {
105
- from?: number;
106
- }): Promise<AgentLogEntry[]>;
107
- /** The thread's current log length (0 for an unknown thread) — the next `expectedIndex`. */
108
- length(threadId: string): Promise<number>;
109
- /**
110
- * Copy the prefix `[0, upToIndex)` onto a fresh, empty `newThreadId`.
111
- * Without `upToIndex` the full source is copied. The fork then appends
112
- * independently. Rejects (plain `Error`) if `newThreadId` already has
113
- * entries, the source is unknown, or `upToIndex` is out of range.
114
- * Implementations may copy-on-write or physically copy; observable behavior
115
- * must match a full copy.
116
- */
117
- fork(input: {
118
- threadId: string;
119
- newThreadId: string; /** Exclusive index cutoff. */
120
- upToIndex?: number;
121
- }): Promise<void>;
122
- }
123
- /**
124
- * Rejection from {@link AgentEventLogStore.append} when the thread's stored
125
- * length is not the `expectedIndex` the writer held — a concurrent writer
126
- * appended first. `actualIndex` is the next index the store would accept.
127
- */
128
- declare class AgentEventLogConflictError extends AgentError {
129
- readonly threadId: string;
130
- readonly expectedIndex: number;
131
- readonly actualIndex: number;
132
- constructor(threadId: string, expectedIndex: number, actualIndex: number);
133
- }
134
- /**
135
- * In-memory reference store, and the baseline the conformance suite runs
136
- * against. Per-thread entries are held in a contiguous, index-ordered list;
137
- * append's check-and-push runs synchronously (no `await` between reading the
138
- * length and writing), so two appends racing on the same `expectedIndex`
139
- * resolve to exactly one winner. Every stored and returned entry is
140
- * `structuredClone`d, so a caller can neither mutate stored state through a
141
- * value it appended nor through a value it read.
142
- */
143
- declare function createInMemoryEventLogStore(): AgentEventLogStore;
144
- //#endregion
145
- export { AgentLogVerification as a, assertAgentLogEntry as c, assertEventLogStoreConformance as d, AgentLogEntry as i, assertJsonSerializable as l, AgentEventLogConflictError as n, JsonValue as o, AgentEventLogStore as r, NonSerializableAgentEventError as s, AGENT_EVENT_SCHEMA_VERSION as t, createInMemoryEventLogStore as u };