@statelyai/agent 2.0.0-alpha.27 → 2.0.0-alpha.29
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.
- package/dist/ai-sdk.cjs +149 -26
- package/dist/ai-sdk.d.cts +57 -34
- package/dist/ai-sdk.d.mts +57 -34
- package/dist/ai-sdk.mjs +147 -23
- package/dist/{decision-RQ0iv0oZ.mjs → decision-Bl_rKQnU.mjs} +73 -7
- package/dist/{decision-CmM8-HHz.cjs → decision-oevZnkBe.cjs} +112 -29
- package/dist/{text-logic-f5F5sCdc.cjs → event-log-Dtb16p1p.cjs} +813 -6
- package/dist/{text-logic-CIqHAmBi.mjs → event-log-GPZO9p7_.mjs} +679 -3
- package/dist/{event-log-store-BIPOz-di.d.mts → event-log-store-CN9ygggF.d.cts} +90 -5
- package/dist/{event-log-store-2xzFmgr2.d.cts → event-log-store-DS836wch.d.mts} +90 -5
- package/dist/event-log-store-bCdskPNS.cjs +95 -0
- package/dist/event-log-store-yalq8C77.mjs +84 -0
- package/dist/index.cjs +571 -58
- package/dist/index.d.cts +104 -510
- package/dist/index.d.mts +104 -510
- package/dist/index.mjs +542 -32
- package/dist/log.cjs +77 -20
- package/dist/log.d.cts +5 -5
- package/dist/log.d.mts +5 -5
- package/dist/log.mjs +58 -3
- package/dist/machines.cjs +1 -1
- package/dist/machines.d.cts +15 -15
- package/dist/machines.d.mts +15 -15
- package/dist/machines.mjs +1 -1
- package/dist/model-source-C7FFP2Sj.mjs +39 -0
- package/dist/model-source-DjJPjGSP.cjs +44 -0
- package/dist/openai.cjs +10 -10
- package/dist/openai.d.cts +27 -25
- package/dist/openai.d.mts +27 -25
- package/dist/openai.mjs +2 -2
- package/dist/otel.cjs +5 -4
- package/dist/otel.d.cts +5 -7
- package/dist/otel.d.mts +5 -7
- package/dist/otel.mjs +5 -3
- package/dist/{run-agent-COXXc0RW.d.mts → run-agent-C9ubX8Tx.d.cts} +87 -30
- package/dist/{run-agent-xNTxpt82.mjs → run-agent-CuQT1xSS.mjs} +170 -42
- package/dist/{run-agent-ByO-Bxyd.d.cts → run-agent-CxSyZmIE.d.mts} +87 -30
- package/dist/{run-agent-Dmf8GV2d.cjs → run-agent-cToZ3K42.cjs} +219 -86
- package/dist/{setup-agent-DV4cTou-.cjs → setup-agent-DTF3NQg3.cjs} +31 -20
- package/dist/setup-agent-DlbgwsIJ.d.cts +577 -0
- package/dist/{setup-agent-BuanDXeh.mjs → setup-agent-DniLvDu7.mjs} +15 -9
- package/dist/setup-agent-tsc3vm5I.d.mts +577 -0
- package/dist/tanstack-ai.cjs +627 -0
- package/dist/tanstack-ai.d.cts +204 -0
- package/dist/tanstack-ai.d.mts +204 -0
- package/dist/tanstack-ai.mjs +618 -0
- package/dist/testing.cjs +98 -985
- package/dist/testing.d.cts +51 -347
- package/dist/testing.d.mts +51 -347
- package/dist/testing.mjs +86 -973
- package/dist/{text-logic-IjfYy9DP.d.cts → text-logic-9fv1i9aK.d.cts} +50 -10
- package/dist/{text-logic-D-czVPYp.d.mts → text-logic-BDbGjYMh.d.mts} +50 -10
- package/dist/{types-BgNbNKnJ.d.mts → types-Dp5_Ru4R.d.cts} +2 -2
- package/dist/{types-hR5f5YXa.d.cts → types-Dp5_Ru4R.d.mts} +2 -2
- package/dist/usage-D8UphgEA.d.mts +17 -0
- package/dist/usage-R1NTmLxY.d.cts +17 -0
- package/dist/{utils-_q7F-AZu.d.mts → utils-BnXdWih3.d.mts} +1 -2
- package/dist/{utils-o4YRdHJX.d.cts → utils-ebVpCYoF.d.cts} +1 -2
- package/dist/validate.cjs +239 -8
- package/dist/validate.d.cts +110 -3
- package/dist/validate.d.mts +110 -3
- package/dist/validate.mjs +238 -7
- package/dist/verify-B5qGC5WN.mjs +1181 -0
- package/dist/verify-CBuYIpsa.d.mts +414 -0
- package/dist/verify-Cqghu4gz.cjs +1222 -0
- package/dist/verify-DYH_2VzU.d.cts +414 -0
- package/package.json +44 -31
- package/readme.md +23 -5
- package/skills/generate-machine/SKILL.md +136 -64
- package/skills/improve-machine/SKILL.md +190 -0
- package/skills/improve-machine/reference.md +96 -0
- package/dist/event-log-store-2pAFiWuc.mjs +0 -576
- package/dist/event-log-store-C-COhIXP.cjs +0 -702
- package/dist/usage-BdEjFuIi.mjs +0 -5
- package/dist/usage-efOQPdf_.cjs +0 -10
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { AnyMachineSnapshot, AnyStateMachine, EventObject, Snapshot, SnapshotFrom } from "xstate";
|
|
3
|
-
|
|
1
|
+
import { I as DecisionAttempt, Q as AgentError, t as AgentCallUsage } from "./text-logic-9fv1i9aK.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;
|
|
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 {
|
|
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 {
|
|
2
|
-
import { AnyMachineSnapshot, AnyStateMachine, EventObject, Snapshot, SnapshotFrom } from "xstate";
|
|
3
|
-
|
|
1
|
+
import { I as DecisionAttempt, Q as AgentError, t as AgentCallUsage } from "./text-logic-BDbGjYMh.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;
|
|
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 {
|
|
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-Dtb16p1p.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-GPZO9p7_.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 };
|