ai-experiments 0.1.0 → 2.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/.turbo/turbo-build.log +5 -0
- package/CHANGELOG.md +8 -0
- package/README.md +306 -91
- package/dist/cartesian.d.ts +140 -0
- package/dist/cartesian.d.ts.map +1 -0
- package/dist/cartesian.js +216 -0
- package/dist/cartesian.js.map +1 -0
- package/dist/decide.d.ts +152 -0
- package/dist/decide.d.ts.map +1 -0
- package/dist/decide.js +329 -0
- package/dist/decide.js.map +1 -0
- package/dist/experiment.d.ts +53 -0
- package/dist/experiment.d.ts.map +1 -0
- package/dist/experiment.js +292 -0
- package/dist/experiment.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/tracking.d.ts +159 -0
- package/dist/tracking.d.ts.map +1 -0
- package/dist/tracking.js +310 -0
- package/dist/tracking.js.map +1 -0
- package/dist/types.d.ts +198 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/examples.ts +261 -0
- package/package.json +21 -39
- package/src/cartesian.ts +259 -0
- package/src/decide.ts +398 -0
- package/src/experiment.ts +358 -0
- package/src/index.ts +44 -0
- package/src/tracking.ts +339 -0
- package/src/types.ts +215 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cartesian product utilities for parameter exploration
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Generate cartesian product of parameter sets
|
|
6
|
+
*
|
|
7
|
+
* Takes an object where each key maps to an array of possible values,
|
|
8
|
+
* and returns all possible combinations as an array of objects.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { cartesian } from 'ai-experiments'
|
|
13
|
+
*
|
|
14
|
+
* const combinations = cartesian({
|
|
15
|
+
* model: ['sonnet', 'opus', 'gpt-4o'],
|
|
16
|
+
* temperature: [0.3, 0.7, 1.0],
|
|
17
|
+
* maxTokens: [100, 500, 1000],
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* // Returns 27 combinations (3 * 3 * 3):
|
|
21
|
+
* // [
|
|
22
|
+
* // { model: 'sonnet', temperature: 0.3, maxTokens: 100 },
|
|
23
|
+
* // { model: 'sonnet', temperature: 0.3, maxTokens: 500 },
|
|
24
|
+
* // { model: 'sonnet', temperature: 0.3, maxTokens: 1000 },
|
|
25
|
+
* // { model: 'sonnet', temperature: 0.7, maxTokens: 100 },
|
|
26
|
+
* // ...
|
|
27
|
+
* // ]
|
|
28
|
+
*
|
|
29
|
+
* // Use with experiments:
|
|
30
|
+
* const variants = combinations.map((config, i) => ({
|
|
31
|
+
* id: `variant-${i}`,
|
|
32
|
+
* name: `${config.model} T=${config.temperature} max=${config.maxTokens}`,
|
|
33
|
+
* config,
|
|
34
|
+
* }))
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export function cartesian(params) {
|
|
38
|
+
const keys = Object.keys(params);
|
|
39
|
+
const values = keys.map((k) => params[k]);
|
|
40
|
+
// Handle empty input
|
|
41
|
+
if (keys.length === 0) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
// Handle single parameter
|
|
45
|
+
if (keys.length === 1) {
|
|
46
|
+
const key = keys[0];
|
|
47
|
+
return values[0].map((val) => ({ [key]: val }));
|
|
48
|
+
}
|
|
49
|
+
// Generate all combinations using recursive helper
|
|
50
|
+
const combinations = cartesianProduct(values);
|
|
51
|
+
// Map back to objects
|
|
52
|
+
return combinations.map((combo) => {
|
|
53
|
+
const obj = {};
|
|
54
|
+
keys.forEach((key, i) => {
|
|
55
|
+
obj[key] = combo[i];
|
|
56
|
+
});
|
|
57
|
+
return obj;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Recursive cartesian product implementation
|
|
62
|
+
*/
|
|
63
|
+
function cartesianProduct(arrays) {
|
|
64
|
+
if (arrays.length === 0)
|
|
65
|
+
return [[]];
|
|
66
|
+
const [first, ...rest] = arrays;
|
|
67
|
+
// Base case: single array
|
|
68
|
+
if (rest.length === 0) {
|
|
69
|
+
return first.map((x) => [x]);
|
|
70
|
+
}
|
|
71
|
+
// Recursive case
|
|
72
|
+
const restProduct = cartesianProduct(rest);
|
|
73
|
+
const result = [];
|
|
74
|
+
for (const x of first) {
|
|
75
|
+
for (const restCombo of restProduct) {
|
|
76
|
+
result.push([x, ...restCombo]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Generate a grid of parameter combinations with filtering
|
|
83
|
+
*
|
|
84
|
+
* Similar to cartesian(), but allows filtering out invalid combinations.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* import { cartesianFilter } from 'ai-experiments'
|
|
89
|
+
*
|
|
90
|
+
* const combinations = cartesianFilter(
|
|
91
|
+
* {
|
|
92
|
+
* model: ['sonnet', 'opus'],
|
|
93
|
+
* temperature: [0.3, 0.7, 1.0],
|
|
94
|
+
* maxTokens: [100, 500],
|
|
95
|
+
* },
|
|
96
|
+
* // Filter out combinations where opus uses high temperature
|
|
97
|
+
* (combo) => !(combo.model === 'opus' && combo.temperature > 0.7)
|
|
98
|
+
* )
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export function cartesianFilter(params, filter) {
|
|
102
|
+
const allCombinations = cartesian(params);
|
|
103
|
+
return allCombinations.filter(filter);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Generate a random sample from the cartesian product
|
|
107
|
+
*
|
|
108
|
+
* Useful when the full cartesian product is too large to test all combinations.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* import { cartesianSample } from 'ai-experiments'
|
|
113
|
+
*
|
|
114
|
+
* // Full product would be 1000 combinations (10 * 10 * 10)
|
|
115
|
+
* // Sample just 20 random combinations
|
|
116
|
+
* const sample = cartesianSample(
|
|
117
|
+
* {
|
|
118
|
+
* param1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
|
119
|
+
* param2: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
|
120
|
+
* param3: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
|
121
|
+
* },
|
|
122
|
+
* 20
|
|
123
|
+
* )
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export function cartesianSample(params, sampleSize, options = {}) {
|
|
127
|
+
const { unique = true } = options;
|
|
128
|
+
// Generate all combinations first
|
|
129
|
+
const allCombinations = cartesian(params);
|
|
130
|
+
// If sample size is larger than available combinations, return all
|
|
131
|
+
if (sampleSize >= allCombinations.length) {
|
|
132
|
+
return allCombinations;
|
|
133
|
+
}
|
|
134
|
+
// Shuffle and take first n items
|
|
135
|
+
const shuffled = [...allCombinations];
|
|
136
|
+
// Simple Fisher-Yates shuffle
|
|
137
|
+
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
138
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
139
|
+
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
|
140
|
+
}
|
|
141
|
+
return shuffled.slice(0, sampleSize);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Count the total number of combinations without generating them
|
|
145
|
+
*
|
|
146
|
+
* Useful for checking if cartesian product is feasible before generating.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* import { cartesianCount } from 'ai-experiments'
|
|
151
|
+
*
|
|
152
|
+
* const count = cartesianCount({
|
|
153
|
+
* model: ['sonnet', 'opus', 'gpt-4o'],
|
|
154
|
+
* temperature: [0.3, 0.5, 0.7, 0.9],
|
|
155
|
+
* maxTokens: [100, 500, 1000, 2000],
|
|
156
|
+
* })
|
|
157
|
+
* // Returns 48 (3 * 4 * 4)
|
|
158
|
+
*
|
|
159
|
+
* if (count > 100) {
|
|
160
|
+
* console.log('Too many combinations, use cartesianSample instead')
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export function cartesianCount(params) {
|
|
165
|
+
const keys = Object.keys(params);
|
|
166
|
+
if (keys.length === 0)
|
|
167
|
+
return 0;
|
|
168
|
+
return keys.reduce((total, key) => {
|
|
169
|
+
const arr = params[key];
|
|
170
|
+
return total * (arr?.length ?? 0);
|
|
171
|
+
}, 1);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Generate cartesian product with labels for each dimension
|
|
175
|
+
*
|
|
176
|
+
* Returns combinations with additional metadata about which dimension each value came from.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```ts
|
|
180
|
+
* import { cartesianWithLabels } from 'ai-experiments'
|
|
181
|
+
*
|
|
182
|
+
* const labeled = cartesianWithLabels({
|
|
183
|
+
* model: ['sonnet', 'opus'],
|
|
184
|
+
* temperature: [0.3, 0.7],
|
|
185
|
+
* })
|
|
186
|
+
* // [
|
|
187
|
+
* // { values: { model: 'sonnet', temperature: 0.3 }, labels: { model: 0, temperature: 0 } },
|
|
188
|
+
* // { values: { model: 'sonnet', temperature: 0.7 }, labels: { model: 0, temperature: 1 } },
|
|
189
|
+
* // { values: { model: 'opus', temperature: 0.3 }, labels: { model: 1, temperature: 0 } },
|
|
190
|
+
* // { values: { model: 'opus', temperature: 0.7 }, labels: { model: 1, temperature: 1 } },
|
|
191
|
+
* // ]
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export function cartesianWithLabels(params) {
|
|
195
|
+
const keys = Object.keys(params);
|
|
196
|
+
const values = keys.map((k) => params[k]);
|
|
197
|
+
if (keys.length === 0) {
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
const combinations = cartesianProduct(values);
|
|
201
|
+
return combinations.map((combo) => {
|
|
202
|
+
const valuesObj = {};
|
|
203
|
+
const labelsObj = {};
|
|
204
|
+
keys.forEach((key, i) => {
|
|
205
|
+
const value = combo[i];
|
|
206
|
+
valuesObj[key] = value;
|
|
207
|
+
const arr = params[key];
|
|
208
|
+
labelsObj[key] = arr ? arr.indexOf(value) : -1;
|
|
209
|
+
});
|
|
210
|
+
return {
|
|
211
|
+
values: valuesObj,
|
|
212
|
+
labels: labelsObj,
|
|
213
|
+
};
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=cartesian.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cartesian.js","sourceRoot":"","sources":["../src/cartesian.ts"],"names":[],"mappings":"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"}
|
package/dist/decide.d.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decision making utilities
|
|
3
|
+
*/
|
|
4
|
+
import type { DecideOptions, DecisionResult } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Make a decision by evaluating and scoring multiple options
|
|
7
|
+
*
|
|
8
|
+
* Scores each option and returns the best one (highest score).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { decide } from 'ai-experiments'
|
|
13
|
+
*
|
|
14
|
+
* // Simple decision with sync scoring
|
|
15
|
+
* const result = await decide({
|
|
16
|
+
* options: ['apple', 'banana', 'orange'],
|
|
17
|
+
* score: (fruit) => {
|
|
18
|
+
* const prices = { apple: 1.5, banana: 0.5, orange: 2.0 }
|
|
19
|
+
* return 1 / prices[fruit] // Lower price = higher score
|
|
20
|
+
* },
|
|
21
|
+
* })
|
|
22
|
+
* console.log(result.selected) // 'banana'
|
|
23
|
+
*
|
|
24
|
+
* // Decision with async scoring (AI-based)
|
|
25
|
+
* const result = await decide({
|
|
26
|
+
* options: [
|
|
27
|
+
* { prompt: 'Summarize in one sentence' },
|
|
28
|
+
* { prompt: 'Provide a detailed summary' },
|
|
29
|
+
* { prompt: 'Extract key points only' },
|
|
30
|
+
* ],
|
|
31
|
+
* score: async (option) => {
|
|
32
|
+
* const result = await ai.generate(option)
|
|
33
|
+
* return evaluateQuality(result)
|
|
34
|
+
* },
|
|
35
|
+
* context: 'Choosing best summarization approach',
|
|
36
|
+
* })
|
|
37
|
+
*
|
|
38
|
+
* // Get all options sorted by score
|
|
39
|
+
* const result = await decide({
|
|
40
|
+
* options: ['fast', 'accurate', 'balanced'],
|
|
41
|
+
* score: (approach) => evaluateApproach(approach),
|
|
42
|
+
* returnAll: true,
|
|
43
|
+
* })
|
|
44
|
+
* console.log(result.allOptions)
|
|
45
|
+
* // [
|
|
46
|
+
* // { option: 'balanced', score: 0.9 },
|
|
47
|
+
* // { option: 'accurate', score: 0.85 },
|
|
48
|
+
* // { option: 'fast', score: 0.7 },
|
|
49
|
+
* // ]
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function decide<T>(options: DecideOptions<T>): Promise<DecisionResult<T>>;
|
|
53
|
+
/**
|
|
54
|
+
* Weighted random selection from options
|
|
55
|
+
*
|
|
56
|
+
* Each option has a weight, and selection probability is proportional to weight.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* import { decideWeighted } from 'ai-experiments'
|
|
61
|
+
*
|
|
62
|
+
* const result = decideWeighted([
|
|
63
|
+
* { value: 'A', weight: 0.7 }, // 70% chance
|
|
64
|
+
* { value: 'B', weight: 0.2 }, // 20% chance
|
|
65
|
+
* { value: 'C', weight: 0.1 }, // 10% chance
|
|
66
|
+
* ])
|
|
67
|
+
*
|
|
68
|
+
* console.log(result) // Most likely 'A', but could be B or C
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare function decideWeighted<T>(options: Array<{
|
|
72
|
+
value: T;
|
|
73
|
+
weight: number;
|
|
74
|
+
}>): T;
|
|
75
|
+
/**
|
|
76
|
+
* Epsilon-greedy decision strategy
|
|
77
|
+
*
|
|
78
|
+
* With probability epsilon, select a random option (exploration).
|
|
79
|
+
* Otherwise, select the best option by score (exploitation).
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* import { decideEpsilonGreedy } from 'ai-experiments'
|
|
84
|
+
*
|
|
85
|
+
* const result = await decideEpsilonGreedy({
|
|
86
|
+
* options: ['model-a', 'model-b', 'model-c'],
|
|
87
|
+
* score: async (model) => await evaluateModel(model),
|
|
88
|
+
* epsilon: 0.1, // 10% exploration, 90% exploitation
|
|
89
|
+
* })
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare function decideEpsilonGreedy<T>(options: DecideOptions<T> & {
|
|
93
|
+
epsilon: number;
|
|
94
|
+
}): Promise<DecisionResult<T>>;
|
|
95
|
+
/**
|
|
96
|
+
* Thompson sampling decision strategy
|
|
97
|
+
*
|
|
98
|
+
* Bayesian approach to balancing exploration and exploitation.
|
|
99
|
+
* Each option has a Beta distribution representing our belief about its true score.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* import { decideThompsonSampling } from 'ai-experiments'
|
|
104
|
+
*
|
|
105
|
+
* // Track successes and failures for each option
|
|
106
|
+
* const priors = {
|
|
107
|
+
* 'variant-a': { alpha: 10, beta: 5 }, // 10 successes, 5 failures
|
|
108
|
+
* 'variant-b': { alpha: 8, beta: 3 }, // 8 successes, 3 failures
|
|
109
|
+
* 'variant-c': { alpha: 2, beta: 2 }, // 2 successes, 2 failures (uncertain)
|
|
110
|
+
* }
|
|
111
|
+
*
|
|
112
|
+
* const result = decideThompsonSampling(['variant-a', 'variant-b', 'variant-c'], priors)
|
|
113
|
+
* // More likely to select 'variant-b' (higher rate) but will sometimes explore 'variant-c'
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare function decideThompsonSampling<T extends string>(options: T[], priors: Record<T, {
|
|
117
|
+
alpha: number;
|
|
118
|
+
beta: number;
|
|
119
|
+
}>): T;
|
|
120
|
+
/**
|
|
121
|
+
* Upper Confidence Bound (UCB) decision strategy
|
|
122
|
+
*
|
|
123
|
+
* Select the option with the highest upper confidence bound.
|
|
124
|
+
* Balances exploration and exploitation using confidence intervals.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* import { decideUCB } from 'ai-experiments'
|
|
129
|
+
*
|
|
130
|
+
* const stats = {
|
|
131
|
+
* 'variant-a': { mean: 0.85, count: 100 },
|
|
132
|
+
* 'variant-b': { mean: 0.82, count: 50 }, // Less data, higher uncertainty
|
|
133
|
+
* 'variant-c': { mean: 0.78, count: 10 }, // Very uncertain
|
|
134
|
+
* }
|
|
135
|
+
*
|
|
136
|
+
* const result = decideUCB(['variant-a', 'variant-b', 'variant-c'], stats, {
|
|
137
|
+
* explorationFactor: 2.0,
|
|
138
|
+
* totalCount: 160,
|
|
139
|
+
* })
|
|
140
|
+
* // Might select variant-c to explore more, despite lower mean
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export declare function decideUCB<T extends string>(options: T[], stats: Record<T, {
|
|
144
|
+
mean: number;
|
|
145
|
+
count: number;
|
|
146
|
+
}>, config: {
|
|
147
|
+
/** Exploration factor (typically 1-2) */
|
|
148
|
+
explorationFactor: number;
|
|
149
|
+
/** Total number of trials across all options */
|
|
150
|
+
totalCount: number;
|
|
151
|
+
}): T;
|
|
152
|
+
//# sourceMappingURL=decide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decide.d.ts","sourceRoot":"","sources":["../src/decide.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAG/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,wBAAsB,MAAM,CAAC,CAAC,EAC5B,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CA2C5B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAC3C,CAAC,CA0BH;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CA6C5B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EACrD,OAAO,EAAE,CAAC,EAAE,EACZ,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GACjD,CAAC,CA+BH;AAuDD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EACxC,OAAO,EAAE,CAAC,EAAE,EACZ,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EACjD,MAAM,EAAE;IACN,yCAAyC;IACzC,iBAAiB,EAAE,MAAM,CAAA;IACzB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAA;CACnB,GACA,CAAC,CAwCH"}
|