@statelyai/agent 2.0.0-alpha.24 → 2.0.0-alpha.25

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 (53) hide show
  1. package/dist/ai-sdk.cjs +30 -34
  2. package/dist/ai-sdk.d.cts +27 -31
  3. package/dist/ai-sdk.d.mts +27 -31
  4. package/dist/ai-sdk.mjs +27 -31
  5. package/dist/decision-CM9CYZ6t.cjs +519 -0
  6. package/dist/decision-DzSv1NpD.mjs +453 -0
  7. package/dist/event-log-store-Ba2fsc4E.mjs +576 -0
  8. package/dist/event-log-store-DQmImLYk.cjs +702 -0
  9. package/dist/event-log-store-DvOcs10J.d.cts +338 -0
  10. package/dist/event-log-store-DxyVgnas.d.mts +338 -0
  11. package/dist/index.cjs +429 -4272
  12. package/dist/index.d.cts +104 -1005
  13. package/dist/index.d.mts +104 -1005
  14. package/dist/index.mjs +389 -4202
  15. package/dist/log.cjs +392 -0
  16. package/dist/log.d.cts +32 -0
  17. package/dist/log.d.mts +32 -0
  18. package/dist/log.mjs +371 -0
  19. package/dist/machines.cjs +27 -16
  20. package/dist/machines.d.cts +1 -1
  21. package/dist/machines.d.mts +1 -1
  22. package/dist/machines.mjs +27 -16
  23. package/dist/openai.cjs +16 -15
  24. package/dist/openai.d.cts +9 -9
  25. package/dist/openai.d.mts +9 -9
  26. package/dist/openai.mjs +10 -9
  27. package/dist/otel.d.cts +1 -1
  28. package/dist/otel.d.mts +1 -1
  29. package/dist/{run-agent-Ck7Sa3Tb.d.mts → run-agent-BOfoJg5B.d.cts} +86 -387
  30. package/dist/{run-agent-DWqA8KiI.d.cts → run-agent-CG343kFs.d.mts} +86 -387
  31. package/dist/run-agent-Cb1-LS5P.cjs +1783 -0
  32. package/dist/run-agent-DvDQd4If.mjs +1669 -0
  33. package/dist/{setup-agent-CeO2fARv.mjs → setup-agent-CFW-jPI8.mjs} +9 -20
  34. package/dist/{setup-agent-Dl2VELLi.cjs → setup-agent-CPf7MxnG.cjs} +20 -37
  35. package/dist/testing.cjs +1222 -0
  36. package/dist/testing.d.cts +602 -0
  37. package/dist/testing.d.mts +602 -0
  38. package/dist/testing.mjs +1212 -0
  39. package/dist/{text-logic-DJBK3LbG.d.mts → text-logic-BFEOxyxv.d.cts} +71 -147
  40. package/dist/text-logic-Bl_ZRxDi.mjs +833 -0
  41. package/dist/text-logic-C8xyr6Ag.cjs +1091 -0
  42. package/dist/{text-logic-C7bSnH_B.d.cts → text-logic-hZSiRUo1.d.mts} +71 -147
  43. package/dist/{types-CjHk5OdH.d.cts → types-B1Qs2q3q.d.cts} +2 -1
  44. package/dist/{types-DWA6X9R-.d.mts → types-tA3SdczG.d.mts} +2 -1
  45. package/dist/usage-BdEjFuIi.mjs +5 -0
  46. package/dist/usage-efOQPdf_.cjs +10 -0
  47. package/dist/utils-C1p37X_c.d.mts +209 -0
  48. package/dist/utils-RalRn9sk.d.cts +209 -0
  49. package/package.json +24 -4
  50. package/readme.md +2 -2
  51. package/skills/generate-machine/SKILL.md +4 -6
  52. package/dist/decision-BBZ2jMO1.mjs +0 -1490
  53. package/dist/decision-Cv6SfNWl.cjs +0 -1856
@@ -0,0 +1,338 @@
1
+ import { Z as AgentError, t as AgentCallUsage } from "./text-logic-BFEOxyxv.cjs";
2
+ import { AnyMachineSnapshot, AnyStateMachine, EventObject, Snapshot, SnapshotFrom } from "xstate";
3
+
4
+ //#region src/event-log.d.ts
5
+ /** The durable entry envelope version. */
6
+ declare const AGENT_EVENT_SCHEMA_VERSION: 1;
7
+ /**
8
+ * The reserved event type of the first entry of every log. It carries the
9
+ * machine `input` (fresh start) or a persisted `snapshot` (continuation), so a
10
+ * log replays with no side channel. Lives in the reserved `@agent.*` namespace
11
+ * so it can never collide with a machine's own vocabulary; it is consumed by
12
+ * {@link replay} and never fed to `transition`.
13
+ */
14
+ declare const AGENT_INIT_EVENT_TYPE: "@agent.init";
15
+ /** Values that round-trip through JSON without adapters or silent coercion. */
16
+ type JsonValue = null | boolean | number | string | JsonValue[] | {
17
+ [key: string]: JsonValue;
18
+ };
19
+ /** A persisted (JSON-safe) machine snapshot, as `machine.getPersistedSnapshot()` returns. */
20
+ type AgentPersistedSnapshot = Snapshot<unknown>;
21
+ /** Recorded projection hash used by {@link replay} verification. */
22
+ interface AgentLogVerification {
23
+ /** {@link getSnapshotStateHash} of the persisted snapshot after this entry is applied. */
24
+ stateHash: string;
25
+ }
26
+ /**
27
+ * One journaled external input, JSON-safe and stored verbatim.
28
+ */
29
+ interface AgentLogEntry {
30
+ /** Version of this outer envelope, independent of the machine event type. */
31
+ schemaVersion: typeof AGENT_EVENT_SCHEMA_VERSION;
32
+ /** Stable identity within the log. Forked prefixes retain their ids. */
33
+ id: string;
34
+ /** 0-based position in the log. */
35
+ index: number;
36
+ /** RFC 3339 wall-clock time when the host accepted the entry. Metadata only. */
37
+ recordedAt: string;
38
+ /** The authored XState machine id. */
39
+ machineId: string;
40
+ /** Explicit version or structural hash of the machine that accepted the event. */
41
+ machineVersion: string;
42
+ event: EventObject;
43
+ /** Optional causal parent entry id, scoped to the same log. */
44
+ causationId?: string;
45
+ /** Host-owned, JSON-safe; stored verbatim, never interpreted. */
46
+ metadata?: Record<string, JsonValue>;
47
+ /** Recorded projection hash used by replay verification. */
48
+ verification?: AgentLogVerification;
49
+ }
50
+ /** The payload of the reserved {@link AGENT_INIT_EVENT_TYPE} first entry. */
51
+ interface AgentInitEvent extends EventObject {
52
+ type: typeof AGENT_INIT_EVENT_TYPE;
53
+ /** Machine input for a fresh start. Mutually exclusive with `snapshot`. */
54
+ input?: unknown;
55
+ /** Persisted snapshot to continue from. Mutually exclusive with `input`. */
56
+ snapshot?: AgentPersistedSnapshot;
57
+ }
58
+ /** A malformed or internally inconsistent log. */
59
+ declare class AgentEventLogError extends AgentError {
60
+ constructor(message: string);
61
+ }
62
+ /** A precise failure when an entry would not survive a JSON round-trip. */
63
+ declare class NonSerializableAgentEventError extends AgentError {
64
+ readonly path: string;
65
+ readonly valueType: string;
66
+ constructor(path: string, valueType: string);
67
+ }
68
+ /** Replay reached a state that does not match the entry's recorded hash. */
69
+ declare class AgentReplayDivergenceError extends AgentError {
70
+ readonly eventId: string;
71
+ readonly index: number;
72
+ readonly kind: "state" | "missing-verification";
73
+ readonly expected?: string | undefined;
74
+ readonly actual?: string | undefined;
75
+ constructor(eventId: string, index: number, kind: "state" | "missing-verification", expected?: string | undefined, actual?: string | undefined);
76
+ }
77
+ /**
78
+ * An entry was recorded against a different machine (id) or a different
79
+ * machine version than the one replaying it. An init-with-snapshot entry is
80
+ * exempt: that entry IS the bridge from the old version to the new one.
81
+ */
82
+ declare class AgentMachineVersionMismatchError extends AgentError {
83
+ readonly eventId: string;
84
+ readonly index: number;
85
+ readonly expected: {
86
+ machineId: string;
87
+ machineVersion: string;
88
+ };
89
+ readonly actual: {
90
+ machineId: string;
91
+ machineVersion: string;
92
+ };
93
+ constructor(eventId: string, index: number, expected: {
94
+ machineId: string;
95
+ machineVersion: string;
96
+ }, actual: {
97
+ machineId: string;
98
+ machineVersion: string;
99
+ });
100
+ }
101
+ /**
102
+ * Rejects values JSON would drop or coerce. Unlike `JSON.stringify`, this does
103
+ * not silently erase `undefined`/functions or turn non-finite numbers into
104
+ * `null`; durable entries contain only plain JSON values.
105
+ */
106
+ declare function assertJsonSerializable(value: unknown, path?: string, ancestors?: WeakSet<object>): asserts value is JsonValue;
107
+ /** Validates the complete durable envelope before append/export/replay. */
108
+ declare function assertAgentLogEntry(entry: unknown): asserts entry is AgentLogEntry;
109
+ /**
110
+ * The canonical hash of a PERSISTED snapshot (`machine.getPersistedSnapshot()`,
111
+ * or {@link replay}'s `persistedSnapshot`) — the value recorded in an entry's
112
+ * `verification.stateHash`.
113
+ *
114
+ * Stripped before hashing, because they are re-minted on every fold and would
115
+ * otherwise make two identical runs hash differently: `sessionId`,
116
+ * `_nextTimerId` and `_nextActorIds` at the snapshot root, `sessionId` on each
117
+ * `children[*]` entry (recursively, through nested child snapshots), and
118
+ * `undefined`-valued properties (so a snapshot hashes the same before and
119
+ * after a JSON round-trip). Stripping is confined to those structural
120
+ * positions: a `sessionId` inside `context`, `output`, `error` or an event
121
+ * payload is application data and is hashed. Object keys are sorted, so key
122
+ * order is irrelevant.
123
+ *
124
+ * A change detector, not a cryptographic digest.
125
+ */
126
+ declare function getSnapshotStateHash(snapshot: AgentPersistedSnapshot | unknown): string;
127
+ /** Options controlling the durable envelope created by {@link createReplayEntry}. */
128
+ interface CreateReplayEntryOptions {
129
+ /** Explicit machine version; defaults to the machine's resolved version. */
130
+ machineVersion?: string;
131
+ /** Stable entry id; defaults to `evt_` plus the zero-padded index. */
132
+ id?: string;
133
+ /** RFC 3339 acceptance time; defaults to the current wall clock. */
134
+ recordedAt?: string;
135
+ causationId?: string;
136
+ metadata?: Record<string, JsonValue>;
137
+ /** Record `verification.stateHash` (default `true`). */
138
+ verification?: boolean;
139
+ /**
140
+ * The snapshot this entry folds to, when the caller already has it — avoids
141
+ * re-folding the whole prefix just to compute the hash. Accepts a live or a
142
+ * persisted snapshot.
143
+ */
144
+ snapshot?: AnyMachineSnapshot | AgentPersistedSnapshot;
145
+ }
146
+ /**
147
+ * Creates a JSON-safe, self-describing entry for `event` appended after
148
+ * `entries` (which must be the complete prefix, so `index` and the recorded
149
+ * state hash line up).
150
+ */
151
+ declare function createReplayEntry(machine: AnyStateMachine, entries: readonly AgentLogEntry[], event: EventObject, options?: CreateReplayEntryOptions): AgentLogEntry;
152
+ /** How a log begins: from machine input, or from a persisted snapshot. */
153
+ type AgentLogInit = {
154
+ input?: unknown;
155
+ snapshot?: never;
156
+ } | {
157
+ snapshot: AgentPersistedSnapshot;
158
+ input?: never;
159
+ };
160
+ /**
161
+ * The reserved first entry of a log. Pass EXACTLY one of:
162
+ *
163
+ * - `{ input }` — a fresh start; replay folds from `initialTransition`.
164
+ * - `{ snapshot }` — a continuation from a persisted snapshot: a version
165
+ * bridge, or a legacy snapshot that predates the log. Replay restores it
166
+ * purely (no actors started) and folds the rest of the log onto it.
167
+ *
168
+ * `options.metadata.executionId` names the lineage; this library always sets
169
+ * one, and readers must tolerate its absence in logs written elsewhere.
170
+ */
171
+ declare function initEntry(machine: AnyStateMachine, init?: AgentLogInit, options?: CreateReplayEntryOptions): AgentLogEntry;
172
+ /**
173
+ * The log's execution id: the lineage identity pinned in the init entry's
174
+ * `metadata.executionId`.
175
+ *
176
+ * Minted once per run and inherited verbatim by every resume of that log, so
177
+ * it names one lineage rather than one process. Entry ids cannot serve this
178
+ * role — the built-in ids are index-derived, so every log's init entry is
179
+ * `evt_00000000`. A fork copies the init entry, so it shares its parent's
180
+ * execution id by construction.
181
+ *
182
+ * Returns `undefined` for a log with no init entry and for one written without
183
+ * the field — callers must treat the id as optional.
184
+ */
185
+ declare function getLogExecutionId(entries: readonly AgentLogEntry[]): string | undefined;
186
+ /**
187
+ * Validates a log before replay or append: every envelope well-formed, indices
188
+ * contiguous from 0, ids unique, the first entry the reserved init entry, and
189
+ * one consistent machine identity throughout.
190
+ *
191
+ * With `machine`, entries are also checked against that machine's id and
192
+ * resolved version — a mismatch throws {@link AgentMachineVersionMismatchError}.
193
+ * An init-with-snapshot entry is exempt from the version check: that entry is
194
+ * itself the bridge from whatever version produced the snapshot.
195
+ */
196
+ declare function validateReplayEntries(entries: readonly AgentLogEntry[], options?: {
197
+ machine?: AnyStateMachine;
198
+ machineVersion?: string;
199
+ }): void;
200
+ /**
201
+ * The prefix `[0, upToIndex)` of a log, as a new log. `upToIndex` is exclusive
202
+ * and must leave the init entry in place, so the fork is still self-contained.
203
+ */
204
+ declare function forkEventLog(entries: readonly AgentLogEntry[], upToIndex: number): AgentLogEntry[];
205
+ /**
206
+ * The 1-based occurrence `n` for the NEXT call at invoke site `siteId`:
207
+ * `1 + completions`, where a completion is a journaled `xstate.done.actor` OR
208
+ * `xstate.error.actor` for that `actorId` (an error is a semantic completion).
209
+ * The one counting rule behind every `${siteId}#${n}` call key, so a live run
210
+ * and a replay derive the same `n` by construction.
211
+ */
212
+ declare function agentCallOccurrence(history: readonly (EventObject | AgentLogEntry)[] | undefined, siteId: string): number;
213
+ /**
214
+ * Folds the reserved `@agent.usage` entries of a log into one cumulative usage
215
+ * total. The log is the source of truth, so the totals are a pure projection of
216
+ * it: replay a log, fold it, and you get the numbers the run reported with no
217
+ * host-side accumulator in between.
218
+ *
219
+ * Accepts entries or bare events. Token fields are partial sums: a field stays
220
+ * `undefined` until some entry reports it, and non-finite values are ignored.
221
+ */
222
+ declare function getUsageFromEvents(entries: readonly (EventObject | AgentLogEntry)[]): AgentCallUsage;
223
+ /**
224
+ * Rewrites a journaled `xstate.done.actor`/`xstate.error.actor` event's
225
+ * `sessionId` to the session the CURRENT fold minted for that `actorId`.
226
+ *
227
+ * Session ids are re-minted on every fold, and XState drops a completion event
228
+ * whose `sessionId` does not match the live child — silently, as a no-op
229
+ * transition. Rebinding is what makes a journaled completion replayable at all.
230
+ * `sessions` caches the mapping per fold, so a later event referring to the
231
+ * recorded session of an already-stopped child still resolves.
232
+ */
233
+ declare function rebindActorSession(event: EventObject, snapshot: AnyMachineSnapshot, sessions: Map<string, string>): EventObject;
234
+ /** Options for {@link replay}. */
235
+ interface ReplayOptions {
236
+ /** Explicit expected machine version; defaults to the machine's resolved version. */
237
+ machineVersion?: string;
238
+ /**
239
+ * `true` (default) checks the entries that carry a `verification.stateHash`;
240
+ * `'strict'` additionally requires every entry to carry one; `false` skips
241
+ * verification entirely.
242
+ */
243
+ verify?: boolean | "strict";
244
+ }
245
+ /** The result of a {@link replay}. */
246
+ interface ReplayResult<TMachine extends AnyStateMachine> {
247
+ /** The folded live snapshot (no actors started, no effects run). */
248
+ snapshot: SnapshotFrom<TMachine>;
249
+ /** Its persisted projection — what a host stores, and what hashes. */
250
+ persistedSnapshot: AgentPersistedSnapshot;
251
+ }
252
+ /**
253
+ * Folds a log through XState's pure `initialTransition`/`transition` WITHOUT
254
+ * executing anything: no actor is started, no action runs, no model is called.
255
+ * A journaled `xstate.done.actor` entry carries the completed actor's output
256
+ * inline, so the invoke it belongs to is never re-run. Crash recovery, fork
257
+ * resume, and time travel in one call.
258
+ *
259
+ * The first entry is the reserved {@link initEntry}: `input` folds from
260
+ * `initialTransition`, `snapshot` restores the persisted snapshot purely
261
+ * (`machine.restoreSnapshot`) and folds the rest of the log onto it.
262
+ */
263
+ declare function replay<TMachine extends AnyStateMachine>(machine: TMachine, entries: readonly AgentLogEntry[], options?: ReplayOptions): ReplayResult<TMachine>;
264
+ //#endregion
265
+ //#region src/event-log-store.d.ts
266
+ /**
267
+ * An append-only event log: the authoritative durability artifact of a thread.
268
+ * The journal of external inputs IS the source of truth — deterministic
269
+ * `replay` derives every snapshot from it, and a fork is a copied log prefix.
270
+ *
271
+ * Userland stores (a Postgres table with a `(thread_id, index)` primary key, an
272
+ * append-only object in blob storage, …) implement this one shape so they
273
+ * interoperate; {@link createInMemoryEventLogStore} is the reference, and
274
+ * `assertEventLogStoreConformance` checks an implementation against it.
275
+ */
276
+ interface AgentEventLogStore {
277
+ /**
278
+ * Append `entries` starting at `expectedIndex` (the current length of the
279
+ * thread's log; 0 for a new thread). Atomic — all entries land or none do.
280
+ * Rejects with {@link AgentEventLogConflictError} when the thread's length
281
+ * differs from `expectedIndex`: a concurrent writer appended first. Each
282
+ * entry's `index` must be contiguous from `expectedIndex` (a plain `Error`
283
+ * otherwise: that is caller misuse, not a race).
284
+ */
285
+ append(input: {
286
+ threadId: string;
287
+ expectedIndex: number;
288
+ entries: AgentLogEntry[];
289
+ }): Promise<void>;
290
+ /**
291
+ * Read a thread's entries in log order. `from` (default 0) skips entries
292
+ * below that index for incremental catch-up. An unknown thread reads as an
293
+ * empty array.
294
+ */
295
+ read(threadId: string, options?: {
296
+ from?: number;
297
+ }): Promise<AgentLogEntry[]>;
298
+ /** The thread's current log length (0 for an unknown thread) — the next `expectedIndex`. */
299
+ length(threadId: string): Promise<number>;
300
+ /**
301
+ * Copy the prefix `[0, upToIndex)` onto a fresh, empty `newThreadId`.
302
+ * Without `upToIndex` the full source is copied. `upToIndex` is exclusive
303
+ * and must be an integer in `[1, length]`, so the fork keeps the reserved
304
+ * init entry and stays a self-contained log. The fork then appends
305
+ * independently. Rejects (plain `Error`) if `newThreadId` already has
306
+ * entries, the source is unknown, or `upToIndex` is out of range.
307
+ * Implementations may copy-on-write or physically copy; observable behavior
308
+ * must match a full copy.
309
+ */
310
+ fork(input: {
311
+ threadId: string;
312
+ newThreadId: string; /** Exclusive index cutoff. */
313
+ upToIndex?: number;
314
+ }): Promise<void>;
315
+ }
316
+ /**
317
+ * Rejection from {@link AgentEventLogStore.append} when the thread's stored
318
+ * length is not the `expectedIndex` the writer held — a concurrent writer
319
+ * appended first. `actualIndex` is the next index the store would accept.
320
+ */
321
+ declare class AgentEventLogConflictError extends AgentError {
322
+ readonly threadId: string;
323
+ readonly expectedIndex: number;
324
+ readonly actualIndex: number;
325
+ constructor(threadId: string, expectedIndex: number, actualIndex: number);
326
+ }
327
+ /**
328
+ * In-memory reference store, and the baseline the conformance suite runs
329
+ * against. Per-thread entries are held in a contiguous, index-ordered list;
330
+ * append's check-and-push runs synchronously (no `await` between reading the
331
+ * length and writing), so two appends racing on the same `expectedIndex`
332
+ * resolve to exactly one winner. Every stored and returned entry is
333
+ * `structuredClone`d, so a caller can neither mutate stored state through a
334
+ * value it appended nor through a value it read.
335
+ */
336
+ declare function createInMemoryEventLogStore(): AgentEventLogStore;
337
+ //#endregion
338
+ export { validateReplayEntries as A, forkEventLog as C, initEntry as D, getUsageFromEvents as E, rebindActorSession as O, createReplayEntry as S, getSnapshotStateHash as T, ReplayOptions as _, AGENT_INIT_EVENT_TYPE as a, assertAgentLogEntry as b, AgentLogEntry as c, AgentMachineVersionMismatchError as d, AgentPersistedSnapshot as f, NonSerializableAgentEventError as g, JsonValue as h, AGENT_EVENT_SCHEMA_VERSION as i, replay as k, AgentLogInit as l, CreateReplayEntryOptions as m, AgentEventLogStore as n, AgentEventLogError as o, AgentReplayDivergenceError as p, createInMemoryEventLogStore as r, AgentInitEvent as s, AgentEventLogConflictError as t, AgentLogVerification as u, ReplayResult as v, getLogExecutionId as w, assertJsonSerializable as x, agentCallOccurrence as y };
@@ -0,0 +1,338 @@
1
+ import { Z as AgentError, t as AgentCallUsage } from "./text-logic-hZSiRUo1.mjs";
2
+ import { AnyMachineSnapshot, AnyStateMachine, EventObject, Snapshot, SnapshotFrom } from "xstate";
3
+
4
+ //#region src/event-log.d.ts
5
+ /** The durable entry envelope version. */
6
+ declare const AGENT_EVENT_SCHEMA_VERSION: 1;
7
+ /**
8
+ * The reserved event type of the first entry of every log. It carries the
9
+ * machine `input` (fresh start) or a persisted `snapshot` (continuation), so a
10
+ * log replays with no side channel. Lives in the reserved `@agent.*` namespace
11
+ * so it can never collide with a machine's own vocabulary; it is consumed by
12
+ * {@link replay} and never fed to `transition`.
13
+ */
14
+ declare const AGENT_INIT_EVENT_TYPE: "@agent.init";
15
+ /** Values that round-trip through JSON without adapters or silent coercion. */
16
+ type JsonValue = null | boolean | number | string | JsonValue[] | {
17
+ [key: string]: JsonValue;
18
+ };
19
+ /** A persisted (JSON-safe) machine snapshot, as `machine.getPersistedSnapshot()` returns. */
20
+ type AgentPersistedSnapshot = Snapshot<unknown>;
21
+ /** Recorded projection hash used by {@link replay} verification. */
22
+ interface AgentLogVerification {
23
+ /** {@link getSnapshotStateHash} of the persisted snapshot after this entry is applied. */
24
+ stateHash: string;
25
+ }
26
+ /**
27
+ * One journaled external input, JSON-safe and stored verbatim.
28
+ */
29
+ interface AgentLogEntry {
30
+ /** Version of this outer envelope, independent of the machine event type. */
31
+ schemaVersion: typeof AGENT_EVENT_SCHEMA_VERSION;
32
+ /** Stable identity within the log. Forked prefixes retain their ids. */
33
+ id: string;
34
+ /** 0-based position in the log. */
35
+ index: number;
36
+ /** RFC 3339 wall-clock time when the host accepted the entry. Metadata only. */
37
+ recordedAt: string;
38
+ /** The authored XState machine id. */
39
+ machineId: string;
40
+ /** Explicit version or structural hash of the machine that accepted the event. */
41
+ machineVersion: string;
42
+ event: EventObject;
43
+ /** Optional causal parent entry id, scoped to the same log. */
44
+ causationId?: string;
45
+ /** Host-owned, JSON-safe; stored verbatim, never interpreted. */
46
+ metadata?: Record<string, JsonValue>;
47
+ /** Recorded projection hash used by replay verification. */
48
+ verification?: AgentLogVerification;
49
+ }
50
+ /** The payload of the reserved {@link AGENT_INIT_EVENT_TYPE} first entry. */
51
+ interface AgentInitEvent extends EventObject {
52
+ type: typeof AGENT_INIT_EVENT_TYPE;
53
+ /** Machine input for a fresh start. Mutually exclusive with `snapshot`. */
54
+ input?: unknown;
55
+ /** Persisted snapshot to continue from. Mutually exclusive with `input`. */
56
+ snapshot?: AgentPersistedSnapshot;
57
+ }
58
+ /** A malformed or internally inconsistent log. */
59
+ declare class AgentEventLogError extends AgentError {
60
+ constructor(message: string);
61
+ }
62
+ /** A precise failure when an entry would not survive a JSON round-trip. */
63
+ declare class NonSerializableAgentEventError extends AgentError {
64
+ readonly path: string;
65
+ readonly valueType: string;
66
+ constructor(path: string, valueType: string);
67
+ }
68
+ /** Replay reached a state that does not match the entry's recorded hash. */
69
+ declare class AgentReplayDivergenceError extends AgentError {
70
+ readonly eventId: string;
71
+ readonly index: number;
72
+ readonly kind: "state" | "missing-verification";
73
+ readonly expected?: string | undefined;
74
+ readonly actual?: string | undefined;
75
+ constructor(eventId: string, index: number, kind: "state" | "missing-verification", expected?: string | undefined, actual?: string | undefined);
76
+ }
77
+ /**
78
+ * An entry was recorded against a different machine (id) or a different
79
+ * machine version than the one replaying it. An init-with-snapshot entry is
80
+ * exempt: that entry IS the bridge from the old version to the new one.
81
+ */
82
+ declare class AgentMachineVersionMismatchError extends AgentError {
83
+ readonly eventId: string;
84
+ readonly index: number;
85
+ readonly expected: {
86
+ machineId: string;
87
+ machineVersion: string;
88
+ };
89
+ readonly actual: {
90
+ machineId: string;
91
+ machineVersion: string;
92
+ };
93
+ constructor(eventId: string, index: number, expected: {
94
+ machineId: string;
95
+ machineVersion: string;
96
+ }, actual: {
97
+ machineId: string;
98
+ machineVersion: string;
99
+ });
100
+ }
101
+ /**
102
+ * Rejects values JSON would drop or coerce. Unlike `JSON.stringify`, this does
103
+ * not silently erase `undefined`/functions or turn non-finite numbers into
104
+ * `null`; durable entries contain only plain JSON values.
105
+ */
106
+ declare function assertJsonSerializable(value: unknown, path?: string, ancestors?: WeakSet<object>): asserts value is JsonValue;
107
+ /** Validates the complete durable envelope before append/export/replay. */
108
+ declare function assertAgentLogEntry(entry: unknown): asserts entry is AgentLogEntry;
109
+ /**
110
+ * The canonical hash of a PERSISTED snapshot (`machine.getPersistedSnapshot()`,
111
+ * or {@link replay}'s `persistedSnapshot`) — the value recorded in an entry's
112
+ * `verification.stateHash`.
113
+ *
114
+ * Stripped before hashing, because they are re-minted on every fold and would
115
+ * otherwise make two identical runs hash differently: `sessionId`,
116
+ * `_nextTimerId` and `_nextActorIds` at the snapshot root, `sessionId` on each
117
+ * `children[*]` entry (recursively, through nested child snapshots), and
118
+ * `undefined`-valued properties (so a snapshot hashes the same before and
119
+ * after a JSON round-trip). Stripping is confined to those structural
120
+ * positions: a `sessionId` inside `context`, `output`, `error` or an event
121
+ * payload is application data and is hashed. Object keys are sorted, so key
122
+ * order is irrelevant.
123
+ *
124
+ * A change detector, not a cryptographic digest.
125
+ */
126
+ declare function getSnapshotStateHash(snapshot: AgentPersistedSnapshot | unknown): string;
127
+ /** Options controlling the durable envelope created by {@link createReplayEntry}. */
128
+ interface CreateReplayEntryOptions {
129
+ /** Explicit machine version; defaults to the machine's resolved version. */
130
+ machineVersion?: string;
131
+ /** Stable entry id; defaults to `evt_` plus the zero-padded index. */
132
+ id?: string;
133
+ /** RFC 3339 acceptance time; defaults to the current wall clock. */
134
+ recordedAt?: string;
135
+ causationId?: string;
136
+ metadata?: Record<string, JsonValue>;
137
+ /** Record `verification.stateHash` (default `true`). */
138
+ verification?: boolean;
139
+ /**
140
+ * The snapshot this entry folds to, when the caller already has it — avoids
141
+ * re-folding the whole prefix just to compute the hash. Accepts a live or a
142
+ * persisted snapshot.
143
+ */
144
+ snapshot?: AnyMachineSnapshot | AgentPersistedSnapshot;
145
+ }
146
+ /**
147
+ * Creates a JSON-safe, self-describing entry for `event` appended after
148
+ * `entries` (which must be the complete prefix, so `index` and the recorded
149
+ * state hash line up).
150
+ */
151
+ declare function createReplayEntry(machine: AnyStateMachine, entries: readonly AgentLogEntry[], event: EventObject, options?: CreateReplayEntryOptions): AgentLogEntry;
152
+ /** How a log begins: from machine input, or from a persisted snapshot. */
153
+ type AgentLogInit = {
154
+ input?: unknown;
155
+ snapshot?: never;
156
+ } | {
157
+ snapshot: AgentPersistedSnapshot;
158
+ input?: never;
159
+ };
160
+ /**
161
+ * The reserved first entry of a log. Pass EXACTLY one of:
162
+ *
163
+ * - `{ input }` — a fresh start; replay folds from `initialTransition`.
164
+ * - `{ snapshot }` — a continuation from a persisted snapshot: a version
165
+ * bridge, or a legacy snapshot that predates the log. Replay restores it
166
+ * purely (no actors started) and folds the rest of the log onto it.
167
+ *
168
+ * `options.metadata.executionId` names the lineage; this library always sets
169
+ * one, and readers must tolerate its absence in logs written elsewhere.
170
+ */
171
+ declare function initEntry(machine: AnyStateMachine, init?: AgentLogInit, options?: CreateReplayEntryOptions): AgentLogEntry;
172
+ /**
173
+ * The log's execution id: the lineage identity pinned in the init entry's
174
+ * `metadata.executionId`.
175
+ *
176
+ * Minted once per run and inherited verbatim by every resume of that log, so
177
+ * it names one lineage rather than one process. Entry ids cannot serve this
178
+ * role — the built-in ids are index-derived, so every log's init entry is
179
+ * `evt_00000000`. A fork copies the init entry, so it shares its parent's
180
+ * execution id by construction.
181
+ *
182
+ * Returns `undefined` for a log with no init entry and for one written without
183
+ * the field — callers must treat the id as optional.
184
+ */
185
+ declare function getLogExecutionId(entries: readonly AgentLogEntry[]): string | undefined;
186
+ /**
187
+ * Validates a log before replay or append: every envelope well-formed, indices
188
+ * contiguous from 0, ids unique, the first entry the reserved init entry, and
189
+ * one consistent machine identity throughout.
190
+ *
191
+ * With `machine`, entries are also checked against that machine's id and
192
+ * resolved version — a mismatch throws {@link AgentMachineVersionMismatchError}.
193
+ * An init-with-snapshot entry is exempt from the version check: that entry is
194
+ * itself the bridge from whatever version produced the snapshot.
195
+ */
196
+ declare function validateReplayEntries(entries: readonly AgentLogEntry[], options?: {
197
+ machine?: AnyStateMachine;
198
+ machineVersion?: string;
199
+ }): void;
200
+ /**
201
+ * The prefix `[0, upToIndex)` of a log, as a new log. `upToIndex` is exclusive
202
+ * and must leave the init entry in place, so the fork is still self-contained.
203
+ */
204
+ declare function forkEventLog(entries: readonly AgentLogEntry[], upToIndex: number): AgentLogEntry[];
205
+ /**
206
+ * The 1-based occurrence `n` for the NEXT call at invoke site `siteId`:
207
+ * `1 + completions`, where a completion is a journaled `xstate.done.actor` OR
208
+ * `xstate.error.actor` for that `actorId` (an error is a semantic completion).
209
+ * The one counting rule behind every `${siteId}#${n}` call key, so a live run
210
+ * and a replay derive the same `n` by construction.
211
+ */
212
+ declare function agentCallOccurrence(history: readonly (EventObject | AgentLogEntry)[] | undefined, siteId: string): number;
213
+ /**
214
+ * Folds the reserved `@agent.usage` entries of a log into one cumulative usage
215
+ * total. The log is the source of truth, so the totals are a pure projection of
216
+ * it: replay a log, fold it, and you get the numbers the run reported with no
217
+ * host-side accumulator in between.
218
+ *
219
+ * Accepts entries or bare events. Token fields are partial sums: a field stays
220
+ * `undefined` until some entry reports it, and non-finite values are ignored.
221
+ */
222
+ declare function getUsageFromEvents(entries: readonly (EventObject | AgentLogEntry)[]): AgentCallUsage;
223
+ /**
224
+ * Rewrites a journaled `xstate.done.actor`/`xstate.error.actor` event's
225
+ * `sessionId` to the session the CURRENT fold minted for that `actorId`.
226
+ *
227
+ * Session ids are re-minted on every fold, and XState drops a completion event
228
+ * whose `sessionId` does not match the live child — silently, as a no-op
229
+ * transition. Rebinding is what makes a journaled completion replayable at all.
230
+ * `sessions` caches the mapping per fold, so a later event referring to the
231
+ * recorded session of an already-stopped child still resolves.
232
+ */
233
+ declare function rebindActorSession(event: EventObject, snapshot: AnyMachineSnapshot, sessions: Map<string, string>): EventObject;
234
+ /** Options for {@link replay}. */
235
+ interface ReplayOptions {
236
+ /** Explicit expected machine version; defaults to the machine's resolved version. */
237
+ machineVersion?: string;
238
+ /**
239
+ * `true` (default) checks the entries that carry a `verification.stateHash`;
240
+ * `'strict'` additionally requires every entry to carry one; `false` skips
241
+ * verification entirely.
242
+ */
243
+ verify?: boolean | "strict";
244
+ }
245
+ /** The result of a {@link replay}. */
246
+ interface ReplayResult<TMachine extends AnyStateMachine> {
247
+ /** The folded live snapshot (no actors started, no effects run). */
248
+ snapshot: SnapshotFrom<TMachine>;
249
+ /** Its persisted projection — what a host stores, and what hashes. */
250
+ persistedSnapshot: AgentPersistedSnapshot;
251
+ }
252
+ /**
253
+ * Folds a log through XState's pure `initialTransition`/`transition` WITHOUT
254
+ * executing anything: no actor is started, no action runs, no model is called.
255
+ * A journaled `xstate.done.actor` entry carries the completed actor's output
256
+ * inline, so the invoke it belongs to is never re-run. Crash recovery, fork
257
+ * resume, and time travel in one call.
258
+ *
259
+ * The first entry is the reserved {@link initEntry}: `input` folds from
260
+ * `initialTransition`, `snapshot` restores the persisted snapshot purely
261
+ * (`machine.restoreSnapshot`) and folds the rest of the log onto it.
262
+ */
263
+ declare function replay<TMachine extends AnyStateMachine>(machine: TMachine, entries: readonly AgentLogEntry[], options?: ReplayOptions): ReplayResult<TMachine>;
264
+ //#endregion
265
+ //#region src/event-log-store.d.ts
266
+ /**
267
+ * An append-only event log: the authoritative durability artifact of a thread.
268
+ * The journal of external inputs IS the source of truth — deterministic
269
+ * `replay` derives every snapshot from it, and a fork is a copied log prefix.
270
+ *
271
+ * Userland stores (a Postgres table with a `(thread_id, index)` primary key, an
272
+ * append-only object in blob storage, …) implement this one shape so they
273
+ * interoperate; {@link createInMemoryEventLogStore} is the reference, and
274
+ * `assertEventLogStoreConformance` checks an implementation against it.
275
+ */
276
+ interface AgentEventLogStore {
277
+ /**
278
+ * Append `entries` starting at `expectedIndex` (the current length of the
279
+ * thread's log; 0 for a new thread). Atomic — all entries land or none do.
280
+ * Rejects with {@link AgentEventLogConflictError} when the thread's length
281
+ * differs from `expectedIndex`: a concurrent writer appended first. Each
282
+ * entry's `index` must be contiguous from `expectedIndex` (a plain `Error`
283
+ * otherwise: that is caller misuse, not a race).
284
+ */
285
+ append(input: {
286
+ threadId: string;
287
+ expectedIndex: number;
288
+ entries: AgentLogEntry[];
289
+ }): Promise<void>;
290
+ /**
291
+ * Read a thread's entries in log order. `from` (default 0) skips entries
292
+ * below that index for incremental catch-up. An unknown thread reads as an
293
+ * empty array.
294
+ */
295
+ read(threadId: string, options?: {
296
+ from?: number;
297
+ }): Promise<AgentLogEntry[]>;
298
+ /** The thread's current log length (0 for an unknown thread) — the next `expectedIndex`. */
299
+ length(threadId: string): Promise<number>;
300
+ /**
301
+ * Copy the prefix `[0, upToIndex)` onto a fresh, empty `newThreadId`.
302
+ * Without `upToIndex` the full source is copied. `upToIndex` is exclusive
303
+ * and must be an integer in `[1, length]`, so the fork keeps the reserved
304
+ * init entry and stays a self-contained log. The fork then appends
305
+ * independently. Rejects (plain `Error`) if `newThreadId` already has
306
+ * entries, the source is unknown, or `upToIndex` is out of range.
307
+ * Implementations may copy-on-write or physically copy; observable behavior
308
+ * must match a full copy.
309
+ */
310
+ fork(input: {
311
+ threadId: string;
312
+ newThreadId: string; /** Exclusive index cutoff. */
313
+ upToIndex?: number;
314
+ }): Promise<void>;
315
+ }
316
+ /**
317
+ * Rejection from {@link AgentEventLogStore.append} when the thread's stored
318
+ * length is not the `expectedIndex` the writer held — a concurrent writer
319
+ * appended first. `actualIndex` is the next index the store would accept.
320
+ */
321
+ declare class AgentEventLogConflictError extends AgentError {
322
+ readonly threadId: string;
323
+ readonly expectedIndex: number;
324
+ readonly actualIndex: number;
325
+ constructor(threadId: string, expectedIndex: number, actualIndex: number);
326
+ }
327
+ /**
328
+ * In-memory reference store, and the baseline the conformance suite runs
329
+ * against. Per-thread entries are held in a contiguous, index-ordered list;
330
+ * append's check-and-push runs synchronously (no `await` between reading the
331
+ * length and writing), so two appends racing on the same `expectedIndex`
332
+ * resolve to exactly one winner. Every stored and returned entry is
333
+ * `structuredClone`d, so a caller can neither mutate stored state through a
334
+ * value it appended nor through a value it read.
335
+ */
336
+ declare function createInMemoryEventLogStore(): AgentEventLogStore;
337
+ //#endregion
338
+ export { validateReplayEntries as A, forkEventLog as C, initEntry as D, getUsageFromEvents as E, rebindActorSession as O, createReplayEntry as S, getSnapshotStateHash as T, ReplayOptions as _, AGENT_INIT_EVENT_TYPE as a, assertAgentLogEntry as b, AgentLogEntry as c, AgentMachineVersionMismatchError as d, AgentPersistedSnapshot as f, NonSerializableAgentEventError as g, JsonValue as h, AGENT_EVENT_SCHEMA_VERSION as i, replay as k, AgentLogInit as l, CreateReplayEntryOptions as m, AgentEventLogStore as n, AgentEventLogError as o, AgentReplayDivergenceError as p, createInMemoryEventLogStore as r, AgentInitEvent as s, AgentEventLogConflictError as t, AgentLogVerification as u, ReplayResult as v, getLogExecutionId as w, assertJsonSerializable as x, agentCallOccurrence as y };