ai-experiments 2.1.3 → 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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +17 -0
- package/README.md +13 -1
- package/dist/clickhouse-storage.d.ts +227 -0
- package/dist/clickhouse-storage.d.ts.map +1 -0
- package/dist/clickhouse-storage.js +522 -0
- package/dist/clickhouse-storage.js.map +1 -0
- package/dist/decide.d.ts.map +1 -1
- package/dist/decide.js +6 -2
- package/dist/decide.js.map +1 -1
- package/dist/experiment.js +9 -9
- package/dist/experiment.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/tracking.js +3 -3
- package/dist/tracking.js.map +1 -1
- package/package.json +16 -16
- package/src/clickhouse-storage.ts +698 -0
- package/src/decide.ts +8 -10
- package/src/experiment.ts +12 -12
- package/src/index.ts +13 -3
- package/src/tracking.ts +3 -3
- package/test/cartesian.test.ts +287 -0
- package/test/clickhouse-storage.test.ts +470 -0
- package/test/decide.test.ts +414 -0
- package/test/experiment.test.ts +473 -0
- package/test/tracking.test.ts +347 -0
- package/vitest.config.ts +34 -0
- package/LICENSE +0 -21
- package/dist/chdb-storage.d.ts +0 -135
- package/dist/chdb-storage.d.ts.map +0 -1
- package/dist/chdb-storage.js +0 -468
- package/dist/chdb-storage.js.map +0 -1
- package/src/cartesian.js +0 -215
- package/src/chdb-storage.js +0 -464
- package/src/chdb-storage.ts +0 -567
- package/src/decide.js +0 -328
- package/src/experiment.js +0 -291
- package/src/index.js +0 -20
- package/src/tracking.js +0 -309
- package/src/types.js +0 -4
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# ai-experiments
|
|
2
2
|
|
|
3
|
+
## 2.4.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [4d58f5f]
|
|
8
|
+
- ai-functions@2.4.0
|
|
9
|
+
- ai-database@2.4.0
|
|
10
|
+
|
|
11
|
+
## 2.3.0
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [9e2779a]
|
|
16
|
+
- Updated dependencies [b7c7c57]
|
|
17
|
+
- ai-functions@2.3.0
|
|
18
|
+
- ai-database@2.3.0
|
|
19
|
+
|
|
3
20
|
## 2.1.3
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
# ai-experiments
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Runtime A/B testing for AI variants in production. Traffic splitting, multi-armed bandits, parameter sweeps, and ClickHouse-backed outcome tracking via the canonical `ai-database` adapter.
|
|
6
|
+
|
|
7
|
+
## Lifecycle
|
|
8
|
+
|
|
9
|
+
**Runtime (production).** `ai-experiments` is for splitting live traffic across model/prompt/parameter variants and measuring outcomes against real users. Reach for it when you need to learn which variant wins under production conditions — not in a test suite.
|
|
10
|
+
|
|
11
|
+
## Not for
|
|
12
|
+
|
|
13
|
+
- **Unit testing.** If you want to assert that a specific input produces a specific output during development or CI, use [`ai-tests`](../ai-tests) plus `vitest`. `ai-experiments` exists to *measure* outcomes across users, not to *assert* them against fixtures.
|
|
14
|
+
- **Sandboxing untrusted code.** That's [`ai-evaluate`](../ai-evaluate)'s job.
|
|
15
|
+
- **Offline-only experiments.** While `Experiment()` works offline for parameter sweeps, the package's value comes from production tracking — if you're never deploying the variants, a plain `for` loop is simpler.
|
|
4
16
|
|
|
5
17
|
## Overview
|
|
6
18
|
|
|
@@ -0,0 +1,227 @@
|
|
|
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 { type ClickHouseHttpFetcher, type ClickHouseProvider } from 'ai-database';
|
|
35
|
+
import type { TrackingBackend, TrackingEvent, ExperimentResult } from './types.js';
|
|
36
|
+
/** Options for {@link ClickHouseExperimentStorage}. */
|
|
37
|
+
export interface ClickHouseExperimentStorageOptions {
|
|
38
|
+
/** HTTP fetcher (typically constructed via `createClickHouseHttpFetcher`). */
|
|
39
|
+
fetcher: ClickHouseHttpFetcher;
|
|
40
|
+
/**
|
|
41
|
+
* ClickHouse database. Must already exist (or call
|
|
42
|
+
* {@link bootstrapExperimentsSchema}).
|
|
43
|
+
*
|
|
44
|
+
* @default 'aidb'
|
|
45
|
+
*/
|
|
46
|
+
database?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Namespace partition for experiment events.
|
|
49
|
+
*
|
|
50
|
+
* @default 'experiments'
|
|
51
|
+
*/
|
|
52
|
+
namespace?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Whether to bootstrap the canonical schema (`things`/`actions`/`verbs`)
|
|
55
|
+
* before the first write.
|
|
56
|
+
*
|
|
57
|
+
* @default false
|
|
58
|
+
*/
|
|
59
|
+
autoBootstrap?: boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Backwards-compat alias for the prior `ChdbStorageOptions`. The
|
|
63
|
+
* `dataPath` and `autoInit` fields are retained as no-ops to ease the
|
|
64
|
+
* upgrade — they are ignored in favor of HTTP fetcher options.
|
|
65
|
+
*/
|
|
66
|
+
export interface ChdbStorageOptions extends Partial<ClickHouseExperimentStorageOptions> {
|
|
67
|
+
/** @deprecated Embedded chdb is no longer used; supply `fetcher`. */
|
|
68
|
+
dataPath?: string;
|
|
69
|
+
/** @deprecated Replaced by `autoBootstrap`. */
|
|
70
|
+
autoInit?: boolean;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* ClickHouse-backed experiment storage built on the canonical
|
|
74
|
+
* {@link ClickHouseProvider} adapter. Implements
|
|
75
|
+
* {@link TrackingBackend}.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* import { configureTracking } from 'ai-experiments'
|
|
80
|
+
* import { createClickHouseExperimentStorage } from 'ai-experiments/storage'
|
|
81
|
+
* import { createClickHouseHttpFetcher } from 'ai-database'
|
|
82
|
+
*
|
|
83
|
+
* const fetcher = createClickHouseHttpFetcher({
|
|
84
|
+
* url: process.env.CLICKHOUSE_URL!,
|
|
85
|
+
* username: process.env.CLICKHOUSE_USER,
|
|
86
|
+
* password: process.env.CLICKHOUSE_PASSWORD,
|
|
87
|
+
* database: 'aidb',
|
|
88
|
+
* })
|
|
89
|
+
* const storage = createClickHouseExperimentStorage({ fetcher })
|
|
90
|
+
*
|
|
91
|
+
* configureTracking({ backend: storage })
|
|
92
|
+
*
|
|
93
|
+
* // Later: analyse results
|
|
94
|
+
* const best = await storage.getBestVariant('my-experiment')
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export declare class ClickHouseExperimentStorage implements TrackingBackend {
|
|
98
|
+
private readonly provider;
|
|
99
|
+
private readonly fetcher;
|
|
100
|
+
private readonly database;
|
|
101
|
+
private readonly namespace;
|
|
102
|
+
private readonly autoBootstrap;
|
|
103
|
+
private bootstrapped;
|
|
104
|
+
private readonly nextEventId;
|
|
105
|
+
constructor(options: ClickHouseExperimentStorageOptions);
|
|
106
|
+
/** Underlying canonical CH provider (escape hatch for advanced callers). */
|
|
107
|
+
getProvider(): ClickHouseProvider;
|
|
108
|
+
private ensureBootstrap;
|
|
109
|
+
track(event: TrackingEvent): Promise<void>;
|
|
110
|
+
flush(): Promise<void>;
|
|
111
|
+
storeResult(result: ExperimentResult): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Bulk-store results via {@link ClickHouseProvider.commitBatch}. One
|
|
114
|
+
* HTTP POST per call carries the entire batch as `JSONEachRow`.
|
|
115
|
+
*/
|
|
116
|
+
storeResults(results: ExperimentResult[]): Promise<void>;
|
|
117
|
+
/** Quote a SQL string literal — same shape as the canonical adapter. */
|
|
118
|
+
private quote;
|
|
119
|
+
/**
|
|
120
|
+
* Get all experiments seen in the actions table (variant.complete events).
|
|
121
|
+
*/
|
|
122
|
+
getExperiments(): Promise<Array<{
|
|
123
|
+
experimentId: string;
|
|
124
|
+
experimentName: string;
|
|
125
|
+
variantCount: number;
|
|
126
|
+
runCount: number;
|
|
127
|
+
firstRun: string;
|
|
128
|
+
lastRun: string;
|
|
129
|
+
}>>;
|
|
130
|
+
getVariantStats(experimentId: string): Promise<Array<{
|
|
131
|
+
variantId: string;
|
|
132
|
+
variantName: string;
|
|
133
|
+
runCount: number;
|
|
134
|
+
successCount: number;
|
|
135
|
+
successRate: number;
|
|
136
|
+
avgDuration: number;
|
|
137
|
+
avgMetric: number;
|
|
138
|
+
minMetric: number;
|
|
139
|
+
maxMetric: number;
|
|
140
|
+
}>>;
|
|
141
|
+
getBestVariant(experimentId: string, options?: {
|
|
142
|
+
metric?: 'avgMetric' | 'successRate' | 'avgDuration';
|
|
143
|
+
minimumRuns?: number;
|
|
144
|
+
}): Promise<{
|
|
145
|
+
variantId: string;
|
|
146
|
+
variantName: string;
|
|
147
|
+
metricValue: number;
|
|
148
|
+
runCount: number;
|
|
149
|
+
} | null>;
|
|
150
|
+
getCartesianAnalysis(experimentId: string, dimension: string): Promise<Array<{
|
|
151
|
+
dimensionValue: string;
|
|
152
|
+
runCount: number;
|
|
153
|
+
avgMetric: number;
|
|
154
|
+
successRate: number;
|
|
155
|
+
}>>;
|
|
156
|
+
getCartesianGrid(experimentId: string, dimensions: string[]): Promise<Array<{
|
|
157
|
+
dimensions: Record<string, string>;
|
|
158
|
+
runCount: number;
|
|
159
|
+
avgMetric: number;
|
|
160
|
+
successRate: number;
|
|
161
|
+
}>>;
|
|
162
|
+
getTimeSeries(experimentId: string, options?: {
|
|
163
|
+
interval?: 'hour' | 'day' | 'week';
|
|
164
|
+
variantId?: string;
|
|
165
|
+
}): Promise<Array<{
|
|
166
|
+
period: string;
|
|
167
|
+
runCount: number;
|
|
168
|
+
avgMetric: number;
|
|
169
|
+
successRate: number;
|
|
170
|
+
}>>;
|
|
171
|
+
getEvents(experimentId: string, options?: {
|
|
172
|
+
eventType?: string;
|
|
173
|
+
variantId?: string;
|
|
174
|
+
limit?: number;
|
|
175
|
+
}): Promise<TrackingEvent[]>;
|
|
176
|
+
/**
|
|
177
|
+
* Raw analytical SQL pass-through. Routes to
|
|
178
|
+
* {@link ClickHouseProvider.analyticsQuery}.
|
|
179
|
+
*/
|
|
180
|
+
query(sql: string): Promise<Array<Record<string, unknown>>>;
|
|
181
|
+
/** No-op (kept for backwards compat with the chdb-era API). */
|
|
182
|
+
close(): void;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Bootstrap the canonical CH schema (`things`, `actions`, `verbs`).
|
|
186
|
+
* Convenience wrapper around the canonical
|
|
187
|
+
* {@link bootstrapClickHouseSchema}.
|
|
188
|
+
*/
|
|
189
|
+
export declare function bootstrapExperimentsSchema(fetcher: ClickHouseHttpFetcher, options?: {
|
|
190
|
+
database?: string;
|
|
191
|
+
}): Promise<void>;
|
|
192
|
+
/**
|
|
193
|
+
* Create a ClickHouse-backed experiment storage backend.
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```ts
|
|
197
|
+
* import { configureTracking } from 'ai-experiments'
|
|
198
|
+
* import { createClickHouseExperimentStorage } from 'ai-experiments/storage'
|
|
199
|
+
* import { createClickHouseHttpFetcher } from 'ai-database'
|
|
200
|
+
*
|
|
201
|
+
* const fetcher = createClickHouseHttpFetcher({
|
|
202
|
+
* url: process.env.CLICKHOUSE_URL!,
|
|
203
|
+
* username: process.env.CLICKHOUSE_USER,
|
|
204
|
+
* password: process.env.CLICKHOUSE_PASSWORD,
|
|
205
|
+
* database: 'aidb',
|
|
206
|
+
* })
|
|
207
|
+
* const storage = createClickHouseExperimentStorage({ fetcher })
|
|
208
|
+
*
|
|
209
|
+
* configureTracking({ backend: storage })
|
|
210
|
+
*
|
|
211
|
+
* const best = await storage.getBestVariant('my-experiment')
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
export declare function createClickHouseExperimentStorage(options: ClickHouseExperimentStorageOptions): ClickHouseExperimentStorage;
|
|
215
|
+
/**
|
|
216
|
+
* @deprecated Renamed to {@link ClickHouseExperimentStorage}. The class
|
|
217
|
+
* now wraps the canonical `ClickHouseProvider` from `ai-database` instead
|
|
218
|
+
* of embedded chdb. The old `dataPath` constructor option is ignored —
|
|
219
|
+
* supply a `fetcher` instead.
|
|
220
|
+
*/
|
|
221
|
+
export declare const ChdbStorage: typeof ClickHouseExperimentStorage;
|
|
222
|
+
export type ChdbStorage = ClickHouseExperimentStorage;
|
|
223
|
+
/**
|
|
224
|
+
* @deprecated Renamed to {@link createClickHouseExperimentStorage}.
|
|
225
|
+
*/
|
|
226
|
+
export declare function createChdbBackend(options: ClickHouseExperimentStorageOptions): ClickHouseExperimentStorage;
|
|
227
|
+
//# sourceMappingURL=clickhouse-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clickhouse-storage.d.ts","sourceRoot":"","sources":["../src/clickhouse-storage.ts"],"names":[],"mappings":"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"}
|