@you-agent-factory/factory-emulator 0.0.0 → 0.0.1
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/LICENSE.md +19 -1
- package/README.md +305 -286
- package/dist/compatibility.d.ts +19 -0
- package/dist/compatibility.js +156 -0
- package/dist/event-sink.d.ts +29 -0
- package/dist/event-sink.js +58 -0
- package/dist/generated/scenario-schema.d.ts +268 -0
- package/dist/generated/scenario-schema.js +319 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/logical-move.d.ts +10 -0
- package/dist/logical-move.js +18 -0
- package/dist/recording-sink.d.ts +22 -0
- package/dist/recording-sink.js +122 -0
- package/dist/runtime-reference-conformance.d.ts +20 -0
- package/dist/runtime-reference-conformance.js +138 -0
- package/dist/runtime-reference-evidence.d.ts +9 -0
- package/dist/runtime-reference-evidence.js +193 -0
- package/dist/runtime-reference-fixtures.d.ts +7 -0
- package/dist/runtime-reference-fixtures.js +308 -0
- package/dist/runtime-reference.d.ts +48 -0
- package/dist/runtime-reference.js +143 -0
- package/dist/scenario-contracts.d.ts +81 -0
- package/dist/scenario-contracts.js +11 -0
- package/dist/scenario.d.ts +271 -0
- package/dist/scenario.js +333 -0
- package/dist/scheduler.d.ts +24 -0
- package/dist/scheduler.js +104 -0
- package/dist/session-contracts.d.ts +262 -0
- package/dist/session-contracts.js +74 -0
- package/dist/session.d.ts +4 -0
- package/dist/session.js +1490 -0
- package/dist/submission-replay.d.ts +14 -0
- package/dist/submission-replay.js +96 -0
- package/dist/submission-validation.d.ts +3 -0
- package/dist/submission-validation.js +113 -0
- package/examples/customer-support.scenario.v1.json +45 -0
- package/package.json +44 -22
- package/schema/scenario.schema.json +171 -0
- package/generated/factory-emulator-scenario.schema.json +0 -191
- package/generated/factory.schema.json +0 -2606
- package/src/contracts.ts +0 -41
- package/src/data-error.js +0 -21
- package/src/data-only.js +0 -208
- package/src/emulator.js +0 -195
- package/src/emulator.ts +0 -86
- package/src/examples.js +0 -86
- package/src/examples.ts +0 -11
- package/src/generated/factory-schema.d.ts +0 -3
- package/src/generated/factory-schema.js +0 -5
- package/src/generated/scenario-schema.d.ts +0 -4
- package/src/generated/scenario-schema.js +0 -6
- package/src/generated/scenario.ts +0 -103
- package/src/identity.js +0 -55
- package/src/index.js +0 -34
- package/src/index.ts +0 -102
- package/src/limits.js +0 -125
- package/src/parser.js +0 -113
- package/src/parser.ts +0 -56
- package/src/scheduler.js +0 -374
- package/src/semantics.js +0 -354
- package/src/semantics.ts +0 -38
- package/src/session.js +0 -1201
- package/src/session.ts +0 -324
- package/src/sinks.js +0 -118
- package/src/sinks.ts +0 -56
- package/src/support.js +0 -334
- package/src/support.ts +0 -15
- package/src/virtual-time.js +0 -36
package/src/session.ts
DELETED
|
@@ -1,324 +0,0 @@
|
|
|
1
|
-
import type { FactoryEventBatch, FactoryEventSink } from "./contracts.js";
|
|
2
|
-
import type {
|
|
3
|
-
EmulatorInitialSubmission,
|
|
4
|
-
EmulatorOutcome,
|
|
5
|
-
EmulatorScenario,
|
|
6
|
-
} from "./generated/scenario.js";
|
|
7
|
-
import type {
|
|
8
|
-
EmulatorFactoryDefinition,
|
|
9
|
-
EmulatorScenarioDiagnostic,
|
|
10
|
-
} from "./parser.js";
|
|
11
|
-
|
|
12
|
-
export type FactoryEmulatorConfigurationDiagnostic =
|
|
13
|
-
| EmulatorScenarioDiagnostic
|
|
14
|
-
| {
|
|
15
|
-
readonly code: "INVALID_LIMIT_CONFIGURATION";
|
|
16
|
-
readonly path: string;
|
|
17
|
-
readonly message: string;
|
|
18
|
-
readonly expectation: string;
|
|
19
|
-
}
|
|
20
|
-
| {
|
|
21
|
-
readonly code: "SYNCHRONOUS_WORK_LIMIT_EXCEEDED";
|
|
22
|
-
readonly path: "/initialSubmissions";
|
|
23
|
-
readonly message: string;
|
|
24
|
-
readonly expectation: string;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export interface FactoryEmulatorDataError {
|
|
28
|
-
readonly name: string;
|
|
29
|
-
readonly message: string;
|
|
30
|
-
readonly code: string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface FactoryEmulatorConfigurationError extends FactoryEmulatorDataError {
|
|
34
|
-
readonly name: "FactoryEmulatorConfigurationError";
|
|
35
|
-
readonly code: "INVALID_CONFIGURATION";
|
|
36
|
-
readonly diagnostics: readonly FactoryEmulatorConfigurationDiagnostic[];
|
|
37
|
-
}
|
|
38
|
-
export declare const FactoryEmulatorConfigurationError: {
|
|
39
|
-
new (diagnostics: readonly FactoryEmulatorConfigurationDiagnostic[]): FactoryEmulatorConfigurationError;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export interface FactoryEmulatorLifecycleError extends FactoryEmulatorDataError {
|
|
43
|
-
readonly name: "FactoryEmulatorLifecycleError";
|
|
44
|
-
readonly code: "INVALID_LIFECYCLE";
|
|
45
|
-
readonly command: "start" | "submit" | "advanceBy" | "advanceToNext" | "close" | "reset";
|
|
46
|
-
readonly phase:
|
|
47
|
-
| FactoryEmulatorSessionState["lifecycle"]
|
|
48
|
-
| "starting"
|
|
49
|
-
| "submitting"
|
|
50
|
-
| "advancing"
|
|
51
|
-
| "closing";
|
|
52
|
-
}
|
|
53
|
-
export declare const FactoryEmulatorLifecycleError: {
|
|
54
|
-
new (
|
|
55
|
-
command: FactoryEmulatorLifecycleError["command"],
|
|
56
|
-
phase: FactoryEmulatorLifecycleError["phase"],
|
|
57
|
-
): FactoryEmulatorLifecycleError;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export interface FactoryEmulatorDurationError extends FactoryEmulatorDataError {
|
|
61
|
-
readonly name: "FactoryEmulatorDurationError";
|
|
62
|
-
readonly code: "INVALID_DURATION";
|
|
63
|
-
readonly durationMs: number;
|
|
64
|
-
}
|
|
65
|
-
export declare const FactoryEmulatorDurationError: {
|
|
66
|
-
new (durationMs: number): FactoryEmulatorDurationError;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export interface FactoryEmulatorSubmissionError extends FactoryEmulatorDataError {
|
|
70
|
-
readonly name: "FactoryEmulatorSubmissionError";
|
|
71
|
-
readonly code: "INVALID_SUBMISSION";
|
|
72
|
-
readonly diagnostics: readonly EmulatorScenarioDiagnostic[];
|
|
73
|
-
}
|
|
74
|
-
export declare const FactoryEmulatorSubmissionError: {
|
|
75
|
-
new (diagnostics: readonly EmulatorScenarioDiagnostic[]): FactoryEmulatorSubmissionError;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export type FactoryEmulatorExecutionDiagnostic =
|
|
79
|
-
| {
|
|
80
|
-
readonly kind: "budget-exceeded";
|
|
81
|
-
readonly limit: "completedDispatches" | "events" | "virtualElapsedMs";
|
|
82
|
-
readonly configured: number;
|
|
83
|
-
readonly observed: number;
|
|
84
|
-
readonly virtualTime: string;
|
|
85
|
-
readonly virtualElapsedMs: number;
|
|
86
|
-
}
|
|
87
|
-
| {
|
|
88
|
-
readonly kind: "zero-duration-cycle";
|
|
89
|
-
readonly limit: "zeroDurationBatches";
|
|
90
|
-
readonly configured: number;
|
|
91
|
-
readonly observed: number;
|
|
92
|
-
readonly virtualTime: string;
|
|
93
|
-
readonly virtualElapsedMs: number;
|
|
94
|
-
}
|
|
95
|
-
| {
|
|
96
|
-
readonly kind: "synchronous-work-limit";
|
|
97
|
-
readonly limit: "schedulerWorkItems";
|
|
98
|
-
readonly configured: number;
|
|
99
|
-
readonly observed: number;
|
|
100
|
-
readonly virtualTime: string;
|
|
101
|
-
readonly virtualElapsedMs: number;
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
export interface FactoryEmulatorExecutionPausedError extends FactoryEmulatorDataError {
|
|
105
|
-
readonly name: "FactoryEmulatorExecutionPausedError";
|
|
106
|
-
readonly code: "EXECUTION_PAUSED";
|
|
107
|
-
readonly diagnostic: FactoryEmulatorExecutionDiagnostic;
|
|
108
|
-
}
|
|
109
|
-
export declare const FactoryEmulatorExecutionPausedError: {
|
|
110
|
-
new (diagnostic: FactoryEmulatorExecutionDiagnostic): FactoryEmulatorExecutionPausedError;
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
export interface FactoryEmulatorLimits {
|
|
114
|
-
readonly maxCompletedDispatches?: number;
|
|
115
|
-
readonly maxEvents?: number;
|
|
116
|
-
readonly maxVirtualElapsedMs?: number;
|
|
117
|
-
readonly maxZeroDurationBatches?: number;
|
|
118
|
-
readonly maxSynchronousBatches?: number;
|
|
119
|
-
readonly maxSynchronousWorkItems?: number;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export declare const DEFAULT_FACTORY_EMULATOR_LIMITS: Readonly<Required<FactoryEmulatorLimits>>;
|
|
123
|
-
export declare const FACTORY_EMULATOR_LIMIT_HARD_CAPS: Readonly<Required<FactoryEmulatorLimits>>;
|
|
124
|
-
|
|
125
|
-
export interface FactoryEmulatorPendingCommandError extends FactoryEmulatorDataError {
|
|
126
|
-
readonly name: "FactoryEmulatorPendingCommandError";
|
|
127
|
-
readonly code: "PENDING_TRANSACTION";
|
|
128
|
-
readonly attemptedCommand:
|
|
129
|
-
| "start"
|
|
130
|
-
| "submit"
|
|
131
|
-
| "advanceBy"
|
|
132
|
-
| "advanceToNext"
|
|
133
|
-
| "close";
|
|
134
|
-
readonly pendingCommand:
|
|
135
|
-
| "start"
|
|
136
|
-
| "submit"
|
|
137
|
-
| "advanceBy"
|
|
138
|
-
| "advanceToNext"
|
|
139
|
-
| "close";
|
|
140
|
-
}
|
|
141
|
-
export declare const FactoryEmulatorPendingCommandError: {
|
|
142
|
-
new (
|
|
143
|
-
attemptedCommand: FactoryEmulatorPendingCommandError["attemptedCommand"],
|
|
144
|
-
pendingCommand: FactoryEmulatorPendingCommandError["pendingCommand"],
|
|
145
|
-
): FactoryEmulatorPendingCommandError;
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
export type FactoryEmulatorCommandError =
|
|
149
|
-
| FactoryEmulatorConfigurationError
|
|
150
|
-
| FactoryEmulatorDurationError
|
|
151
|
-
| FactoryEmulatorExecutionPausedError
|
|
152
|
-
| FactoryEmulatorLifecycleError
|
|
153
|
-
| FactoryEmulatorPendingCommandError
|
|
154
|
-
| FactoryEmulatorSubmissionError;
|
|
155
|
-
|
|
156
|
-
export interface FactoryEmulatorSessionOptions {
|
|
157
|
-
readonly factory: EmulatorFactoryDefinition;
|
|
158
|
-
readonly scenario: EmulatorScenario;
|
|
159
|
-
readonly sink: FactoryEventSink;
|
|
160
|
-
readonly limits?: FactoryEmulatorLimits;
|
|
161
|
-
/** Host-owned task boundary used after the configured synchronous cadence. */
|
|
162
|
-
readonly yieldControl?: () => void | PromiseLike<void>;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export interface FactoryEmulatorSessionWork {
|
|
166
|
-
readonly submissionId: string;
|
|
167
|
-
readonly requestId: string;
|
|
168
|
-
readonly traceId: string;
|
|
169
|
-
readonly workId: string;
|
|
170
|
-
readonly tokenId: string;
|
|
171
|
-
readonly workType: string;
|
|
172
|
-
readonly phase: "active" | "ready" | "waiting" | "completed";
|
|
173
|
-
readonly input?: Readonly<Record<string, unknown>>;
|
|
174
|
-
readonly output?: Readonly<Record<string, unknown>>;
|
|
175
|
-
readonly rejectionReason?: string;
|
|
176
|
-
readonly dispatch?: {
|
|
177
|
-
readonly dispatchId: string;
|
|
178
|
-
readonly completionId: string;
|
|
179
|
-
readonly lineageTokenId: string;
|
|
180
|
-
readonly outputTokenId: string;
|
|
181
|
-
readonly transitionId: string;
|
|
182
|
-
readonly startedElapsedMs: number;
|
|
183
|
-
readonly dueElapsedMs: number;
|
|
184
|
-
readonly outcome: EmulatorOutcome;
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export interface FactoryEmulatorSessionCounters {
|
|
189
|
-
readonly commands: number;
|
|
190
|
-
readonly events: number;
|
|
191
|
-
readonly requests: number;
|
|
192
|
-
readonly works: number;
|
|
193
|
-
readonly dispatches: number;
|
|
194
|
-
readonly completions: number;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export type FactoryEmulatorSessionState =
|
|
198
|
-
| {
|
|
199
|
-
readonly lifecycle: "pre-start";
|
|
200
|
-
readonly virtualElapsedMs: 0;
|
|
201
|
-
readonly works: readonly [];
|
|
202
|
-
readonly ruleCursors: Readonly<Record<string, number>>;
|
|
203
|
-
readonly counters: FactoryEmulatorSessionCounters;
|
|
204
|
-
}
|
|
205
|
-
| {
|
|
206
|
-
readonly lifecycle: "started";
|
|
207
|
-
readonly sessionId: string;
|
|
208
|
-
readonly virtualTime: string;
|
|
209
|
-
readonly virtualElapsedMs: number;
|
|
210
|
-
readonly works: readonly FactoryEmulatorSessionWork[];
|
|
211
|
-
readonly ruleCursors: Readonly<Record<string, number>>;
|
|
212
|
-
readonly counters: FactoryEmulatorSessionCounters;
|
|
213
|
-
}
|
|
214
|
-
| {
|
|
215
|
-
readonly lifecycle: "closed";
|
|
216
|
-
readonly sessionId: string;
|
|
217
|
-
readonly virtualTime: string;
|
|
218
|
-
readonly virtualElapsedMs: number;
|
|
219
|
-
readonly works: readonly FactoryEmulatorSessionWork[];
|
|
220
|
-
readonly ruleCursors: Readonly<Record<string, number>>;
|
|
221
|
-
readonly counters: FactoryEmulatorSessionCounters;
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
export interface FactoryEmulatorStartReceipt {
|
|
225
|
-
readonly status: "started";
|
|
226
|
-
readonly batches: readonly FactoryEventBatch[];
|
|
227
|
-
readonly state: Extract<FactoryEmulatorSessionState, { lifecycle: "started" }>;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export interface FactoryEmulatorResetReceipt {
|
|
231
|
-
readonly status: "reset";
|
|
232
|
-
readonly state: Extract<FactoryEmulatorSessionState, { lifecycle: "pre-start" }>;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export interface FactoryEmulatorSubmitReceipt {
|
|
236
|
-
readonly status: "submitted";
|
|
237
|
-
readonly batch: FactoryEventBatch;
|
|
238
|
-
readonly state: Extract<FactoryEmulatorSessionState, { lifecycle: "started" }>;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
export interface FactoryEmulatorSessionAdvanceReceipt {
|
|
242
|
-
readonly status: "advanced" | "idle";
|
|
243
|
-
readonly command: "advanceBy" | "advanceToNext";
|
|
244
|
-
readonly fromVirtualTime: string;
|
|
245
|
-
readonly virtualTime: string;
|
|
246
|
-
readonly virtualElapsedMs: number;
|
|
247
|
-
readonly batches: readonly FactoryEventBatch[];
|
|
248
|
-
readonly state: Extract<FactoryEmulatorSessionState, { lifecycle: "started" }>;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
export interface FactoryEmulatorSessionCloseReceipt {
|
|
252
|
-
readonly status: "closed";
|
|
253
|
-
readonly batch: FactoryEventBatch;
|
|
254
|
-
readonly state: Extract<FactoryEmulatorSessionState, { lifecycle: "closed" }>;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export interface FactoryEmulatorBudgetUsage {
|
|
258
|
-
readonly completedDispatches: {
|
|
259
|
-
readonly used: number;
|
|
260
|
-
readonly limit: number;
|
|
261
|
-
};
|
|
262
|
-
readonly events: {
|
|
263
|
-
readonly used: number;
|
|
264
|
-
readonly limit: number;
|
|
265
|
-
};
|
|
266
|
-
readonly virtualElapsedMs: {
|
|
267
|
-
readonly used: number;
|
|
268
|
-
readonly limit: number;
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
export type FactoryEmulatorSessionError =
|
|
273
|
-
| {
|
|
274
|
-
readonly code: "EXECUTION_PAUSED";
|
|
275
|
-
readonly diagnostic: FactoryEmulatorExecutionDiagnostic;
|
|
276
|
-
}
|
|
277
|
-
| {
|
|
278
|
-
readonly code: "SINK_WRITE_REJECTED" | "SINK_CLOSE_REJECTED";
|
|
279
|
-
readonly operation: "write" | "close";
|
|
280
|
-
readonly command: "start" | "submit" | "advanceBy" | "advanceToNext" | "close";
|
|
281
|
-
readonly message: string;
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
export interface FactoryEmulatorPendingTransactionStatus {
|
|
285
|
-
readonly command: "start" | "submit" | "advanceBy" | "advanceToNext" | "close";
|
|
286
|
-
readonly phase: "sink-write" | "sink-close";
|
|
287
|
-
readonly eventCount: number;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export interface FactoryEmulatorSessionStatus {
|
|
291
|
-
readonly phase:
|
|
292
|
-
| "error"
|
|
293
|
-
| "closed"
|
|
294
|
-
| "active"
|
|
295
|
-
| "ready"
|
|
296
|
-
| "waiting"
|
|
297
|
-
| "idle";
|
|
298
|
-
readonly reason: string;
|
|
299
|
-
readonly virtualTime?: string;
|
|
300
|
-
readonly virtualElapsedMs: number;
|
|
301
|
-
readonly budgetUsage: FactoryEmulatorBudgetUsage;
|
|
302
|
-
readonly pendingTransaction?: FactoryEmulatorPendingTransactionStatus;
|
|
303
|
-
readonly error?: FactoryEmulatorSessionError;
|
|
304
|
-
readonly diagnostic?: FactoryEmulatorExecutionDiagnostic;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
export interface FactoryEmulatorSession {
|
|
308
|
-
start(): Promise<FactoryEmulatorStartReceipt>;
|
|
309
|
-
submit(
|
|
310
|
-
submissionOrBatch: EmulatorInitialSubmission | readonly EmulatorInitialSubmission[],
|
|
311
|
-
): Promise<FactoryEmulatorSubmitReceipt>;
|
|
312
|
-
advanceBy(durationMs: number): Promise<FactoryEmulatorSessionAdvanceReceipt>;
|
|
313
|
-
advanceToNext(): Promise<FactoryEmulatorSessionAdvanceReceipt>;
|
|
314
|
-
close(): Promise<FactoryEmulatorSessionCloseReceipt>;
|
|
315
|
-
reset(): FactoryEmulatorResetReceipt;
|
|
316
|
-
pending(): FactoryEventBatch | undefined;
|
|
317
|
-
state(): FactoryEmulatorSessionState;
|
|
318
|
-
status(): FactoryEmulatorSessionStatus;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/** Creates one validated, caller-owned deterministic Factory emulator session. */
|
|
322
|
-
export declare function createFactoryEmulatorSession(
|
|
323
|
-
options: FactoryEmulatorSessionOptions,
|
|
324
|
-
): FactoryEmulatorSession;
|
package/src/sinks.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
const acceptedReceipt = Object.freeze({ status: "accepted" });
|
|
2
|
-
const closedReceipt = Object.freeze({ status: "closed" });
|
|
3
|
-
|
|
4
|
-
export class FactoryEventSinkClosedError extends Error {
|
|
5
|
-
constructor() {
|
|
6
|
-
super("Factory event sink is closed");
|
|
7
|
-
this.name = "FactoryEventSinkClosedError";
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class FactoryEventSinkCapacityError extends Error {
|
|
12
|
-
constructor(limit, attempted) {
|
|
13
|
-
super(
|
|
14
|
-
`Factory event sink capacity ${limit} cannot accept ${attempted} more event${attempted === 1 ? "" : "s"}`,
|
|
15
|
-
);
|
|
16
|
-
this.name = "FactoryEventSinkCapacityError";
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function createMemoryFactoryEventSink({ maxEvents }) {
|
|
21
|
-
assertPositiveInteger(maxEvents, "maxEvents");
|
|
22
|
-
const retainedBatches = [];
|
|
23
|
-
let retainedEventCount = 0;
|
|
24
|
-
let isClosed = false;
|
|
25
|
-
|
|
26
|
-
return Object.freeze({
|
|
27
|
-
maxEvents,
|
|
28
|
-
async write(batch) {
|
|
29
|
-
assertOpen(isClosed);
|
|
30
|
-
const copiedBatch = copyBatch(batch);
|
|
31
|
-
if (copiedBatch.events.length === 0) {
|
|
32
|
-
return acceptedReceipt;
|
|
33
|
-
}
|
|
34
|
-
if (copiedBatch.events.length > maxEvents) {
|
|
35
|
-
throw new FactoryEventSinkCapacityError(maxEvents, copiedBatch.events.length);
|
|
36
|
-
}
|
|
37
|
-
while (
|
|
38
|
-
retainedBatches.length > 0 &&
|
|
39
|
-
retainedEventCount + copiedBatch.events.length > maxEvents
|
|
40
|
-
) {
|
|
41
|
-
retainedEventCount -= retainedBatches.shift().events.length;
|
|
42
|
-
}
|
|
43
|
-
retainedBatches.push(copiedBatch);
|
|
44
|
-
retainedEventCount += copiedBatch.events.length;
|
|
45
|
-
return acceptedReceipt;
|
|
46
|
-
},
|
|
47
|
-
async close() {
|
|
48
|
-
isClosed = true;
|
|
49
|
-
return closedReceipt;
|
|
50
|
-
},
|
|
51
|
-
batches() {
|
|
52
|
-
return copyBatches(retainedBatches);
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function createFactoryRecordingSink({ sessionId, maxEvents }) {
|
|
58
|
-
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
59
|
-
throw new TypeError("sessionId must be a non-empty string");
|
|
60
|
-
}
|
|
61
|
-
assertPositiveInteger(maxEvents, "maxEvents");
|
|
62
|
-
|
|
63
|
-
const retainedEvents = [];
|
|
64
|
-
let isClosed = false;
|
|
65
|
-
|
|
66
|
-
return Object.freeze({
|
|
67
|
-
sessionId,
|
|
68
|
-
maxEvents,
|
|
69
|
-
async write(batch) {
|
|
70
|
-
assertOpen(isClosed);
|
|
71
|
-
const copiedBatch = copyBatch(batch);
|
|
72
|
-
assertRecordingSession(copiedBatch.events, sessionId);
|
|
73
|
-
const attemptedCount = retainedEvents.length + copiedBatch.events.length;
|
|
74
|
-
if (attemptedCount > maxEvents) {
|
|
75
|
-
throw new FactoryEventSinkCapacityError(maxEvents, copiedBatch.events.length);
|
|
76
|
-
}
|
|
77
|
-
retainedEvents.push(...copiedBatch.events);
|
|
78
|
-
return acceptedReceipt;
|
|
79
|
-
},
|
|
80
|
-
async close() {
|
|
81
|
-
isClosed = true;
|
|
82
|
-
return closedReceipt;
|
|
83
|
-
},
|
|
84
|
-
recording() {
|
|
85
|
-
return structuredClone({
|
|
86
|
-
schemaVersion: "agent-factory.recording.v1",
|
|
87
|
-
sessionId,
|
|
88
|
-
events: retainedEvents,
|
|
89
|
-
});
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function assertPositiveInteger(value, name) {
|
|
95
|
-
if (!Number.isSafeInteger(value) || value < 1) {
|
|
96
|
-
throw new RangeError(`${name} must be a positive safe integer`);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function assertOpen(isClosed) {
|
|
101
|
-
if (isClosed) {
|
|
102
|
-
throw new FactoryEventSinkClosedError();
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function assertRecordingSession(events, sessionId) {
|
|
107
|
-
if (events.some((event) => event.context.sessionId !== sessionId)) {
|
|
108
|
-
throw new TypeError("recording sink batch has an event for another session");
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function copyBatch(batch) {
|
|
113
|
-
return structuredClone(batch);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function copyBatches(batches) {
|
|
117
|
-
return structuredClone(batches);
|
|
118
|
-
}
|
package/src/sinks.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import type { FactoryRecording } from "@you-agent-factory/client";
|
|
2
|
-
|
|
3
|
-
import type {
|
|
4
|
-
FactoryEventBatch,
|
|
5
|
-
FactoryEventSink,
|
|
6
|
-
} from "./contracts.js";
|
|
7
|
-
|
|
8
|
-
/** Raised when a caller writes to a helper after it has closed. */
|
|
9
|
-
export declare class FactoryEventSinkClosedError extends Error {}
|
|
10
|
-
|
|
11
|
-
/** Raised when a batch cannot fit without exceeding a helper's declared bound. */
|
|
12
|
-
export declare class FactoryEventSinkCapacityError extends Error {}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* The maximum number of events a memory sink retains. Batches remain atomic:
|
|
16
|
-
* an oversized batch is rejected and older complete batches are discarded
|
|
17
|
-
* before a later accepted batch is retained.
|
|
18
|
-
*/
|
|
19
|
-
export interface MemoryFactoryEventSinkOptions {
|
|
20
|
-
readonly maxEvents: number;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* A bounded in-memory sink. `batches` returns a detached snapshot, not the
|
|
25
|
-
* values retained by the sink.
|
|
26
|
-
*/
|
|
27
|
-
export interface MemoryFactoryEventSink extends FactoryEventSink {
|
|
28
|
-
readonly maxEvents: number;
|
|
29
|
-
batches(): readonly FactoryEventBatch[];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** Creates a bounded, detached in-memory event sink. */
|
|
33
|
-
export declare function createMemoryFactoryEventSink(
|
|
34
|
-
options: MemoryFactoryEventSinkOptions,
|
|
35
|
-
): MemoryFactoryEventSink;
|
|
36
|
-
|
|
37
|
-
/** The fixed metadata and capacity of one finite Factory recording. */
|
|
38
|
-
export interface FactoryRecordingSinkOptions {
|
|
39
|
-
readonly sessionId: string;
|
|
40
|
-
readonly maxEvents: number;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* A bounded sink that produces one finite recording. `recording` returns a
|
|
45
|
-
* detached snapshot and remains readable after close.
|
|
46
|
-
*/
|
|
47
|
-
export interface FactoryRecordingSink extends FactoryEventSink {
|
|
48
|
-
readonly sessionId: string;
|
|
49
|
-
readonly maxEvents: number;
|
|
50
|
-
recording(): FactoryRecording;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** Creates a bounded sink for one caller-owned Factory recording. */
|
|
54
|
-
export declare function createFactoryRecordingSink(
|
|
55
|
-
options: FactoryRecordingSinkOptions,
|
|
56
|
-
): FactoryRecordingSink;
|