@statelyai/agent 2.0.0-alpha.28 → 2.0.0-alpha.30

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 (80) hide show
  1. package/dist/ai-sdk.cjs +150 -27
  2. package/dist/ai-sdk.d.cts +59 -36
  3. package/dist/ai-sdk.d.mts +59 -36
  4. package/dist/ai-sdk.mjs +148 -24
  5. package/dist/{decision-RQ0iv0oZ.mjs → decision-BHkvuImD.mjs} +74 -8
  6. package/dist/{decision-CmM8-HHz.cjs → decision-CIb7ddIv.cjs} +113 -30
  7. package/dist/{text-logic-f5F5sCdc.cjs → event-log-BZRfBRd7.cjs} +814 -7
  8. package/dist/{text-logic-CIqHAmBi.mjs → event-log-DJCMHek_.mjs} +680 -4
  9. package/dist/{event-log-store-BIPOz-di.d.mts → event-log-store-CIIJohjj.d.mts} +90 -5
  10. package/dist/{event-log-store-2xzFmgr2.d.cts → event-log-store-CLAC9q2Y.d.cts} +90 -5
  11. package/dist/event-log-store-DZR4IIWe.cjs +95 -0
  12. package/dist/event-log-store-DsP6GCRh.mjs +84 -0
  13. package/dist/index.cjs +576 -58
  14. package/dist/index.d.cts +104 -510
  15. package/dist/index.d.mts +104 -510
  16. package/dist/index.mjs +547 -32
  17. package/dist/log.cjs +77 -20
  18. package/dist/log.d.cts +5 -5
  19. package/dist/log.d.mts +5 -5
  20. package/dist/log.mjs +58 -3
  21. package/dist/machines.cjs +1 -1
  22. package/dist/machines.d.cts +15 -15
  23. package/dist/machines.d.mts +15 -15
  24. package/dist/machines.mjs +1 -1
  25. package/dist/model-source-BCKg4qJ1.cjs +44 -0
  26. package/dist/model-source-BaHwJ1wK.mjs +39 -0
  27. package/dist/openai.cjs +11 -11
  28. package/dist/openai.d.cts +28 -26
  29. package/dist/openai.d.mts +28 -26
  30. package/dist/openai.mjs +3 -3
  31. package/dist/otel.cjs +5 -4
  32. package/dist/otel.d.cts +5 -7
  33. package/dist/otel.d.mts +5 -7
  34. package/dist/otel.mjs +5 -3
  35. package/dist/{run-agent-xNTxpt82.mjs → run-agent-BpHqkaZw.mjs} +181 -44
  36. package/dist/{run-agent-COXXc0RW.d.mts → run-agent-CAVt5R-r.d.mts} +95 -30
  37. package/dist/{run-agent-ByO-Bxyd.d.cts → run-agent-CTlMc3Jb.d.cts} +95 -30
  38. package/dist/{run-agent-Dmf8GV2d.cjs → run-agent-ctLCvNgL.cjs} +230 -88
  39. package/dist/{setup-agent-BuanDXeh.mjs → setup-agent-7rV_cujV.mjs} +15 -9
  40. package/dist/setup-agent-CGELn1qZ.d.mts +577 -0
  41. package/dist/setup-agent-CLPCkXsu.d.cts +577 -0
  42. package/dist/{setup-agent-DV4cTou-.cjs → setup-agent-DoUk7EdC.cjs} +31 -20
  43. package/dist/tanstack-ai.cjs +627 -0
  44. package/dist/tanstack-ai.d.cts +204 -0
  45. package/dist/tanstack-ai.d.mts +204 -0
  46. package/dist/tanstack-ai.mjs +618 -0
  47. package/dist/testing.cjs +204 -985
  48. package/dist/testing.d.cts +132 -347
  49. package/dist/testing.d.mts +132 -347
  50. package/dist/testing.mjs +191 -973
  51. package/dist/{text-logic-IjfYy9DP.d.cts → text-logic-BRYOPWvY.d.mts} +52 -12
  52. package/dist/{text-logic-D-czVPYp.d.mts → text-logic-DmciuVUQ.d.cts} +52 -12
  53. package/dist/{types-BgNbNKnJ.d.mts → types-Dp5_Ru4R.d.cts} +2 -2
  54. package/dist/{types-hR5f5YXa.d.cts → types-Dp5_Ru4R.d.mts} +2 -2
  55. package/dist/usage-BkM3z02Y.d.mts +17 -0
  56. package/dist/usage-Cm_ovz9V.d.cts +17 -0
  57. package/dist/{utils-_q7F-AZu.d.mts → utils-BnXdWih3.d.mts} +1 -2
  58. package/dist/{utils-o4YRdHJX.d.cts → utils-ebVpCYoF.d.cts} +1 -2
  59. package/dist/validate.cjs +239 -8
  60. package/dist/validate.d.cts +110 -3
  61. package/dist/validate.d.mts +110 -3
  62. package/dist/validate.mjs +238 -7
  63. package/dist/verify-COFWyprJ.mjs +1181 -0
  64. package/dist/verify-CVlsTZ-V.cjs +1222 -0
  65. package/dist/verify-Cn86rT8l.d.mts +414 -0
  66. package/dist/verify-Dzwd4Mvk.d.cts +414 -0
  67. package/package.json +44 -31
  68. package/readme.md +40 -28
  69. package/skills/add-evals/SKILL.md +129 -0
  70. package/skills/add-traces/SKILL.md +135 -0
  71. package/skills/generate-machine/SKILL.md +143 -69
  72. package/skills/graph-engineering/SKILL.md +33 -0
  73. package/skills/improve-machine/SKILL.md +241 -0
  74. package/skills/improve-machine/reference.md +101 -0
  75. package/skills/loop-to-machine/SKILL.md +183 -0
  76. package/skills/loop-to-machine/policy.md +158 -0
  77. package/dist/event-log-store-2pAFiWuc.mjs +0 -576
  78. package/dist/event-log-store-C-COhIXP.cjs +0 -702
  79. package/dist/usage-BdEjFuIi.mjs +0 -5
  80. package/dist/usage-efOQPdf_.cjs +0 -10
@@ -1,6 +1,5 @@
1
- import { Z as AgentError, t as AgentCallUsage } from "./text-logic-D-czVPYp.mjs";
2
- import { AnyMachineSnapshot, AnyStateMachine, EventObject, Snapshot, SnapshotFrom } from "xstate";
3
-
1
+ import { I as DecisionAttempt, Q as AgentError, t as AgentCallUsage } from "./text-logic-BRYOPWvY.mjs";
2
+ import { Actor, AnyMachineSnapshot, AnyStateMachine, EventObject, Snapshot, SnapshotFrom } from "xstate";
4
3
  //#region src/event-log.d.ts
5
4
  /** The durable entry envelope version. */
6
5
  declare const AGENT_EVENT_SCHEMA_VERSION: 1;
@@ -46,6 +45,15 @@ interface AgentLogEntry {
46
45
  metadata?: Record<string, JsonValue>;
47
46
  /** Recorded projection hash used by replay verification. */
48
47
  verification?: AgentLogVerification;
48
+ /**
49
+ * The decision attempts the machine did NOT accept before this entry's
50
+ * event landed (guard rejections, non-offered options, unknown types,
51
+ * invalid payloads), in the order they were made, when a decider
52
+ * (`agent.decide`, or a host using `decideNext`) needed more than one try.
53
+ * Omitted when there are none. Replay-ignored: it explains the entry, it
54
+ * does not change the fold.
55
+ */
56
+ attempts?: DecisionAttempt[];
49
57
  }
50
58
  /** The payload of the reserved {@link AGENT_INIT_EVENT_TYPE} first entry. */
51
59
  interface AgentInitEvent extends EventObject {
@@ -134,6 +142,8 @@ interface CreateReplayEntryOptions {
134
142
  recordedAt?: string;
135
143
  causationId?: string;
136
144
  metadata?: Record<string, JsonValue>;
145
+ /** Rejected decision attempts that preceded `event`; omitted when empty. */
146
+ attempts?: DecisionAttempt[];
137
147
  /** Record `verification.stateHash` (default `true`). */
138
148
  verification?: boolean;
139
149
  /**
@@ -220,6 +230,29 @@ declare function agentCallOccurrence(history: readonly (EventObject | AgentLogEn
220
230
  * `undefined` until some entry reports it, and non-finite values are ignored.
221
231
  */
222
232
  declare function getUsageFromEvents(entries: readonly (EventObject | AgentLogEntry)[]): AgentCallUsage;
233
+ /** One entry's rejected decision attempts, as {@link getDecisionAttempts} returns them. */
234
+ interface AgentLogDecisionAttempts {
235
+ /** The entry's `index` in the log. */
236
+ index: number;
237
+ /**
238
+ * The entry's event type: the event the attempts preceded, or an
239
+ * `xstate.error.actor.*` type when the decision exhausted its retries.
240
+ */
241
+ eventType: string;
242
+ attempts: DecisionAttempt[];
243
+ }
244
+ /**
245
+ * The decision attempts a log recorded but the machine never accepted, in log
246
+ * order — the input for improving a decider from its traces. Two sources:
247
+ *
248
+ * - `entry.attempts`: the failed tries before the entry's event landed.
249
+ * - An `xstate.error.actor.*` entry whose `error` is a decision-exhausted
250
+ * error (`code: "decision-exhausted"`) that kept its `attempts`: every try
251
+ * failed. Another actor error's `attempts` field is not read.
252
+ *
253
+ * Entries with neither are skipped.
254
+ */
255
+ declare function getDecisionAttempts(entries: readonly AgentLogEntry[]): AgentLogDecisionAttempts[];
223
256
  /**
224
257
  * Rewrites a journaled `xstate.done.actor`/`xstate.error.actor` event's
225
258
  * `sessionId` to the session the CURRENT fold minted for that `actorId`.
@@ -261,8 +294,51 @@ interface ReplayResult<TMachine extends AnyStateMachine> {
261
294
  * (`machine.restoreSnapshot`) and folds the rest of the log onto it.
262
295
  */
263
296
  declare function replay<TMachine extends AnyStateMachine>(machine: TMachine, entries: readonly AgentLogEntry[], options?: ReplayOptions): ReplayResult<TMachine>;
297
+ /** A log being recorded from a plain actor. See {@link recordLog}. */
298
+ interface LogRecorder {
299
+ /**
300
+ * The entries so far, init entry first, in the shape {@link replay} folds.
301
+ * Throws the recording's error if an event could not be journaled, and
302
+ * throws when there is no init entry yet (not started, or attached late).
303
+ */
304
+ readonly entries: AgentLogEntry[];
305
+ /** Stops recording. Entries recorded so far stay readable. */
306
+ stop(): void;
307
+ }
308
+ /**
309
+ * Records a plain `createActor` run as an event log, with no
310
+ * `createAgentRuntime`: the init entry (the actor's `input`, or the snapshot
311
+ * it was created from), then every event the root machine processed, invoke
312
+ * completions with their outputs inline. Attach it before `actor.start()`.
313
+ *
314
+ * @example
315
+ * ```ts no-check
316
+ * const actor = createActor(machine, { input });
317
+ * const log = recordLog(actor);
318
+ * actor.start();
319
+ * // ...later
320
+ * const { snapshot } = replay(machine, log.entries); // no actor runs
321
+ * ```
322
+ */
323
+ declare function recordLog(actor: Actor<AnyStateMachine>): LogRecorder;
264
324
  //#endregion
265
325
  //#region src/event-log-store.d.ts
326
+ /** Options for {@link AgentEventLogStore.listThreads}. */
327
+ interface ListThreadsOptions {
328
+ /** Only thread ids that start with this string. */
329
+ prefix?: string;
330
+ /** At most this many ids per page (a positive integer). Omit for all. */
331
+ limit?: number;
332
+ /** The `cursor` of the previous page, to continue after it. */
333
+ cursor?: string;
334
+ }
335
+ /** One page of {@link AgentEventLogStore.listThreads}. */
336
+ interface ListThreadsResult {
337
+ /** Thread ids in a stable store-defined order (the reference sorts them). */
338
+ threadIds: string[];
339
+ /** Present when more ids remain: pass it back as `options.cursor`. Opaque. */
340
+ cursor?: string;
341
+ }
266
342
  /**
267
343
  * An append-only event log: the authoritative durability artifact of a thread.
268
344
  * The journal of external inputs IS the source of truth — deterministic
@@ -309,9 +385,18 @@ interface AgentEventLogStore {
309
385
  */
310
386
  fork(input: {
311
387
  threadId: string;
312
- newThreadId: string; /** Exclusive index cutoff. */
388
+ newThreadId: string;
389
+ /** Exclusive index cutoff. */
313
390
  upToIndex?: number;
314
391
  }): Promise<void>;
392
+ /**
393
+ * Optional: list the threads that hold at least one entry, so a caller
394
+ * (an improver reading traces, a retention job) need not record thread ids
395
+ * itself. Pages with `limit` + `cursor`; the cursor is opaque and the order
396
+ * is stable across pages. Optional so existing stores keep compiling;
397
+ * `assertEventLogStoreConformance` checks it only when it is present.
398
+ */
399
+ listThreads?(options?: ListThreadsOptions): Promise<ListThreadsResult>;
315
400
  }
316
401
  /**
317
402
  * Rejection from {@link AgentEventLogStore.append} when the thread's stored
@@ -335,4 +420,4 @@ declare class AgentEventLogConflictError extends AgentError {
335
420
  */
336
421
  declare function createInMemoryEventLogStore(): AgentEventLogStore;
337
422
  //#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 };
423
+ export { rebindActorSession as A, createReplayEntry as C, getSnapshotStateHash as D, getLogExecutionId as E, replay as M, validateReplayEntries as N, getUsageFromEvents as O, assertJsonSerializable as S, getDecisionAttempts as T, NonSerializableAgentEventError as _, AGENT_INIT_EVENT_TYPE as a, agentCallOccurrence as b, AgentLogEntry as c, AgentMachineVersionMismatchError as d, AgentPersistedSnapshot as f, LogRecorder as g, JsonValue as h, AGENT_EVENT_SCHEMA_VERSION as i, recordLog as j, initEntry 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, ReplayOptions as v, forkEventLog as w, assertAgentLogEntry as x, ReplayResult as y };
@@ -1,6 +1,5 @@
1
- import { Z as AgentError, t as AgentCallUsage } from "./text-logic-IjfYy9DP.cjs";
2
- import { AnyMachineSnapshot, AnyStateMachine, EventObject, Snapshot, SnapshotFrom } from "xstate";
3
-
1
+ import { I as DecisionAttempt, Q as AgentError, t as AgentCallUsage } from "./text-logic-DmciuVUQ.cjs";
2
+ import { Actor, AnyMachineSnapshot, AnyStateMachine, EventObject, Snapshot, SnapshotFrom } from "xstate";
4
3
  //#region src/event-log.d.ts
5
4
  /** The durable entry envelope version. */
6
5
  declare const AGENT_EVENT_SCHEMA_VERSION: 1;
@@ -46,6 +45,15 @@ interface AgentLogEntry {
46
45
  metadata?: Record<string, JsonValue>;
47
46
  /** Recorded projection hash used by replay verification. */
48
47
  verification?: AgentLogVerification;
48
+ /**
49
+ * The decision attempts the machine did NOT accept before this entry's
50
+ * event landed (guard rejections, non-offered options, unknown types,
51
+ * invalid payloads), in the order they were made, when a decider
52
+ * (`agent.decide`, or a host using `decideNext`) needed more than one try.
53
+ * Omitted when there are none. Replay-ignored: it explains the entry, it
54
+ * does not change the fold.
55
+ */
56
+ attempts?: DecisionAttempt[];
49
57
  }
50
58
  /** The payload of the reserved {@link AGENT_INIT_EVENT_TYPE} first entry. */
51
59
  interface AgentInitEvent extends EventObject {
@@ -134,6 +142,8 @@ interface CreateReplayEntryOptions {
134
142
  recordedAt?: string;
135
143
  causationId?: string;
136
144
  metadata?: Record<string, JsonValue>;
145
+ /** Rejected decision attempts that preceded `event`; omitted when empty. */
146
+ attempts?: DecisionAttempt[];
137
147
  /** Record `verification.stateHash` (default `true`). */
138
148
  verification?: boolean;
139
149
  /**
@@ -220,6 +230,29 @@ declare function agentCallOccurrence(history: readonly (EventObject | AgentLogEn
220
230
  * `undefined` until some entry reports it, and non-finite values are ignored.
221
231
  */
222
232
  declare function getUsageFromEvents(entries: readonly (EventObject | AgentLogEntry)[]): AgentCallUsage;
233
+ /** One entry's rejected decision attempts, as {@link getDecisionAttempts} returns them. */
234
+ interface AgentLogDecisionAttempts {
235
+ /** The entry's `index` in the log. */
236
+ index: number;
237
+ /**
238
+ * The entry's event type: the event the attempts preceded, or an
239
+ * `xstate.error.actor.*` type when the decision exhausted its retries.
240
+ */
241
+ eventType: string;
242
+ attempts: DecisionAttempt[];
243
+ }
244
+ /**
245
+ * The decision attempts a log recorded but the machine never accepted, in log
246
+ * order — the input for improving a decider from its traces. Two sources:
247
+ *
248
+ * - `entry.attempts`: the failed tries before the entry's event landed.
249
+ * - An `xstate.error.actor.*` entry whose `error` is a decision-exhausted
250
+ * error (`code: "decision-exhausted"`) that kept its `attempts`: every try
251
+ * failed. Another actor error's `attempts` field is not read.
252
+ *
253
+ * Entries with neither are skipped.
254
+ */
255
+ declare function getDecisionAttempts(entries: readonly AgentLogEntry[]): AgentLogDecisionAttempts[];
223
256
  /**
224
257
  * Rewrites a journaled `xstate.done.actor`/`xstate.error.actor` event's
225
258
  * `sessionId` to the session the CURRENT fold minted for that `actorId`.
@@ -261,8 +294,51 @@ interface ReplayResult<TMachine extends AnyStateMachine> {
261
294
  * (`machine.restoreSnapshot`) and folds the rest of the log onto it.
262
295
  */
263
296
  declare function replay<TMachine extends AnyStateMachine>(machine: TMachine, entries: readonly AgentLogEntry[], options?: ReplayOptions): ReplayResult<TMachine>;
297
+ /** A log being recorded from a plain actor. See {@link recordLog}. */
298
+ interface LogRecorder {
299
+ /**
300
+ * The entries so far, init entry first, in the shape {@link replay} folds.
301
+ * Throws the recording's error if an event could not be journaled, and
302
+ * throws when there is no init entry yet (not started, or attached late).
303
+ */
304
+ readonly entries: AgentLogEntry[];
305
+ /** Stops recording. Entries recorded so far stay readable. */
306
+ stop(): void;
307
+ }
308
+ /**
309
+ * Records a plain `createActor` run as an event log, with no
310
+ * `createAgentRuntime`: the init entry (the actor's `input`, or the snapshot
311
+ * it was created from), then every event the root machine processed, invoke
312
+ * completions with their outputs inline. Attach it before `actor.start()`.
313
+ *
314
+ * @example
315
+ * ```ts no-check
316
+ * const actor = createActor(machine, { input });
317
+ * const log = recordLog(actor);
318
+ * actor.start();
319
+ * // ...later
320
+ * const { snapshot } = replay(machine, log.entries); // no actor runs
321
+ * ```
322
+ */
323
+ declare function recordLog(actor: Actor<AnyStateMachine>): LogRecorder;
264
324
  //#endregion
265
325
  //#region src/event-log-store.d.ts
326
+ /** Options for {@link AgentEventLogStore.listThreads}. */
327
+ interface ListThreadsOptions {
328
+ /** Only thread ids that start with this string. */
329
+ prefix?: string;
330
+ /** At most this many ids per page (a positive integer). Omit for all. */
331
+ limit?: number;
332
+ /** The `cursor` of the previous page, to continue after it. */
333
+ cursor?: string;
334
+ }
335
+ /** One page of {@link AgentEventLogStore.listThreads}. */
336
+ interface ListThreadsResult {
337
+ /** Thread ids in a stable store-defined order (the reference sorts them). */
338
+ threadIds: string[];
339
+ /** Present when more ids remain: pass it back as `options.cursor`. Opaque. */
340
+ cursor?: string;
341
+ }
266
342
  /**
267
343
  * An append-only event log: the authoritative durability artifact of a thread.
268
344
  * The journal of external inputs IS the source of truth — deterministic
@@ -309,9 +385,18 @@ interface AgentEventLogStore {
309
385
  */
310
386
  fork(input: {
311
387
  threadId: string;
312
- newThreadId: string; /** Exclusive index cutoff. */
388
+ newThreadId: string;
389
+ /** Exclusive index cutoff. */
313
390
  upToIndex?: number;
314
391
  }): Promise<void>;
392
+ /**
393
+ * Optional: list the threads that hold at least one entry, so a caller
394
+ * (an improver reading traces, a retention job) need not record thread ids
395
+ * itself. Pages with `limit` + `cursor`; the cursor is opaque and the order
396
+ * is stable across pages. Optional so existing stores keep compiling;
397
+ * `assertEventLogStoreConformance` checks it only when it is present.
398
+ */
399
+ listThreads?(options?: ListThreadsOptions): Promise<ListThreadsResult>;
315
400
  }
316
401
  /**
317
402
  * Rejection from {@link AgentEventLogStore.append} when the thread's stored
@@ -335,4 +420,4 @@ declare class AgentEventLogConflictError extends AgentError {
335
420
  */
336
421
  declare function createInMemoryEventLogStore(): AgentEventLogStore;
337
422
  //#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 };
423
+ export { rebindActorSession as A, createReplayEntry as C, getSnapshotStateHash as D, getLogExecutionId as E, replay as M, validateReplayEntries as N, getUsageFromEvents as O, assertJsonSerializable as S, getDecisionAttempts as T, NonSerializableAgentEventError as _, AGENT_INIT_EVENT_TYPE as a, agentCallOccurrence as b, AgentLogEntry as c, AgentMachineVersionMismatchError as d, AgentPersistedSnapshot as f, LogRecorder as g, JsonValue as h, AGENT_EVENT_SCHEMA_VERSION as i, recordLog as j, initEntry 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, ReplayOptions as v, forkEventLog as w, assertAgentLogEntry as x, ReplayResult as y };
@@ -0,0 +1,95 @@
1
+ const require_event_log = require("./event-log-BZRfBRd7.cjs");
2
+ //#region src/event-log-store.ts
3
+ /**
4
+ * Durable storage for {@link AgentLogEntry} logs: the one interface a host
5
+ * implements, plus the in-memory reference implementation the conformance
6
+ * suite is written against.
7
+ * @module
8
+ */
9
+ /**
10
+ * Rejection from {@link AgentEventLogStore.append} when the thread's stored
11
+ * length is not the `expectedIndex` the writer held — a concurrent writer
12
+ * appended first. `actualIndex` is the next index the store would accept.
13
+ */
14
+ var AgentEventLogConflictError = class extends require_event_log.AgentError {
15
+ threadId;
16
+ expectedIndex;
17
+ actualIndex;
18
+ constructor(threadId, expectedIndex, actualIndex) {
19
+ super("event-log-conflict", `AgentEventLogStore.append: index conflict on thread "${threadId}": expected index ${expectedIndex} but found ${actualIndex} — a concurrent writer won.`);
20
+ this.name = "AgentEventLogConflictError";
21
+ this.threadId = threadId;
22
+ this.expectedIndex = expectedIndex;
23
+ this.actualIndex = actualIndex;
24
+ }
25
+ };
26
+ /**
27
+ * In-memory reference store, and the baseline the conformance suite runs
28
+ * against. Per-thread entries are held in a contiguous, index-ordered list;
29
+ * append's check-and-push runs synchronously (no `await` between reading the
30
+ * length and writing), so two appends racing on the same `expectedIndex`
31
+ * resolve to exactly one winner. Every stored and returned entry is
32
+ * `structuredClone`d, so a caller can neither mutate stored state through a
33
+ * value it appended nor through a value it read.
34
+ */
35
+ function createInMemoryEventLogStore() {
36
+ const threads = /* @__PURE__ */ new Map();
37
+ const clone = (value) => structuredClone(value);
38
+ return {
39
+ async append({ threadId, expectedIndex, entries }) {
40
+ for (const entry of entries) require_event_log.assertAgentLogEntry(entry);
41
+ for (let i = 0; i < entries.length; i++) if (entries[i].index !== expectedIndex + i) throw new Error(`AgentEventLogStore.append: entry.index (${entries[i].index}) must be contiguous from expectedIndex (${expectedIndex}); expected ${expectedIndex + i} at position ${i} on thread "${threadId}".`);
42
+ const list = threads.get(threadId);
43
+ const length = list ? list.length : 0;
44
+ if (length !== expectedIndex) throw new AgentEventLogConflictError(threadId, expectedIndex, length);
45
+ const ids = new Set((list ?? []).map((entry) => entry.id));
46
+ for (const entry of entries) {
47
+ if (ids.has(entry.id)) throw new Error(`AgentEventLogStore.append: duplicate event id "${entry.id}" in thread "${threadId}".`);
48
+ ids.add(entry.id);
49
+ }
50
+ const cloned = entries.map((entry) => clone(entry));
51
+ if (list) for (const entry of cloned) list.push(entry);
52
+ else threads.set(threadId, cloned);
53
+ },
54
+ async read(threadId, options) {
55
+ const list = threads.get(threadId) ?? [];
56
+ const from = options?.from ?? 0;
57
+ return list.slice(from).map((entry) => clone(entry));
58
+ },
59
+ async length(threadId) {
60
+ return threads.get(threadId)?.length ?? 0;
61
+ },
62
+ async fork({ threadId, newThreadId, upToIndex }) {
63
+ if ((threads.get(newThreadId)?.length ?? 0) > 0) throw new Error(`AgentEventLogStore.fork: newThreadId "${newThreadId}" already has entries.`);
64
+ const source = threads.get(threadId);
65
+ if (!source) throw new Error(`AgentEventLogStore.fork: unknown source thread "${threadId}".`);
66
+ const upTo = upToIndex ?? source.length;
67
+ if (!Number.isInteger(upTo) || upTo < 1 || upTo > source.length) throw new Error(`AgentEventLogStore.fork: upToIndex must be an integer in [1, ${source.length}] on thread "${threadId}"; got ${String(upTo)}.`);
68
+ threads.set(newThreadId, source.slice(0, upTo).map((entry) => clone(entry)));
69
+ },
70
+ async listThreads(options = {}) {
71
+ const { prefix = "", limit, cursor } = options;
72
+ if (limit !== void 0 && (!Number.isInteger(limit) || limit < 1)) throw new Error(`AgentEventLogStore.listThreads: limit must be a positive integer; got ${String(limit)}.`);
73
+ const ids = [...threads].filter(([id, list]) => list.length > 0 && id.startsWith(prefix)).map(([id]) => id).filter((id) => cursor === void 0 || id > cursor).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
74
+ if (limit === void 0 || ids.length <= limit) return { threadIds: ids };
75
+ const page = ids.slice(0, limit);
76
+ return {
77
+ threadIds: page,
78
+ cursor: page[page.length - 1]
79
+ };
80
+ }
81
+ };
82
+ }
83
+ //#endregion
84
+ Object.defineProperty(exports, "AgentEventLogConflictError", {
85
+ enumerable: true,
86
+ get: function() {
87
+ return AgentEventLogConflictError;
88
+ }
89
+ });
90
+ Object.defineProperty(exports, "createInMemoryEventLogStore", {
91
+ enumerable: true,
92
+ get: function() {
93
+ return createInMemoryEventLogStore;
94
+ }
95
+ });
@@ -0,0 +1,84 @@
1
+ import { c as assertAgentLogEntry, st as AgentError } from "./event-log-DJCMHek_.mjs";
2
+ //#region src/event-log-store.ts
3
+ /**
4
+ * Durable storage for {@link AgentLogEntry} logs: the one interface a host
5
+ * implements, plus the in-memory reference implementation the conformance
6
+ * suite is written against.
7
+ * @module
8
+ */
9
+ /**
10
+ * Rejection from {@link AgentEventLogStore.append} when the thread's stored
11
+ * length is not the `expectedIndex` the writer held — a concurrent writer
12
+ * appended first. `actualIndex` is the next index the store would accept.
13
+ */
14
+ var AgentEventLogConflictError = class extends AgentError {
15
+ threadId;
16
+ expectedIndex;
17
+ actualIndex;
18
+ constructor(threadId, expectedIndex, actualIndex) {
19
+ super("event-log-conflict", `AgentEventLogStore.append: index conflict on thread "${threadId}": expected index ${expectedIndex} but found ${actualIndex} — a concurrent writer won.`);
20
+ this.name = "AgentEventLogConflictError";
21
+ this.threadId = threadId;
22
+ this.expectedIndex = expectedIndex;
23
+ this.actualIndex = actualIndex;
24
+ }
25
+ };
26
+ /**
27
+ * In-memory reference store, and the baseline the conformance suite runs
28
+ * against. Per-thread entries are held in a contiguous, index-ordered list;
29
+ * append's check-and-push runs synchronously (no `await` between reading the
30
+ * length and writing), so two appends racing on the same `expectedIndex`
31
+ * resolve to exactly one winner. Every stored and returned entry is
32
+ * `structuredClone`d, so a caller can neither mutate stored state through a
33
+ * value it appended nor through a value it read.
34
+ */
35
+ function createInMemoryEventLogStore() {
36
+ const threads = /* @__PURE__ */ new Map();
37
+ const clone = (value) => structuredClone(value);
38
+ return {
39
+ async append({ threadId, expectedIndex, entries }) {
40
+ for (const entry of entries) assertAgentLogEntry(entry);
41
+ for (let i = 0; i < entries.length; i++) if (entries[i].index !== expectedIndex + i) throw new Error(`AgentEventLogStore.append: entry.index (${entries[i].index}) must be contiguous from expectedIndex (${expectedIndex}); expected ${expectedIndex + i} at position ${i} on thread "${threadId}".`);
42
+ const list = threads.get(threadId);
43
+ const length = list ? list.length : 0;
44
+ if (length !== expectedIndex) throw new AgentEventLogConflictError(threadId, expectedIndex, length);
45
+ const ids = new Set((list ?? []).map((entry) => entry.id));
46
+ for (const entry of entries) {
47
+ if (ids.has(entry.id)) throw new Error(`AgentEventLogStore.append: duplicate event id "${entry.id}" in thread "${threadId}".`);
48
+ ids.add(entry.id);
49
+ }
50
+ const cloned = entries.map((entry) => clone(entry));
51
+ if (list) for (const entry of cloned) list.push(entry);
52
+ else threads.set(threadId, cloned);
53
+ },
54
+ async read(threadId, options) {
55
+ const list = threads.get(threadId) ?? [];
56
+ const from = options?.from ?? 0;
57
+ return list.slice(from).map((entry) => clone(entry));
58
+ },
59
+ async length(threadId) {
60
+ return threads.get(threadId)?.length ?? 0;
61
+ },
62
+ async fork({ threadId, newThreadId, upToIndex }) {
63
+ if ((threads.get(newThreadId)?.length ?? 0) > 0) throw new Error(`AgentEventLogStore.fork: newThreadId "${newThreadId}" already has entries.`);
64
+ const source = threads.get(threadId);
65
+ if (!source) throw new Error(`AgentEventLogStore.fork: unknown source thread "${threadId}".`);
66
+ const upTo = upToIndex ?? source.length;
67
+ if (!Number.isInteger(upTo) || upTo < 1 || upTo > source.length) throw new Error(`AgentEventLogStore.fork: upToIndex must be an integer in [1, ${source.length}] on thread "${threadId}"; got ${String(upTo)}.`);
68
+ threads.set(newThreadId, source.slice(0, upTo).map((entry) => clone(entry)));
69
+ },
70
+ async listThreads(options = {}) {
71
+ const { prefix = "", limit, cursor } = options;
72
+ if (limit !== void 0 && (!Number.isInteger(limit) || limit < 1)) throw new Error(`AgentEventLogStore.listThreads: limit must be a positive integer; got ${String(limit)}.`);
73
+ const ids = [...threads].filter(([id, list]) => list.length > 0 && id.startsWith(prefix)).map(([id]) => id).filter((id) => cursor === void 0 || id > cursor).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
74
+ if (limit === void 0 || ids.length <= limit) return { threadIds: ids };
75
+ const page = ids.slice(0, limit);
76
+ return {
77
+ threadIds: page,
78
+ cursor: page[page.length - 1]
79
+ };
80
+ }
81
+ };
82
+ }
83
+ //#endregion
84
+ export { createInMemoryEventLogStore as n, AgentEventLogConflictError as t };