ai-experiments 2.3.0 → 2.4.0

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.
@@ -0,0 +1,522 @@
1
+ /**
2
+ * ClickHouse storage backend for AI experiments.
3
+ *
4
+ * Migrated (per [ADR-0003](../../../docs/adr/0003-storage-strategy-pg-clickhouse-default.md))
5
+ * from the standalone embedded `chdb` adapter to the canonical
6
+ * `ClickHouseProvider` from `ai-database`. Experiment runs are recorded as
7
+ * SVO Actions on the canonical `actions` table:
8
+ *
9
+ * - `verb` — event type (e.g. `variant.complete`)
10
+ * - `subject` — `experimentId`
11
+ * - `object` — `variantId`
12
+ * - `roles` — `{ runId }` (other named roles can be carried here)
13
+ * - `data` — JSON payload (`experimentName`, `variantName`, `dimensions`,
14
+ * `runId`, `success`, `durationMs`, `result`, `metricName`,
15
+ * `metricValue`, `errorMessage`, `errorStack`, `metadata`)
16
+ * - `status` — `'completed'` for successful runs, `'failed'` otherwise
17
+ *
18
+ * Writes go through {@link ClickHouseProvider.recordAction} (and
19
+ * {@link ClickHouseProvider.commitBatch} when bulk-storing). Aggregations
20
+ * use {@link ClickHouseProvider.analyticsQuery} against the `actions` table
21
+ * with `JSONExtract*` against the `data` column. This is the **option (c)
22
+ * hybrid** approach from the migration plan: SVO surface for writes, raw
23
+ * analytical SQL for the experiment-specific aggregations the SVO surface
24
+ * doesn't expose directly (cartesian grids, time-series rollups,
25
+ * best-variant selection by metric).
26
+ *
27
+ * Deployment shift: the previous `chdb` adapter used embedded ClickHouse
28
+ * (file-system path). This adapter is HTTP-based — callers wire up a
29
+ * ClickHouse server (self-hosted or ClickHouse Cloud) via
30
+ * {@link createClickHouseHttpFetcher}. Tests use a fake fetcher.
31
+ *
32
+ * @packageDocumentation
33
+ */
34
+ import { createClickHouseProvider, bootstrapClickHouseSchema, } from 'ai-database';
35
+ const DEFAULT_NAMESPACE = 'experiments';
36
+ /**
37
+ * Generate a stable event id. Timestamp + monotonic counter inside the
38
+ * process — ClickHouse de-dupes on `actions.id` only via explicit DELETE,
39
+ * so collisions across processes are tolerated (each becomes a separate
40
+ * row).
41
+ */
42
+ function makeEventIdFactory() {
43
+ let counter = 0;
44
+ return () => `evt-${Date.now()}-${++counter}`;
45
+ }
46
+ /**
47
+ * Map a {@link TrackingEvent} to the SVO Action shape.
48
+ *
49
+ * `verb` carries the event type (`variant.complete`, etc.).
50
+ * `subject` = `experimentId`, `object` = `variantId`. Everything else
51
+ * lands in `data` so analytical queries can `JSONExtract*` whatever they
52
+ * need without changing the schema.
53
+ */
54
+ function eventToActionInput(event, eventId) {
55
+ const data = event.data;
56
+ const experimentId = String(data['experimentId'] ?? '');
57
+ const variantId = String(data['variantId'] ?? '');
58
+ const runId = String(data['runId'] ?? '');
59
+ const success = data['success'] !== false;
60
+ const status = event.type === 'variant.error' || !success ? 'failed' : 'completed';
61
+ // Capture every payload field — aggregation SQL uses JSONExtract* against
62
+ // the `data` JSON blob.
63
+ const errorMessage = data['error'] instanceof Error
64
+ ? data['error'].message
65
+ : data['errorMessage'] !== undefined
66
+ ? String(data['errorMessage'])
67
+ : '';
68
+ const errorStack = data['error'] instanceof Error ? data['error'].stack ?? '' : '';
69
+ const durationMs = Number(data['duration'] ?? data['durationMs'] ?? 0);
70
+ const payload = {
71
+ eventId,
72
+ eventType: event.type,
73
+ timestamp: event.timestamp.toISOString(),
74
+ experimentId,
75
+ experimentName: String(data['experimentName'] ?? ''),
76
+ variantId,
77
+ variantName: String(data['variantName'] ?? ''),
78
+ runId,
79
+ success: success ? 1 : 0,
80
+ durationMs,
81
+ dimensions: data['dimensions'] ?? data['config'] ?? {},
82
+ result: data['result'] ?? {},
83
+ metricName: String(data['metricName'] ?? ''),
84
+ metricValue: Number(data['metricValue'] ?? 0),
85
+ errorMessage,
86
+ errorStack,
87
+ metadata: data['metadata'] ?? {},
88
+ };
89
+ return {
90
+ id: eventId,
91
+ verb: event.type,
92
+ subject: experimentId,
93
+ object: variantId,
94
+ roles: runId ? { runId } : {},
95
+ data: payload,
96
+ status,
97
+ };
98
+ }
99
+ /**
100
+ * ClickHouse-backed experiment storage built on the canonical
101
+ * {@link ClickHouseProvider} adapter. Implements
102
+ * {@link TrackingBackend}.
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * import { configureTracking } from 'ai-experiments'
107
+ * import { createClickHouseExperimentStorage } from 'ai-experiments/storage'
108
+ * import { createClickHouseHttpFetcher } from 'ai-database'
109
+ *
110
+ * const fetcher = createClickHouseHttpFetcher({
111
+ * url: process.env.CLICKHOUSE_URL!,
112
+ * username: process.env.CLICKHOUSE_USER,
113
+ * password: process.env.CLICKHOUSE_PASSWORD,
114
+ * database: 'aidb',
115
+ * })
116
+ * const storage = createClickHouseExperimentStorage({ fetcher })
117
+ *
118
+ * configureTracking({ backend: storage })
119
+ *
120
+ * // Later: analyse results
121
+ * const best = await storage.getBestVariant('my-experiment')
122
+ * ```
123
+ */
124
+ export class ClickHouseExperimentStorage {
125
+ provider;
126
+ fetcher;
127
+ database;
128
+ namespace;
129
+ autoBootstrap;
130
+ bootstrapped = false;
131
+ nextEventId = makeEventIdFactory();
132
+ constructor(options) {
133
+ this.fetcher = options.fetcher;
134
+ this.database = options.database ?? 'aidb';
135
+ this.namespace = options.namespace ?? DEFAULT_NAMESPACE;
136
+ this.autoBootstrap = options.autoBootstrap ?? false;
137
+ this.provider = createClickHouseProvider({
138
+ fetcher: options.fetcher,
139
+ database: this.database,
140
+ namespace: this.namespace,
141
+ });
142
+ }
143
+ /** Underlying canonical CH provider (escape hatch for advanced callers). */
144
+ getProvider() {
145
+ return this.provider;
146
+ }
147
+ async ensureBootstrap() {
148
+ if (this.bootstrapped)
149
+ return;
150
+ if (this.autoBootstrap) {
151
+ await bootstrapClickHouseSchema(this.fetcher, { database: this.database });
152
+ }
153
+ this.bootstrapped = true;
154
+ }
155
+ // ───────────────────────────────────────────────────────────────────────────
156
+ // TrackingBackend implementation
157
+ // ───────────────────────────────────────────────────────────────────────────
158
+ async track(event) {
159
+ await this.ensureBootstrap();
160
+ const eventId = this.nextEventId();
161
+ const action = eventToActionInput(event, eventId);
162
+ await this.provider.recordAction({
163
+ verb: action.verb,
164
+ subject: action.subject,
165
+ object: action.object,
166
+ roles: action.roles,
167
+ data: action.data,
168
+ status: action.status,
169
+ });
170
+ }
171
+ async flush() {
172
+ // Writes go straight through HTTP — nothing to flush.
173
+ }
174
+ // ───────────────────────────────────────────────────────────────────────────
175
+ // Direct experiment-result API
176
+ // ───────────────────────────────────────────────────────────────────────────
177
+ async storeResult(result) {
178
+ await this.track({
179
+ type: 'variant.complete',
180
+ timestamp: result.completedAt,
181
+ data: {
182
+ experimentId: result.experimentId,
183
+ variantId: result.variantId,
184
+ variantName: result.variantName,
185
+ runId: result.runId,
186
+ success: result.success,
187
+ duration: result.duration,
188
+ result: result.result,
189
+ metricValue: result.metricValue,
190
+ error: result.error,
191
+ metadata: result.metadata,
192
+ },
193
+ });
194
+ }
195
+ /**
196
+ * Bulk-store results via {@link ClickHouseProvider.commitBatch}. One
197
+ * HTTP POST per call carries the entire batch as `JSONEachRow`.
198
+ */
199
+ async storeResults(results) {
200
+ if (results.length === 0)
201
+ return;
202
+ await this.ensureBootstrap();
203
+ const actions = results.map((r) => {
204
+ const action = eventToActionInput({
205
+ type: 'variant.complete',
206
+ timestamp: r.completedAt,
207
+ data: {
208
+ experimentId: r.experimentId,
209
+ variantId: r.variantId,
210
+ variantName: r.variantName,
211
+ runId: r.runId,
212
+ success: r.success,
213
+ duration: r.duration,
214
+ result: r.result,
215
+ metricValue: r.metricValue,
216
+ error: r.error,
217
+ metadata: r.metadata,
218
+ },
219
+ }, this.nextEventId());
220
+ return action;
221
+ });
222
+ await this.provider.commitBatch({ actions });
223
+ }
224
+ // ───────────────────────────────────────────────────────────────────────────
225
+ // Analytics queries (raw SQL via canonical adapter's analyticsQuery)
226
+ // ───────────────────────────────────────────────────────────────────────────
227
+ /** Quote a SQL string literal — same shape as the canonical adapter. */
228
+ quote(value) {
229
+ return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
230
+ }
231
+ /**
232
+ * Get all experiments seen in the actions table (variant.complete events).
233
+ */
234
+ async getExperiments() {
235
+ await this.ensureBootstrap();
236
+ const ns = this.quote(this.namespace);
237
+ const sql = `
238
+ SELECT
239
+ subject AS experimentId,
240
+ any(JSONExtractString(data, 'experimentName')) AS experimentName,
241
+ uniq(object) AS variantCount,
242
+ count() AS runCount,
243
+ toString(min(created_at)) AS firstRun,
244
+ toString(max(created_at)) AS lastRun
245
+ FROM ${this.database}.actions
246
+ WHERE ns = ${ns} AND verb = 'variant.complete' AND subject != ''
247
+ GROUP BY subject
248
+ ORDER BY lastRun DESC
249
+ `;
250
+ const rows = await this.provider.analyticsQuery(sql);
251
+ return rows.map((row) => ({
252
+ experimentId: String(row['experimentId'] ?? ''),
253
+ experimentName: String(row['experimentName'] ?? ''),
254
+ variantCount: Number(row['variantCount'] ?? 0),
255
+ runCount: Number(row['runCount'] ?? 0),
256
+ firstRun: String(row['firstRun'] ?? ''),
257
+ lastRun: String(row['lastRun'] ?? ''),
258
+ }));
259
+ }
260
+ async getVariantStats(experimentId) {
261
+ await this.ensureBootstrap();
262
+ const ns = this.quote(this.namespace);
263
+ const exp = this.quote(experimentId);
264
+ const sql = `
265
+ SELECT
266
+ object AS variantId,
267
+ any(JSONExtractString(data, 'variantName')) AS variantName,
268
+ count() AS runCount,
269
+ countIf(JSONExtractInt(data, 'success') = 1) AS successCount,
270
+ countIf(JSONExtractInt(data, 'success') = 1) / count() AS successRate,
271
+ avg(JSONExtractFloat(data, 'durationMs')) AS avgDuration,
272
+ avg(JSONExtractFloat(data, 'metricValue')) AS avgMetric,
273
+ min(JSONExtractFloat(data, 'metricValue')) AS minMetric,
274
+ max(JSONExtractFloat(data, 'metricValue')) AS maxMetric
275
+ FROM ${this.database}.actions
276
+ WHERE ns = ${ns} AND verb = 'variant.complete' AND subject = ${exp}
277
+ GROUP BY object
278
+ ORDER BY avgMetric DESC
279
+ `;
280
+ const rows = await this.provider.analyticsQuery(sql);
281
+ return rows.map((row) => ({
282
+ variantId: String(row['variantId'] ?? ''),
283
+ variantName: String(row['variantName'] ?? ''),
284
+ runCount: Number(row['runCount'] ?? 0),
285
+ successCount: Number(row['successCount'] ?? 0),
286
+ successRate: Number(row['successRate'] ?? 0),
287
+ avgDuration: Number(row['avgDuration'] ?? 0),
288
+ avgMetric: Number(row['avgMetric'] ?? 0),
289
+ minMetric: Number(row['minMetric'] ?? 0),
290
+ maxMetric: Number(row['maxMetric'] ?? 0),
291
+ }));
292
+ }
293
+ async getBestVariant(experimentId, options = {}) {
294
+ await this.ensureBootstrap();
295
+ const { metric = 'avgMetric', minimumRuns = 1 } = options;
296
+ const ns = this.quote(this.namespace);
297
+ const exp = this.quote(experimentId);
298
+ const orderBy = metric === 'avgDuration' ? 'ASC' : 'DESC';
299
+ const metricExpr = metric === 'successRate'
300
+ ? "countIf(JSONExtractInt(data, 'success') = 1) / count()"
301
+ : metric === 'avgDuration'
302
+ ? "avg(JSONExtractFloat(data, 'durationMs'))"
303
+ : "avg(JSONExtractFloat(data, 'metricValue'))";
304
+ const sql = `
305
+ SELECT
306
+ object AS variantId,
307
+ any(JSONExtractString(data, 'variantName')) AS variantName,
308
+ ${metricExpr} AS metricValue,
309
+ count() AS runCount
310
+ FROM ${this.database}.actions
311
+ WHERE ns = ${ns} AND verb = 'variant.complete' AND subject = ${exp}
312
+ GROUP BY object
313
+ HAVING runCount >= ${Number(minimumRuns)}
314
+ ORDER BY metricValue ${orderBy}
315
+ LIMIT 1
316
+ `;
317
+ const rows = await this.provider.analyticsQuery(sql);
318
+ if (rows.length === 0)
319
+ return null;
320
+ const row = rows[0];
321
+ return {
322
+ variantId: String(row['variantId'] ?? ''),
323
+ variantName: String(row['variantName'] ?? ''),
324
+ metricValue: Number(row['metricValue'] ?? 0),
325
+ runCount: Number(row['runCount'] ?? 0),
326
+ };
327
+ }
328
+ async getCartesianAnalysis(experimentId, dimension) {
329
+ await this.ensureBootstrap();
330
+ const ns = this.quote(this.namespace);
331
+ const exp = this.quote(experimentId);
332
+ const dimQuoted = this.quote(dimension);
333
+ const sql = `
334
+ SELECT
335
+ JSONExtractString(JSONExtractRaw(data, 'dimensions'), ${dimQuoted}) AS dimensionValue,
336
+ count() AS runCount,
337
+ avg(JSONExtractFloat(data, 'metricValue')) AS avgMetric,
338
+ countIf(JSONExtractInt(data, 'success') = 1) / count() AS successRate
339
+ FROM ${this.database}.actions
340
+ WHERE ns = ${ns} AND verb = 'variant.complete' AND subject = ${exp}
341
+ GROUP BY dimensionValue
342
+ HAVING dimensionValue != ''
343
+ ORDER BY avgMetric DESC
344
+ `;
345
+ const rows = await this.provider.analyticsQuery(sql);
346
+ return rows.map((row) => ({
347
+ dimensionValue: String(row['dimensionValue'] ?? ''),
348
+ runCount: Number(row['runCount'] ?? 0),
349
+ avgMetric: Number(row['avgMetric'] ?? 0),
350
+ successRate: Number(row['successRate'] ?? 0),
351
+ }));
352
+ }
353
+ async getCartesianGrid(experimentId, dimensions) {
354
+ await this.ensureBootstrap();
355
+ const ns = this.quote(this.namespace);
356
+ const exp = this.quote(experimentId);
357
+ const dimExtracts = dimensions
358
+ .map((d) => `JSONExtractString(JSONExtractRaw(data, 'dimensions'), ${this.quote(d)}) AS dim_${d}`)
359
+ .join(', ');
360
+ const dimGroupBy = dimensions.map((d) => `dim_${d}`).join(', ');
361
+ const sql = `
362
+ SELECT
363
+ ${dimExtracts},
364
+ count() AS runCount,
365
+ avg(JSONExtractFloat(data, 'metricValue')) AS avgMetric,
366
+ countIf(JSONExtractInt(data, 'success') = 1) / count() AS successRate
367
+ FROM ${this.database}.actions
368
+ WHERE ns = ${ns} AND verb = 'variant.complete' AND subject = ${exp}
369
+ GROUP BY ${dimGroupBy}
370
+ ORDER BY avgMetric DESC
371
+ `;
372
+ const rows = await this.provider.analyticsQuery(sql);
373
+ return rows.map((row) => {
374
+ const dims = {};
375
+ for (const d of dimensions) {
376
+ dims[d] = String(row[`dim_${d}`] ?? '');
377
+ }
378
+ return {
379
+ dimensions: dims,
380
+ runCount: Number(row['runCount'] ?? 0),
381
+ avgMetric: Number(row['avgMetric'] ?? 0),
382
+ successRate: Number(row['successRate'] ?? 0),
383
+ };
384
+ });
385
+ }
386
+ async getTimeSeries(experimentId, options = {}) {
387
+ await this.ensureBootstrap();
388
+ const { interval = 'day', variantId } = options;
389
+ const ns = this.quote(this.namespace);
390
+ const exp = this.quote(experimentId);
391
+ const dateFunc = interval === 'hour'
392
+ ? 'toStartOfHour(created_at)'
393
+ : interval === 'week'
394
+ ? 'toStartOfWeek(created_at)'
395
+ : 'toStartOfDay(created_at)';
396
+ const variantFilter = variantId ? `AND object = ${this.quote(variantId)}` : '';
397
+ const sql = `
398
+ SELECT
399
+ toString(${dateFunc}) AS period,
400
+ count() AS runCount,
401
+ avg(JSONExtractFloat(data, 'metricValue')) AS avgMetric,
402
+ countIf(JSONExtractInt(data, 'success') = 1) / count() AS successRate
403
+ FROM ${this.database}.actions
404
+ WHERE ns = ${ns} AND verb = 'variant.complete' AND subject = ${exp}
405
+ ${variantFilter}
406
+ GROUP BY period
407
+ ORDER BY period ASC
408
+ `;
409
+ const rows = await this.provider.analyticsQuery(sql);
410
+ return rows.map((row) => ({
411
+ period: String(row['period'] ?? ''),
412
+ runCount: Number(row['runCount'] ?? 0),
413
+ avgMetric: Number(row['avgMetric'] ?? 0),
414
+ successRate: Number(row['successRate'] ?? 0),
415
+ }));
416
+ }
417
+ async getEvents(experimentId, options = {}) {
418
+ await this.ensureBootstrap();
419
+ const { eventType, variantId, limit = 100 } = options;
420
+ const ns = this.quote(this.namespace);
421
+ const exp = this.quote(experimentId);
422
+ const filters = [`ns = ${ns}`, `subject = ${exp}`];
423
+ if (eventType)
424
+ filters.push(`verb = ${this.quote(eventType)}`);
425
+ if (variantId)
426
+ filters.push(`object = ${this.quote(variantId)}`);
427
+ const sql = `
428
+ SELECT
429
+ verb AS eventType,
430
+ toString(created_at) AS createdAt,
431
+ data
432
+ FROM ${this.database}.actions
433
+ WHERE ${filters.join(' AND ')}
434
+ ORDER BY created_at DESC
435
+ LIMIT ${Number(limit)}
436
+ `;
437
+ const rows = await this.provider.analyticsQuery(sql);
438
+ return rows.map((row) => {
439
+ const dataStr = row['data'];
440
+ let payload = {};
441
+ if (typeof dataStr === 'string' && dataStr.length > 0) {
442
+ try {
443
+ payload = JSON.parse(dataStr);
444
+ }
445
+ catch {
446
+ payload = {};
447
+ }
448
+ }
449
+ else if (dataStr && typeof dataStr === 'object') {
450
+ payload = dataStr;
451
+ }
452
+ const createdAt = String(row['createdAt'] ?? '');
453
+ const ts = createdAt ? new Date(createdAt) : new Date();
454
+ return {
455
+ type: String(row['eventType'] ?? ''),
456
+ timestamp: Number.isNaN(ts.getTime()) ? new Date() : ts,
457
+ data: payload,
458
+ };
459
+ });
460
+ }
461
+ /**
462
+ * Raw analytical SQL pass-through. Routes to
463
+ * {@link ClickHouseProvider.analyticsQuery}.
464
+ */
465
+ async query(sql) {
466
+ return this.provider.analyticsQuery(sql);
467
+ }
468
+ /** No-op (kept for backwards compat with the chdb-era API). */
469
+ close() {
470
+ // HTTP fetcher has nothing to release.
471
+ }
472
+ }
473
+ /**
474
+ * Bootstrap the canonical CH schema (`things`, `actions`, `verbs`).
475
+ * Convenience wrapper around the canonical
476
+ * {@link bootstrapClickHouseSchema}.
477
+ */
478
+ export async function bootstrapExperimentsSchema(fetcher, options = {}) {
479
+ await bootstrapClickHouseSchema(fetcher, options.database !== undefined ? { database: options.database } : {});
480
+ }
481
+ /**
482
+ * Create a ClickHouse-backed experiment storage backend.
483
+ *
484
+ * @example
485
+ * ```ts
486
+ * import { configureTracking } from 'ai-experiments'
487
+ * import { createClickHouseExperimentStorage } from 'ai-experiments/storage'
488
+ * import { createClickHouseHttpFetcher } from 'ai-database'
489
+ *
490
+ * const fetcher = createClickHouseHttpFetcher({
491
+ * url: process.env.CLICKHOUSE_URL!,
492
+ * username: process.env.CLICKHOUSE_USER,
493
+ * password: process.env.CLICKHOUSE_PASSWORD,
494
+ * database: 'aidb',
495
+ * })
496
+ * const storage = createClickHouseExperimentStorage({ fetcher })
497
+ *
498
+ * configureTracking({ backend: storage })
499
+ *
500
+ * const best = await storage.getBestVariant('my-experiment')
501
+ * ```
502
+ */
503
+ export function createClickHouseExperimentStorage(options) {
504
+ return new ClickHouseExperimentStorage(options);
505
+ }
506
+ // =============================================================================
507
+ // Backwards-compat aliases (chdb-era names)
508
+ // =============================================================================
509
+ /**
510
+ * @deprecated Renamed to {@link ClickHouseExperimentStorage}. The class
511
+ * now wraps the canonical `ClickHouseProvider` from `ai-database` instead
512
+ * of embedded chdb. The old `dataPath` constructor option is ignored —
513
+ * supply a `fetcher` instead.
514
+ */
515
+ export const ChdbStorage = ClickHouseExperimentStorage;
516
+ /**
517
+ * @deprecated Renamed to {@link createClickHouseExperimentStorage}.
518
+ */
519
+ export function createChdbBackend(options) {
520
+ return createClickHouseExperimentStorage(options);
521
+ }
522
+ //# sourceMappingURL=clickhouse-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickhouse-storage.js","sourceRoot":"","sources":["../src/clickhouse-storage.ts"],"names":[],"mappings":"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"}