@ax-llm/ax 11.0.27 → 11.0.28
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/index.cjs +845 -42
- package/index.cjs.map +1 -1
- package/index.d.cts +148 -2
- package/index.d.ts +148 -2
- package/index.js +848 -46
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -98,6 +98,7 @@ __export(index_exports, {
|
|
|
98
98
|
AxMCPHTTPTransport: () => AxMCPHTTPTransport,
|
|
99
99
|
AxMCPStdioTransport: () => AxMCPStdioTransport,
|
|
100
100
|
AxMemory: () => AxMemory,
|
|
101
|
+
AxMiPRO: () => AxMiPRO,
|
|
101
102
|
AxMockAIService: () => AxMockAIService,
|
|
102
103
|
AxMultiServiceRouter: () => AxMultiServiceRouter,
|
|
103
104
|
AxProgram: () => AxProgram,
|
|
@@ -4785,16 +4786,19 @@ var validateValue = (field, value) => {
|
|
|
4785
4786
|
};
|
|
4786
4787
|
function mergeProgramUsage(usages) {
|
|
4787
4788
|
const usageMap = {};
|
|
4788
|
-
|
|
4789
|
+
for (const usage of usages) {
|
|
4789
4790
|
const key = `${usage.ai}:${usage.model}`;
|
|
4790
4791
|
if (!usageMap[key]) {
|
|
4791
4792
|
usageMap[key] = { ...usage };
|
|
4792
|
-
|
|
4793
|
+
continue;
|
|
4793
4794
|
}
|
|
4794
|
-
usageMap[key]
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4795
|
+
const currentUsage = usageMap[key];
|
|
4796
|
+
if (currentUsage) {
|
|
4797
|
+
currentUsage.promptTokens += usage.promptTokens;
|
|
4798
|
+
currentUsage.completionTokens += usage.completionTokens;
|
|
4799
|
+
currentUsage.totalTokens += usage.totalTokens;
|
|
4800
|
+
}
|
|
4801
|
+
}
|
|
4798
4802
|
return Object.values(usageMap);
|
|
4799
4803
|
}
|
|
4800
4804
|
var parseMarkdownList = (input) => {
|
|
@@ -4815,7 +4819,6 @@ var parseMarkdownList = (input) => {
|
|
|
4815
4819
|
} else if (numberedListRegex.test(trimmedLine)) {
|
|
4816
4820
|
list.push(trimmedLine.replace(numberedListRegex, "").trim());
|
|
4817
4821
|
} else if (list.length === 0) {
|
|
4818
|
-
continue;
|
|
4819
4822
|
} else {
|
|
4820
4823
|
throw new Error("Could not parse markdown list: mixed content detected");
|
|
4821
4824
|
}
|
|
@@ -4888,12 +4891,72 @@ function matchesContent(content, prefix, startIndex = 0, prefixCache = globalPre
|
|
|
4888
4891
|
);
|
|
4889
4892
|
for (let i = 0; i < prefixes.length - 1; i++) {
|
|
4890
4893
|
const partialPrefix = prefixes[i];
|
|
4891
|
-
if (contentEnd.endsWith(partialPrefix)) {
|
|
4894
|
+
if (partialPrefix && contentEnd.endsWith(partialPrefix)) {
|
|
4892
4895
|
return -2;
|
|
4893
4896
|
}
|
|
4894
4897
|
}
|
|
4895
4898
|
return -1;
|
|
4896
4899
|
}
|
|
4900
|
+
var formatTime = (ms) => {
|
|
4901
|
+
const seconds = Math.floor(ms / 1e3);
|
|
4902
|
+
if (seconds < 60) return `${seconds}s`;
|
|
4903
|
+
const minutes = Math.floor(seconds / 60);
|
|
4904
|
+
const remainingSeconds = seconds % 60;
|
|
4905
|
+
if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;
|
|
4906
|
+
const hours = Math.floor(minutes / 60);
|
|
4907
|
+
const remainingMinutes = minutes % 60;
|
|
4908
|
+
return `${hours}h ${remainingMinutes}m ${remainingSeconds}s`;
|
|
4909
|
+
};
|
|
4910
|
+
var calculateETA = (current, total, elapsedMs) => {
|
|
4911
|
+
if (current === 0) return "calculating...";
|
|
4912
|
+
const msPerItem = elapsedMs / current;
|
|
4913
|
+
const remainingItems = total - current;
|
|
4914
|
+
const etaMs = msPerItem * remainingItems;
|
|
4915
|
+
return formatTime(etaMs);
|
|
4916
|
+
};
|
|
4917
|
+
var updateDetailedProgress = (roundIndex, current, total, elapsedTime, example, stats, configInfo, result, error) => {
|
|
4918
|
+
process.stdout.write("\r\x1B[K");
|
|
4919
|
+
const percentage = (current / total * 100).toFixed(1);
|
|
4920
|
+
const formattedTime = formatTime(elapsedTime);
|
|
4921
|
+
const itemsPerSecond = elapsedTime > 0 ? (current / elapsedTime * 1e3).toFixed(2) : "0.00";
|
|
4922
|
+
const eta = calculateETA(current, total, elapsedTime);
|
|
4923
|
+
let output = `Round ${roundIndex + 1}/${configInfo.maxRounds}: ${current}/${total} (${percentage}%) [${formattedTime}, ${itemsPerSecond} it/s, ETA: ${eta}]`;
|
|
4924
|
+
const successRate = stats.totalCalls > 0 ? stats.successfulDemos / stats.totalCalls * 100 : 0;
|
|
4925
|
+
output += ` | Success: ${stats.successfulDemos}/${stats.totalCalls} (${successRate.toFixed(1)}%)`;
|
|
4926
|
+
if (configInfo.verboseMode || configInfo.debugMode) {
|
|
4927
|
+
if (configInfo.costMonitoring) {
|
|
4928
|
+
output += `
|
|
4929
|
+
Tokens: ~${stats.estimatedTokenUsage.toLocaleString()} total`;
|
|
4930
|
+
}
|
|
4931
|
+
output += `
|
|
4932
|
+
Batch: ${Math.floor(current / configInfo.batchSize) + 1}/${Math.ceil(total / configInfo.batchSize)}`;
|
|
4933
|
+
if (configInfo.earlyStoppingPatience > 0 && stats.earlyStopping) {
|
|
4934
|
+
output += `
|
|
4935
|
+
Best round: ${stats.earlyStopping.bestScoreRound + 1}, Patience: ${configInfo.earlyStoppingPatience}`;
|
|
4936
|
+
}
|
|
4937
|
+
}
|
|
4938
|
+
if (configInfo.debugMode) {
|
|
4939
|
+
const exampleKeys = Object.keys(example).map((k) => {
|
|
4940
|
+
const valueStr = JSON.stringify(example[k]);
|
|
4941
|
+
const truncated = valueStr.length > 30 ? `${valueStr.substring(0, 30)}...` : valueStr;
|
|
4942
|
+
return `${k}: ${truncated}`;
|
|
4943
|
+
}).join(", ");
|
|
4944
|
+
output += `
|
|
4945
|
+
Example: {${exampleKeys}}`;
|
|
4946
|
+
if (error) {
|
|
4947
|
+
output += `
|
|
4948
|
+
ERROR: ${error.message}`;
|
|
4949
|
+
} else if (result) {
|
|
4950
|
+
const resultStr = JSON.stringify(result);
|
|
4951
|
+
const truncatedResult = resultStr.length > 50 ? `${resultStr.substring(0, 50)}...` : resultStr;
|
|
4952
|
+
output += `
|
|
4953
|
+
Result: ${truncatedResult}`;
|
|
4954
|
+
}
|
|
4955
|
+
output += `
|
|
4956
|
+
Temperature: ${(0.7 + 1e-3 * current).toFixed(3)}`;
|
|
4957
|
+
}
|
|
4958
|
+
console.log(output);
|
|
4959
|
+
};
|
|
4897
4960
|
|
|
4898
4961
|
// dsp/program.ts
|
|
4899
4962
|
var AxProgramWithSignature = class {
|
|
@@ -5135,7 +5198,7 @@ ${outputFields}`);
|
|
|
5135
5198
|
demos
|
|
5136
5199
|
}) => {
|
|
5137
5200
|
const renderedExamples = examples ? [
|
|
5138
|
-
{ type: "text", text: "## Examples
|
|
5201
|
+
{ type: "text", text: "\n\n## Examples\n" },
|
|
5139
5202
|
...this.renderExamples(examples)
|
|
5140
5203
|
] : [];
|
|
5141
5204
|
const renderedDemos = demos ? this.renderDemos(demos) : [];
|
|
@@ -5218,6 +5281,9 @@ ${outputFields}`);
|
|
|
5218
5281
|
);
|
|
5219
5282
|
}
|
|
5220
5283
|
const renderedItem = [...renderedInputItem, ...renderedOutputItem];
|
|
5284
|
+
if (index > 0 && renderedItem.length > 0 && renderedItem[0]?.type === "text") {
|
|
5285
|
+
list.push({ type: "text", text: "---\n\n" });
|
|
5286
|
+
}
|
|
5221
5287
|
renderedItem.forEach((v) => {
|
|
5222
5288
|
if ("text" in v) {
|
|
5223
5289
|
v.text = v.text + "\n";
|
|
@@ -5401,10 +5467,7 @@ var processValue = (field, value) => {
|
|
|
5401
5467
|
if (typeof value === "string") {
|
|
5402
5468
|
return value;
|
|
5403
5469
|
}
|
|
5404
|
-
|
|
5405
|
-
return value;
|
|
5406
|
-
}
|
|
5407
|
-
return JSON.stringify(value);
|
|
5470
|
+
return JSON.stringify(value, null, 2);
|
|
5408
5471
|
};
|
|
5409
5472
|
var toFieldType = (type) => {
|
|
5410
5473
|
const baseType = (() => {
|
|
@@ -7145,60 +7208,147 @@ function validateModels2(services) {
|
|
|
7145
7208
|
// dsp/optimize.ts
|
|
7146
7209
|
var AxBootstrapFewShot = class {
|
|
7147
7210
|
ai;
|
|
7211
|
+
teacherAI;
|
|
7148
7212
|
program;
|
|
7149
7213
|
examples;
|
|
7150
7214
|
maxRounds;
|
|
7151
7215
|
maxDemos;
|
|
7152
7216
|
maxExamples;
|
|
7217
|
+
batchSize;
|
|
7218
|
+
earlyStoppingPatience;
|
|
7219
|
+
costMonitoring;
|
|
7220
|
+
maxTokensPerGeneration;
|
|
7221
|
+
verboseMode;
|
|
7222
|
+
debugMode;
|
|
7153
7223
|
traces = [];
|
|
7224
|
+
stats = {
|
|
7225
|
+
totalCalls: 0,
|
|
7226
|
+
successfulDemos: 0,
|
|
7227
|
+
estimatedTokenUsage: 0,
|
|
7228
|
+
earlyStopped: false
|
|
7229
|
+
};
|
|
7154
7230
|
constructor({
|
|
7155
7231
|
ai,
|
|
7156
7232
|
program,
|
|
7157
7233
|
examples = [],
|
|
7158
7234
|
options
|
|
7159
7235
|
}) {
|
|
7160
|
-
if (examples.length
|
|
7236
|
+
if (examples.length === 0) {
|
|
7161
7237
|
throw new Error("No examples found");
|
|
7162
7238
|
}
|
|
7163
7239
|
this.maxRounds = options?.maxRounds ?? 3;
|
|
7164
7240
|
this.maxDemos = options?.maxDemos ?? 4;
|
|
7165
7241
|
this.maxExamples = options?.maxExamples ?? 16;
|
|
7242
|
+
this.batchSize = options?.batchSize ?? 1;
|
|
7243
|
+
this.earlyStoppingPatience = options?.earlyStoppingPatience ?? 0;
|
|
7244
|
+
this.costMonitoring = options?.costMonitoring ?? false;
|
|
7245
|
+
this.maxTokensPerGeneration = options?.maxTokensPerGeneration ?? 0;
|
|
7246
|
+
this.verboseMode = options?.verboseMode ?? true;
|
|
7247
|
+
this.debugMode = options?.debugMode ?? false;
|
|
7166
7248
|
this.ai = ai;
|
|
7249
|
+
this.teacherAI = options?.teacherAI;
|
|
7167
7250
|
this.program = program;
|
|
7168
7251
|
this.examples = examples;
|
|
7169
7252
|
}
|
|
7170
7253
|
async compileRound(roundIndex, metricFn, options) {
|
|
7171
7254
|
const st = (/* @__PURE__ */ new Date()).getTime();
|
|
7172
7255
|
const maxDemos = options?.maxDemos ?? this.maxDemos;
|
|
7173
|
-
const aiOpt = {
|
|
7256
|
+
const aiOpt = {
|
|
7257
|
+
modelConfig: {
|
|
7258
|
+
temperature: 0.7
|
|
7259
|
+
}
|
|
7260
|
+
};
|
|
7261
|
+
if (this.maxTokensPerGeneration > 0) {
|
|
7262
|
+
aiOpt.modelConfig.max_tokens = this.maxTokensPerGeneration;
|
|
7263
|
+
}
|
|
7174
7264
|
const examples = randomSample(this.examples, this.maxExamples);
|
|
7175
|
-
|
|
7265
|
+
const previousSuccessCount = this.traces.length;
|
|
7266
|
+
for (let i = 0; i < examples.length; i += this.batchSize) {
|
|
7176
7267
|
if (i > 0) {
|
|
7177
7268
|
aiOpt.modelConfig.temperature = 0.7 + 1e-3 * i;
|
|
7178
7269
|
}
|
|
7179
|
-
const
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7270
|
+
const batch = examples.slice(i, i + this.batchSize);
|
|
7271
|
+
for (const ex of batch) {
|
|
7272
|
+
if (!ex) {
|
|
7273
|
+
continue;
|
|
7274
|
+
}
|
|
7275
|
+
const exList = examples.filter((e) => e !== ex);
|
|
7276
|
+
this.program.setExamples(exList);
|
|
7277
|
+
const aiService = this.teacherAI || this.ai;
|
|
7278
|
+
this.stats.totalCalls++;
|
|
7279
|
+
let res;
|
|
7280
|
+
let error;
|
|
7281
|
+
try {
|
|
7282
|
+
res = await this.program.forward(aiService, ex, aiOpt);
|
|
7283
|
+
if (this.costMonitoring) {
|
|
7284
|
+
this.stats.estimatedTokenUsage += JSON.stringify(ex).length / 4 + JSON.stringify(res).length / 4;
|
|
7285
|
+
}
|
|
7286
|
+
const success = metricFn({ prediction: res, example: ex });
|
|
7287
|
+
if (success) {
|
|
7288
|
+
this.traces = [...this.traces, ...this.program.getTraces()];
|
|
7289
|
+
this.stats.successfulDemos++;
|
|
7290
|
+
}
|
|
7291
|
+
} catch (err) {
|
|
7292
|
+
error = err;
|
|
7293
|
+
res = {};
|
|
7294
|
+
}
|
|
7295
|
+
const current = i + examples.length * roundIndex + (batch.indexOf(ex) + 1);
|
|
7296
|
+
const total = examples.length * this.maxRounds;
|
|
7297
|
+
const et = (/* @__PURE__ */ new Date()).getTime() - st;
|
|
7298
|
+
if (this.verboseMode || this.debugMode) {
|
|
7299
|
+
const configInfo = {
|
|
7300
|
+
maxRounds: this.maxRounds,
|
|
7301
|
+
batchSize: this.batchSize,
|
|
7302
|
+
earlyStoppingPatience: this.earlyStoppingPatience,
|
|
7303
|
+
costMonitoring: this.costMonitoring,
|
|
7304
|
+
verboseMode: this.verboseMode,
|
|
7305
|
+
debugMode: this.debugMode
|
|
7306
|
+
};
|
|
7307
|
+
updateDetailedProgress(
|
|
7308
|
+
roundIndex,
|
|
7309
|
+
current,
|
|
7310
|
+
total,
|
|
7311
|
+
et,
|
|
7312
|
+
ex,
|
|
7313
|
+
this.stats,
|
|
7314
|
+
configInfo,
|
|
7315
|
+
res,
|
|
7316
|
+
error
|
|
7317
|
+
);
|
|
7318
|
+
} else {
|
|
7319
|
+
updateProgressBar(
|
|
7320
|
+
current,
|
|
7321
|
+
total,
|
|
7322
|
+
this.traces.length,
|
|
7323
|
+
et,
|
|
7324
|
+
"Tuning Prompt",
|
|
7325
|
+
30
|
|
7326
|
+
);
|
|
7327
|
+
}
|
|
7328
|
+
if (this.traces.length >= maxDemos) {
|
|
7329
|
+
return;
|
|
7330
|
+
}
|
|
7189
7331
|
}
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
const
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
if (this.
|
|
7332
|
+
}
|
|
7333
|
+
if (this.earlyStoppingPatience > 0) {
|
|
7334
|
+
const newSuccessCount = this.traces.length;
|
|
7335
|
+
const improvement = newSuccessCount - previousSuccessCount;
|
|
7336
|
+
if (!this.stats.earlyStopping) {
|
|
7337
|
+
this.stats.earlyStopping = {
|
|
7338
|
+
bestScoreRound: improvement > 0 ? roundIndex : 0,
|
|
7339
|
+
patienceExhausted: false
|
|
7340
|
+
};
|
|
7341
|
+
} else if (improvement > 0) {
|
|
7342
|
+
this.stats.earlyStopping.bestScoreRound = roundIndex;
|
|
7343
|
+
} else if (roundIndex - this.stats.earlyStopping.bestScoreRound >= this.earlyStoppingPatience) {
|
|
7344
|
+
this.stats.earlyStopping.patienceExhausted = true;
|
|
7345
|
+
this.stats.earlyStopped = true;
|
|
7346
|
+
if (this.verboseMode || this.debugMode) {
|
|
7347
|
+
console.log(
|
|
7348
|
+
`
|
|
7349
|
+
Early stopping triggered after ${roundIndex + 1} rounds. No improvement for ${this.earlyStoppingPatience} rounds.`
|
|
7350
|
+
);
|
|
7351
|
+
}
|
|
7202
7352
|
return;
|
|
7203
7353
|
}
|
|
7204
7354
|
}
|
|
@@ -7206,8 +7356,17 @@ var AxBootstrapFewShot = class {
|
|
|
7206
7356
|
async compile(metricFn, options) {
|
|
7207
7357
|
const maxRounds = options?.maxRounds ?? this.maxRounds;
|
|
7208
7358
|
this.traces = [];
|
|
7359
|
+
this.stats = {
|
|
7360
|
+
totalCalls: 0,
|
|
7361
|
+
successfulDemos: 0,
|
|
7362
|
+
estimatedTokenUsage: 0,
|
|
7363
|
+
earlyStopped: false
|
|
7364
|
+
};
|
|
7209
7365
|
for (let i = 0; i < maxRounds; i++) {
|
|
7210
7366
|
await this.compileRound(i, metricFn, options);
|
|
7367
|
+
if (this.stats.earlyStopped) {
|
|
7368
|
+
break;
|
|
7369
|
+
}
|
|
7211
7370
|
}
|
|
7212
7371
|
if (this.traces.length === 0) {
|
|
7213
7372
|
throw new Error(
|
|
@@ -7215,22 +7374,32 @@ var AxBootstrapFewShot = class {
|
|
|
7215
7374
|
);
|
|
7216
7375
|
}
|
|
7217
7376
|
const demos = groupTracesByKeys(this.traces);
|
|
7218
|
-
return
|
|
7377
|
+
return {
|
|
7378
|
+
demos,
|
|
7379
|
+
stats: this.stats
|
|
7380
|
+
};
|
|
7381
|
+
}
|
|
7382
|
+
// Get optimization statistics
|
|
7383
|
+
getStats() {
|
|
7384
|
+
return this.stats;
|
|
7219
7385
|
}
|
|
7220
7386
|
};
|
|
7221
7387
|
function groupTracesByKeys(programTraces) {
|
|
7222
7388
|
const groupedTraces = /* @__PURE__ */ new Map();
|
|
7223
7389
|
for (const programTrace of programTraces) {
|
|
7224
7390
|
if (groupedTraces.has(programTrace.programId)) {
|
|
7225
|
-
groupedTraces.get(programTrace.programId)
|
|
7391
|
+
const traces = groupedTraces.get(programTrace.programId);
|
|
7392
|
+
if (traces) {
|
|
7393
|
+
traces.push(programTrace.trace);
|
|
7394
|
+
}
|
|
7226
7395
|
} else {
|
|
7227
7396
|
groupedTraces.set(programTrace.programId, [programTrace.trace]);
|
|
7228
7397
|
}
|
|
7229
7398
|
}
|
|
7230
7399
|
const programDemosArray = [];
|
|
7231
|
-
groupedTraces.
|
|
7400
|
+
for (const [programId, traces] of groupedTraces.entries()) {
|
|
7232
7401
|
programDemosArray.push({ traces, programId });
|
|
7233
|
-
}
|
|
7402
|
+
}
|
|
7234
7403
|
return programDemosArray;
|
|
7235
7404
|
}
|
|
7236
7405
|
var randomSample = (array, n) => {
|
|
@@ -8350,6 +8519,639 @@ var AxJSInterpreter = class {
|
|
|
8350
8519
|
}
|
|
8351
8520
|
};
|
|
8352
8521
|
|
|
8522
|
+
// dsp/mipro.ts
|
|
8523
|
+
var AxMiPRO = class {
|
|
8524
|
+
ai;
|
|
8525
|
+
program;
|
|
8526
|
+
examples;
|
|
8527
|
+
maxBootstrappedDemos;
|
|
8528
|
+
maxLabeledDemos;
|
|
8529
|
+
numCandidates;
|
|
8530
|
+
initTemperature;
|
|
8531
|
+
numTrials;
|
|
8532
|
+
minibatch;
|
|
8533
|
+
minibatchSize;
|
|
8534
|
+
minibatchFullEvalSteps;
|
|
8535
|
+
programAwareProposer;
|
|
8536
|
+
dataAwareProposer;
|
|
8537
|
+
viewDataBatchSize;
|
|
8538
|
+
tipAwareProposer;
|
|
8539
|
+
fewshotAwareProposer;
|
|
8540
|
+
seed;
|
|
8541
|
+
verbose;
|
|
8542
|
+
bootstrapper;
|
|
8543
|
+
earlyStoppingTrials;
|
|
8544
|
+
minImprovementThreshold;
|
|
8545
|
+
constructor({
|
|
8546
|
+
ai,
|
|
8547
|
+
program,
|
|
8548
|
+
examples = [],
|
|
8549
|
+
options
|
|
8550
|
+
}) {
|
|
8551
|
+
if (examples.length === 0) {
|
|
8552
|
+
throw new Error("No examples found");
|
|
8553
|
+
}
|
|
8554
|
+
const miproOptions = options || {};
|
|
8555
|
+
this.numCandidates = miproOptions.numCandidates ?? 5;
|
|
8556
|
+
this.initTemperature = miproOptions.initTemperature ?? 0.7;
|
|
8557
|
+
this.maxBootstrappedDemos = miproOptions.maxBootstrappedDemos ?? 3;
|
|
8558
|
+
this.maxLabeledDemos = miproOptions.maxLabeledDemos ?? 4;
|
|
8559
|
+
this.numTrials = miproOptions.numTrials ?? 30;
|
|
8560
|
+
this.minibatch = miproOptions.minibatch ?? true;
|
|
8561
|
+
this.minibatchSize = miproOptions.minibatchSize ?? 25;
|
|
8562
|
+
this.minibatchFullEvalSteps = miproOptions.minibatchFullEvalSteps ?? 10;
|
|
8563
|
+
this.programAwareProposer = miproOptions.programAwareProposer ?? true;
|
|
8564
|
+
this.dataAwareProposer = miproOptions.dataAwareProposer ?? true;
|
|
8565
|
+
this.viewDataBatchSize = miproOptions.viewDataBatchSize ?? 10;
|
|
8566
|
+
this.tipAwareProposer = miproOptions.tipAwareProposer ?? true;
|
|
8567
|
+
this.fewshotAwareProposer = miproOptions.fewshotAwareProposer ?? true;
|
|
8568
|
+
this.seed = miproOptions.seed;
|
|
8569
|
+
this.verbose = miproOptions.verbose ?? false;
|
|
8570
|
+
this.earlyStoppingTrials = miproOptions.earlyStoppingTrials ?? 5;
|
|
8571
|
+
this.minImprovementThreshold = miproOptions.minImprovementThreshold ?? 0.01;
|
|
8572
|
+
this.ai = ai;
|
|
8573
|
+
this.program = program;
|
|
8574
|
+
this.examples = examples;
|
|
8575
|
+
this.bootstrapper = new AxBootstrapFewShot({
|
|
8576
|
+
ai,
|
|
8577
|
+
program,
|
|
8578
|
+
examples,
|
|
8579
|
+
options: {
|
|
8580
|
+
maxDemos: this.maxBootstrappedDemos,
|
|
8581
|
+
maxRounds: 3,
|
|
8582
|
+
// Default, or adjust based on your needs
|
|
8583
|
+
verboseMode: this.verbose
|
|
8584
|
+
}
|
|
8585
|
+
});
|
|
8586
|
+
}
|
|
8587
|
+
/**
|
|
8588
|
+
* Configures the optimizer for light, medium, or heavy optimization
|
|
8589
|
+
* @param level The optimization level: "light", "medium", or "heavy"
|
|
8590
|
+
*/
|
|
8591
|
+
configureAuto(level) {
|
|
8592
|
+
switch (level) {
|
|
8593
|
+
case "light":
|
|
8594
|
+
this.numCandidates = 3;
|
|
8595
|
+
this.numTrials = 10;
|
|
8596
|
+
this.minibatch = true;
|
|
8597
|
+
this.minibatchSize = 20;
|
|
8598
|
+
break;
|
|
8599
|
+
case "medium":
|
|
8600
|
+
this.numCandidates = 5;
|
|
8601
|
+
this.numTrials = 20;
|
|
8602
|
+
this.minibatch = true;
|
|
8603
|
+
this.minibatchSize = 25;
|
|
8604
|
+
break;
|
|
8605
|
+
case "heavy":
|
|
8606
|
+
this.numCandidates = 7;
|
|
8607
|
+
this.numTrials = 30;
|
|
8608
|
+
this.minibatch = true;
|
|
8609
|
+
this.minibatchSize = 30;
|
|
8610
|
+
break;
|
|
8611
|
+
}
|
|
8612
|
+
}
|
|
8613
|
+
/**
|
|
8614
|
+
* Generates creative tips for instruction generation
|
|
8615
|
+
*/
|
|
8616
|
+
generateTips() {
|
|
8617
|
+
return [
|
|
8618
|
+
"Be very specific and detailed in your instructions.",
|
|
8619
|
+
"Focus on step-by-step reasoning in your instructions.",
|
|
8620
|
+
"Provide clear constraints and guidelines in your instructions.",
|
|
8621
|
+
"Keep your instructions concise and to the point.",
|
|
8622
|
+
"Emphasize accuracy and precision in your instructions.",
|
|
8623
|
+
"Include examples of good outputs in your instructions.",
|
|
8624
|
+
"Focus on handling edge cases in your instructions.",
|
|
8625
|
+
"Explicitly outline the reasoning process in your instructions."
|
|
8626
|
+
];
|
|
8627
|
+
}
|
|
8628
|
+
/**
|
|
8629
|
+
* Generates instruction candidates for each predictor in the program
|
|
8630
|
+
* @returns Array of generated instruction candidates
|
|
8631
|
+
*/
|
|
8632
|
+
async proposeInstructionCandidates() {
|
|
8633
|
+
const instructions = [];
|
|
8634
|
+
let programContext = "";
|
|
8635
|
+
if (this.programAwareProposer) {
|
|
8636
|
+
programContext = await this.generateProgramSummary();
|
|
8637
|
+
}
|
|
8638
|
+
let dataContext = "";
|
|
8639
|
+
if (this.dataAwareProposer) {
|
|
8640
|
+
dataContext = await this.generateDataSummary();
|
|
8641
|
+
}
|
|
8642
|
+
const tips = this.tipAwareProposer ? this.generateTips() : [];
|
|
8643
|
+
for (let i = 0; i < this.numCandidates; i++) {
|
|
8644
|
+
const tipIndex = tips.length > 0 ? i % tips.length : -1;
|
|
8645
|
+
const tipToUse = tipIndex >= 0 ? tips[tipIndex] : "";
|
|
8646
|
+
const instruction = await this.generateInstruction({
|
|
8647
|
+
programContext,
|
|
8648
|
+
dataContext,
|
|
8649
|
+
tip: tipToUse,
|
|
8650
|
+
candidateIndex: i
|
|
8651
|
+
});
|
|
8652
|
+
instructions.push(instruction);
|
|
8653
|
+
}
|
|
8654
|
+
return instructions;
|
|
8655
|
+
}
|
|
8656
|
+
/**
|
|
8657
|
+
* Generates a summary of the program structure for instruction proposal
|
|
8658
|
+
*/
|
|
8659
|
+
async generateProgramSummary() {
|
|
8660
|
+
const prompt = `Summarize the following program structure. Focus on the signatures,
|
|
8661
|
+
input/output fields, and the purpose of each component. Identify key components
|
|
8662
|
+
that might benefit from better instructions.`;
|
|
8663
|
+
const programStr = JSON.stringify(this.program);
|
|
8664
|
+
const response = await this.ai.chat({
|
|
8665
|
+
chatPrompt: [
|
|
8666
|
+
{ role: "system", content: prompt },
|
|
8667
|
+
{ role: "user", content: programStr }
|
|
8668
|
+
],
|
|
8669
|
+
modelConfig: { temperature: 0.2 }
|
|
8670
|
+
});
|
|
8671
|
+
if (response instanceof ReadableStream) {
|
|
8672
|
+
return "";
|
|
8673
|
+
}
|
|
8674
|
+
return response.results[0]?.content || "";
|
|
8675
|
+
}
|
|
8676
|
+
/**
|
|
8677
|
+
* Generates a summary of the dataset for instruction proposal
|
|
8678
|
+
*/
|
|
8679
|
+
async generateDataSummary() {
|
|
8680
|
+
const sampleSize = Math.min(this.viewDataBatchSize, this.examples.length);
|
|
8681
|
+
const sample = this.examples.slice(0, sampleSize);
|
|
8682
|
+
const prompt = `Analyze the following dataset examples and provide a summary
|
|
8683
|
+
of key patterns, input-output relationships, and any specific challenges
|
|
8684
|
+
the data presents. Focus on what makes a good answer and what patterns should
|
|
8685
|
+
be followed.`;
|
|
8686
|
+
const dataStr = JSON.stringify(sample);
|
|
8687
|
+
const response = await this.ai.chat({
|
|
8688
|
+
chatPrompt: [
|
|
8689
|
+
{ role: "system", content: prompt },
|
|
8690
|
+
{ role: "user", content: dataStr }
|
|
8691
|
+
],
|
|
8692
|
+
modelConfig: { temperature: 0.2 }
|
|
8693
|
+
});
|
|
8694
|
+
if (response instanceof ReadableStream) {
|
|
8695
|
+
return "";
|
|
8696
|
+
}
|
|
8697
|
+
return response.results[0]?.content || "";
|
|
8698
|
+
}
|
|
8699
|
+
/**
|
|
8700
|
+
* Generates a specific instruction candidate
|
|
8701
|
+
*/
|
|
8702
|
+
async generateInstruction({
|
|
8703
|
+
programContext,
|
|
8704
|
+
dataContext,
|
|
8705
|
+
tip,
|
|
8706
|
+
candidateIndex
|
|
8707
|
+
}) {
|
|
8708
|
+
const prompt = `Create a high-quality instruction for an AI model performing the task described below.
|
|
8709
|
+
|
|
8710
|
+
${programContext ? `PROGRAM CONTEXT:
|
|
8711
|
+
${programContext}
|
|
8712
|
+
|
|
8713
|
+
` : ""}
|
|
8714
|
+
${dataContext ? `DATA CONTEXT:
|
|
8715
|
+
${dataContext}
|
|
8716
|
+
|
|
8717
|
+
` : ""}
|
|
8718
|
+
${tip ? `STYLE TIP: ${tip}
|
|
8719
|
+
|
|
8720
|
+
` : ""}
|
|
8721
|
+
|
|
8722
|
+
Your task is to craft a clear, effective instruction that will help the AI model generate
|
|
8723
|
+
accurate outputs for this task. Instruction #${candidateIndex + 1}/${this.numCandidates}.
|
|
8724
|
+
|
|
8725
|
+
The instruction should be detailed enough to guide the model but not overly prescriptive
|
|
8726
|
+
or restrictive. Focus on what makes a good response rather than listing exact steps.
|
|
8727
|
+
|
|
8728
|
+
INSTRUCTION:`;
|
|
8729
|
+
const response = await this.ai.chat({
|
|
8730
|
+
chatPrompt: [{ role: "user", content: prompt }],
|
|
8731
|
+
modelConfig: { temperature: 0.7 + 0.1 * candidateIndex }
|
|
8732
|
+
});
|
|
8733
|
+
if (response instanceof ReadableStream) {
|
|
8734
|
+
return "";
|
|
8735
|
+
}
|
|
8736
|
+
return response.results[0]?.content || "";
|
|
8737
|
+
}
|
|
8738
|
+
/**
|
|
8739
|
+
* Bootstraps few-shot examples for the program
|
|
8740
|
+
*/
|
|
8741
|
+
async bootstrapFewShotExamples(metricFn) {
|
|
8742
|
+
if (this.verbose) {
|
|
8743
|
+
console.log("Bootstrapping few-shot examples...");
|
|
8744
|
+
}
|
|
8745
|
+
const result = await this.bootstrapper.compile(metricFn, {
|
|
8746
|
+
maxDemos: this.maxBootstrappedDemos
|
|
8747
|
+
});
|
|
8748
|
+
return result.demos;
|
|
8749
|
+
}
|
|
8750
|
+
/**
|
|
8751
|
+
* Selects labeled examples directly from the training set
|
|
8752
|
+
*/
|
|
8753
|
+
selectLabeledExamples() {
|
|
8754
|
+
const selectedExamples = [];
|
|
8755
|
+
const indices = /* @__PURE__ */ new Set();
|
|
8756
|
+
while (indices.size < this.maxLabeledDemos && indices.size < this.examples.length) {
|
|
8757
|
+
const idx = Math.floor(Math.random() * this.examples.length);
|
|
8758
|
+
if (!indices.has(idx)) {
|
|
8759
|
+
indices.add(idx);
|
|
8760
|
+
const example = this.examples[idx];
|
|
8761
|
+
if (example) {
|
|
8762
|
+
selectedExamples.push(example);
|
|
8763
|
+
}
|
|
8764
|
+
}
|
|
8765
|
+
}
|
|
8766
|
+
return selectedExamples;
|
|
8767
|
+
}
|
|
8768
|
+
/**
|
|
8769
|
+
* Runs Bayesian optimization to find the best combination of few-shot examples and instructions
|
|
8770
|
+
*/
|
|
8771
|
+
async runBayesianOptimization(bootstrappedDemos, labeledExamples, instructions, valset, metricFn) {
|
|
8772
|
+
let bestConfig = null;
|
|
8773
|
+
let bestScore = Number.NEGATIVE_INFINITY;
|
|
8774
|
+
const evaluatedConfigs = [];
|
|
8775
|
+
const defaultConfig = {
|
|
8776
|
+
instruction: instructions[0] || "",
|
|
8777
|
+
bootstrappedDemos: Math.min(1, bootstrappedDemos.length),
|
|
8778
|
+
labeledExamples: Math.min(1, labeledExamples.length)
|
|
8779
|
+
};
|
|
8780
|
+
let trialsWithoutImprovement = 0;
|
|
8781
|
+
let lastBestScore = Number.NEGATIVE_INFINITY;
|
|
8782
|
+
const initialExplorationTrials = Math.min(
|
|
8783
|
+
10,
|
|
8784
|
+
Math.floor(this.numTrials / 3)
|
|
8785
|
+
);
|
|
8786
|
+
const configs = [];
|
|
8787
|
+
for (let i = 0; i < initialExplorationTrials; i++) {
|
|
8788
|
+
const instructionIndex = Math.floor(Math.random() * instructions.length);
|
|
8789
|
+
const instructionValue = instructions[instructionIndex] || "";
|
|
8790
|
+
const config = {
|
|
8791
|
+
instruction: instructionValue,
|
|
8792
|
+
bootstrappedDemos: Math.floor(
|
|
8793
|
+
Math.random() * (bootstrappedDemos.length + 1)
|
|
8794
|
+
),
|
|
8795
|
+
labeledExamples: Math.floor(
|
|
8796
|
+
Math.random() * (labeledExamples.length + 1)
|
|
8797
|
+
)
|
|
8798
|
+
};
|
|
8799
|
+
configs.push(config);
|
|
8800
|
+
}
|
|
8801
|
+
for (let i = 0; i < configs.length; i++) {
|
|
8802
|
+
const config = configs[i];
|
|
8803
|
+
if (!config) continue;
|
|
8804
|
+
const score = await this.evaluateConfig(
|
|
8805
|
+
config,
|
|
8806
|
+
bootstrappedDemos,
|
|
8807
|
+
labeledExamples,
|
|
8808
|
+
valset,
|
|
8809
|
+
metricFn,
|
|
8810
|
+
i
|
|
8811
|
+
);
|
|
8812
|
+
evaluatedConfigs.push({ config, score });
|
|
8813
|
+
if (score > bestScore) {
|
|
8814
|
+
bestScore = score;
|
|
8815
|
+
bestConfig = config;
|
|
8816
|
+
if (this.verbose) {
|
|
8817
|
+
console.log(
|
|
8818
|
+
`New best configuration found with score ${bestScore} (exploration phase)`
|
|
8819
|
+
);
|
|
8820
|
+
}
|
|
8821
|
+
}
|
|
8822
|
+
updateProgressBar(
|
|
8823
|
+
i + 1,
|
|
8824
|
+
this.numTrials,
|
|
8825
|
+
Math.round(bestScore * 100),
|
|
8826
|
+
0,
|
|
8827
|
+
"Running MIPROv2 optimization",
|
|
8828
|
+
30
|
|
8829
|
+
);
|
|
8830
|
+
}
|
|
8831
|
+
for (let i = configs.length; i < this.numTrials; i++) {
|
|
8832
|
+
const nextConfig = this.selectNextConfiguration(
|
|
8833
|
+
evaluatedConfigs,
|
|
8834
|
+
bootstrappedDemos.length,
|
|
8835
|
+
labeledExamples.length,
|
|
8836
|
+
instructions
|
|
8837
|
+
);
|
|
8838
|
+
const score = await this.evaluateConfig(
|
|
8839
|
+
nextConfig,
|
|
8840
|
+
bootstrappedDemos,
|
|
8841
|
+
labeledExamples,
|
|
8842
|
+
valset,
|
|
8843
|
+
metricFn,
|
|
8844
|
+
i
|
|
8845
|
+
);
|
|
8846
|
+
evaluatedConfigs.push({ config: nextConfig, score });
|
|
8847
|
+
if (score > bestScore) {
|
|
8848
|
+
bestScore = score;
|
|
8849
|
+
bestConfig = nextConfig;
|
|
8850
|
+
if (this.verbose) {
|
|
8851
|
+
console.log(
|
|
8852
|
+
`New best configuration found with score ${bestScore} (exploitation phase)`
|
|
8853
|
+
);
|
|
8854
|
+
}
|
|
8855
|
+
trialsWithoutImprovement = 0;
|
|
8856
|
+
lastBestScore = bestScore;
|
|
8857
|
+
} else {
|
|
8858
|
+
if (bestScore - lastBestScore < this.minImprovementThreshold) {
|
|
8859
|
+
trialsWithoutImprovement++;
|
|
8860
|
+
if (trialsWithoutImprovement >= this.earlyStoppingTrials) {
|
|
8861
|
+
if (this.verbose) {
|
|
8862
|
+
console.log(
|
|
8863
|
+
`Early stopping triggered after ${i + 1} trials. No improvement for ${trialsWithoutImprovement} trials.`
|
|
8864
|
+
);
|
|
8865
|
+
}
|
|
8866
|
+
break;
|
|
8867
|
+
}
|
|
8868
|
+
} else {
|
|
8869
|
+
lastBestScore = bestScore;
|
|
8870
|
+
trialsWithoutImprovement = 0;
|
|
8871
|
+
}
|
|
8872
|
+
}
|
|
8873
|
+
updateProgressBar(
|
|
8874
|
+
i + 1,
|
|
8875
|
+
this.numTrials,
|
|
8876
|
+
Math.round(bestScore * 100),
|
|
8877
|
+
0,
|
|
8878
|
+
"Running MIPROv2 optimization",
|
|
8879
|
+
30
|
|
8880
|
+
);
|
|
8881
|
+
if (this.minibatch && i > 0 && (i + 1) % this.minibatchFullEvalSteps === 0 && bestConfig) {
|
|
8882
|
+
if (this.verbose) {
|
|
8883
|
+
console.log(
|
|
8884
|
+
`Running full evaluation on best configuration at trial ${i + 1}`
|
|
8885
|
+
);
|
|
8886
|
+
}
|
|
8887
|
+
const fullScore = await this.fullEvaluation(
|
|
8888
|
+
bestConfig,
|
|
8889
|
+
bootstrappedDemos,
|
|
8890
|
+
labeledExamples,
|
|
8891
|
+
valset,
|
|
8892
|
+
metricFn
|
|
8893
|
+
);
|
|
8894
|
+
if (this.verbose) {
|
|
8895
|
+
console.log(`Full evaluation score: ${fullScore}`);
|
|
8896
|
+
}
|
|
8897
|
+
bestScore = fullScore;
|
|
8898
|
+
}
|
|
8899
|
+
}
|
|
8900
|
+
if (!bestConfig) {
|
|
8901
|
+
if (this.verbose) {
|
|
8902
|
+
console.warn(
|
|
8903
|
+
"Optimization failed to find any valid configurations, using default fallback configuration"
|
|
8904
|
+
);
|
|
8905
|
+
}
|
|
8906
|
+
bestConfig = defaultConfig;
|
|
8907
|
+
try {
|
|
8908
|
+
bestScore = await this.evaluateConfig(
|
|
8909
|
+
bestConfig,
|
|
8910
|
+
bootstrappedDemos,
|
|
8911
|
+
labeledExamples,
|
|
8912
|
+
valset,
|
|
8913
|
+
metricFn,
|
|
8914
|
+
this.numTrials - 1
|
|
8915
|
+
);
|
|
8916
|
+
} catch (err) {
|
|
8917
|
+
if (this.verbose) {
|
|
8918
|
+
console.error("Error evaluating default configuration:", err);
|
|
8919
|
+
}
|
|
8920
|
+
bestScore = 0;
|
|
8921
|
+
}
|
|
8922
|
+
}
|
|
8923
|
+
return { bestConfig, bestScore };
|
|
8924
|
+
}
|
|
8925
|
+
/**
|
|
8926
|
+
* Evaluates a configuration on the validation set
|
|
8927
|
+
*/
|
|
8928
|
+
async evaluateConfig(config, bootstrappedDemos, labeledExamples, valset, metricFn, trialIndex) {
|
|
8929
|
+
this.applyConfigToProgram(
|
|
8930
|
+
this.program,
|
|
8931
|
+
config,
|
|
8932
|
+
bootstrappedDemos,
|
|
8933
|
+
labeledExamples
|
|
8934
|
+
);
|
|
8935
|
+
let evalSet = valset;
|
|
8936
|
+
if (this.minibatch) {
|
|
8937
|
+
const startIdx = trialIndex * this.minibatchSize % valset.length;
|
|
8938
|
+
const minibatchEvalSet = [];
|
|
8939
|
+
for (let j = 0; j < this.minibatchSize; j++) {
|
|
8940
|
+
const idx = (startIdx + j) % valset.length;
|
|
8941
|
+
const example = valset[idx];
|
|
8942
|
+
if (example) {
|
|
8943
|
+
minibatchEvalSet.push(example);
|
|
8944
|
+
}
|
|
8945
|
+
}
|
|
8946
|
+
evalSet = minibatchEvalSet;
|
|
8947
|
+
}
|
|
8948
|
+
let correctCount = 0;
|
|
8949
|
+
for (const example of evalSet) {
|
|
8950
|
+
try {
|
|
8951
|
+
const prediction = await this.program.forward(this.ai, example);
|
|
8952
|
+
const correct = metricFn({ prediction, example });
|
|
8953
|
+
if (correct) correctCount++;
|
|
8954
|
+
} catch (err) {
|
|
8955
|
+
if (this.verbose) {
|
|
8956
|
+
console.error("Error evaluating example:", err);
|
|
8957
|
+
}
|
|
8958
|
+
}
|
|
8959
|
+
}
|
|
8960
|
+
return correctCount / evalSet.length;
|
|
8961
|
+
}
|
|
8962
|
+
/**
|
|
8963
|
+
* Run full evaluation on the entire validation set
|
|
8964
|
+
*/
|
|
8965
|
+
async fullEvaluation(config, bootstrappedDemos, labeledExamples, valset, metricFn) {
|
|
8966
|
+
this.applyConfigToProgram(
|
|
8967
|
+
this.program,
|
|
8968
|
+
config,
|
|
8969
|
+
bootstrappedDemos,
|
|
8970
|
+
labeledExamples
|
|
8971
|
+
);
|
|
8972
|
+
let fullCorrectCount = 0;
|
|
8973
|
+
for (const example of valset) {
|
|
8974
|
+
try {
|
|
8975
|
+
const prediction = await this.program.forward(this.ai, example);
|
|
8976
|
+
const correct = metricFn({ prediction, example });
|
|
8977
|
+
if (correct) fullCorrectCount++;
|
|
8978
|
+
} catch (err) {
|
|
8979
|
+
if (this.verbose) {
|
|
8980
|
+
console.error("Error evaluating example:", err);
|
|
8981
|
+
}
|
|
8982
|
+
}
|
|
8983
|
+
}
|
|
8984
|
+
return fullCorrectCount / valset.length;
|
|
8985
|
+
}
|
|
8986
|
+
/**
|
|
8987
|
+
* Implements a Bayesian-inspired selection of the next configuration to try
|
|
8988
|
+
* This is a simplified version using Upper Confidence Bound (UCB) strategy
|
|
8989
|
+
*/
|
|
8990
|
+
selectNextConfiguration(evaluatedConfigs, maxBootstrappedDemos, maxLabeledExamples, instructions) {
|
|
8991
|
+
if (evaluatedConfigs.length < 5) {
|
|
8992
|
+
const instructionIndex = Math.floor(Math.random() * instructions.length);
|
|
8993
|
+
return {
|
|
8994
|
+
instruction: instructions[instructionIndex] || "",
|
|
8995
|
+
bootstrappedDemos: Math.floor(
|
|
8996
|
+
Math.random() * (maxBootstrappedDemos + 1)
|
|
8997
|
+
),
|
|
8998
|
+
labeledExamples: Math.floor(Math.random() * (maxLabeledExamples + 1))
|
|
8999
|
+
};
|
|
9000
|
+
}
|
|
9001
|
+
const sortedConfigs = [...evaluatedConfigs].sort(
|
|
9002
|
+
(a, b) => b.score - a.score
|
|
9003
|
+
);
|
|
9004
|
+
const topConfigs = sortedConfigs.slice(0, Math.min(3, sortedConfigs.length));
|
|
9005
|
+
const meanBootstrappedDemos = topConfigs.reduce((sum, c) => sum + c.config.bootstrappedDemos, 0) / topConfigs.length;
|
|
9006
|
+
const meanLabeledExamples = topConfigs.reduce((sum, c) => sum + c.config.labeledExamples, 0) / topConfigs.length;
|
|
9007
|
+
const popularInstructions = topConfigs.map((c) => c.config.instruction);
|
|
9008
|
+
const explorationFactor = Math.max(
|
|
9009
|
+
0.2,
|
|
9010
|
+
1 - evaluatedConfigs.length / this.numTrials
|
|
9011
|
+
);
|
|
9012
|
+
let newBootstrappedDemos;
|
|
9013
|
+
let newLabeledExamples;
|
|
9014
|
+
let newInstruction;
|
|
9015
|
+
if (Math.random() < 0.7) {
|
|
9016
|
+
newBootstrappedDemos = Math.min(
|
|
9017
|
+
maxBootstrappedDemos,
|
|
9018
|
+
Math.max(
|
|
9019
|
+
0,
|
|
9020
|
+
Math.round(
|
|
9021
|
+
meanBootstrappedDemos + (Math.random() * 2 - 1) * explorationFactor * 2
|
|
9022
|
+
)
|
|
9023
|
+
)
|
|
9024
|
+
);
|
|
9025
|
+
} else {
|
|
9026
|
+
newBootstrappedDemos = Math.floor(
|
|
9027
|
+
Math.random() * (maxBootstrappedDemos + 1)
|
|
9028
|
+
);
|
|
9029
|
+
}
|
|
9030
|
+
if (Math.random() < 0.7) {
|
|
9031
|
+
newLabeledExamples = Math.min(
|
|
9032
|
+
maxLabeledExamples,
|
|
9033
|
+
Math.max(
|
|
9034
|
+
0,
|
|
9035
|
+
Math.round(
|
|
9036
|
+
meanLabeledExamples + (Math.random() * 2 - 1) * explorationFactor * 2
|
|
9037
|
+
)
|
|
9038
|
+
)
|
|
9039
|
+
);
|
|
9040
|
+
} else {
|
|
9041
|
+
newLabeledExamples = Math.floor(Math.random() * (maxLabeledExamples + 1));
|
|
9042
|
+
}
|
|
9043
|
+
if (Math.random() < 0.7 && popularInstructions.length > 0) {
|
|
9044
|
+
const idx = Math.floor(Math.random() * popularInstructions.length);
|
|
9045
|
+
newInstruction = popularInstructions[idx] || "";
|
|
9046
|
+
} else {
|
|
9047
|
+
const idx = Math.floor(Math.random() * instructions.length);
|
|
9048
|
+
newInstruction = instructions[idx] || "";
|
|
9049
|
+
}
|
|
9050
|
+
return {
|
|
9051
|
+
instruction: newInstruction,
|
|
9052
|
+
bootstrappedDemos: newBootstrappedDemos,
|
|
9053
|
+
labeledExamples: newLabeledExamples
|
|
9054
|
+
};
|
|
9055
|
+
}
|
|
9056
|
+
/**
|
|
9057
|
+
* Applies a configuration to a program instance
|
|
9058
|
+
*/
|
|
9059
|
+
applyConfigToProgram(program, config, bootstrappedDemos, labeledExamples) {
|
|
9060
|
+
this.setInstructionToProgram(program, config.instruction);
|
|
9061
|
+
if (config.bootstrappedDemos > 0) {
|
|
9062
|
+
program.setDemos(bootstrappedDemos.slice(0, config.bootstrappedDemos));
|
|
9063
|
+
}
|
|
9064
|
+
if (config.labeledExamples > 0) {
|
|
9065
|
+
program.setExamples(labeledExamples.slice(0, config.labeledExamples));
|
|
9066
|
+
}
|
|
9067
|
+
}
|
|
9068
|
+
/**
|
|
9069
|
+
* Sets instruction to a program
|
|
9070
|
+
* Note: Workaround since setInstruction may not be available directly
|
|
9071
|
+
*/
|
|
9072
|
+
setInstructionToProgram(program, instruction) {
|
|
9073
|
+
const programWithInstruction = program;
|
|
9074
|
+
programWithInstruction.setInstruction?.(instruction);
|
|
9075
|
+
}
|
|
9076
|
+
/**
|
|
9077
|
+
* The main compile method to run MIPROv2 optimization
|
|
9078
|
+
* @param metricFn Evaluation metric function
|
|
9079
|
+
* @param options Optional configuration options
|
|
9080
|
+
* @returns The optimized program
|
|
9081
|
+
*/
|
|
9082
|
+
async compile(metricFn, options) {
|
|
9083
|
+
if (options?.auto) {
|
|
9084
|
+
this.configureAuto(options.auto);
|
|
9085
|
+
}
|
|
9086
|
+
const trainset = this.examples;
|
|
9087
|
+
const valset = options?.valset || this.examples.slice(0, Math.floor(this.examples.length * 0.8));
|
|
9088
|
+
if (this.verbose) {
|
|
9089
|
+
console.log(`Starting MIPROv2 optimization with ${this.numTrials} trials`);
|
|
9090
|
+
console.log(
|
|
9091
|
+
`Using ${trainset.length} examples for training and ${valset.length} for validation`
|
|
9092
|
+
);
|
|
9093
|
+
}
|
|
9094
|
+
if (options?.teacher) {
|
|
9095
|
+
if (this.verbose) {
|
|
9096
|
+
console.log("Using provided teacher to assist with bootstrapping");
|
|
9097
|
+
}
|
|
9098
|
+
const bootstrapperWithTeacher = new AxBootstrapFewShot({
|
|
9099
|
+
ai: this.ai,
|
|
9100
|
+
program: this.program,
|
|
9101
|
+
examples: this.examples,
|
|
9102
|
+
options: {
|
|
9103
|
+
maxDemos: this.maxBootstrappedDemos,
|
|
9104
|
+
maxRounds: 3,
|
|
9105
|
+
verboseMode: this.verbose,
|
|
9106
|
+
teacherAI: this.ai
|
|
9107
|
+
// Use the same AI but with the teacher program
|
|
9108
|
+
}
|
|
9109
|
+
});
|
|
9110
|
+
this.bootstrapper = bootstrapperWithTeacher;
|
|
9111
|
+
}
|
|
9112
|
+
let bootstrappedDemos = [];
|
|
9113
|
+
if (this.maxBootstrappedDemos > 0) {
|
|
9114
|
+
bootstrappedDemos = await this.bootstrapFewShotExamples(metricFn);
|
|
9115
|
+
if (this.verbose) {
|
|
9116
|
+
console.log(
|
|
9117
|
+
`Generated ${bootstrappedDemos.length} bootstrapped demonstrations`
|
|
9118
|
+
);
|
|
9119
|
+
}
|
|
9120
|
+
}
|
|
9121
|
+
let labeledExamples = [];
|
|
9122
|
+
if (this.maxLabeledDemos > 0) {
|
|
9123
|
+
labeledExamples = this.selectLabeledExamples();
|
|
9124
|
+
if (this.verbose) {
|
|
9125
|
+
console.log(
|
|
9126
|
+
`Selected ${labeledExamples.length} labeled examples from training set`
|
|
9127
|
+
);
|
|
9128
|
+
}
|
|
9129
|
+
}
|
|
9130
|
+
const instructions = await this.proposeInstructionCandidates();
|
|
9131
|
+
if (this.verbose) {
|
|
9132
|
+
console.log(`Generated ${instructions.length} instruction candidates`);
|
|
9133
|
+
}
|
|
9134
|
+
const { bestConfig, bestScore } = await this.runBayesianOptimization(
|
|
9135
|
+
bootstrappedDemos,
|
|
9136
|
+
labeledExamples,
|
|
9137
|
+
instructions,
|
|
9138
|
+
valset,
|
|
9139
|
+
metricFn
|
|
9140
|
+
);
|
|
9141
|
+
if (this.verbose) {
|
|
9142
|
+
console.log(`Optimization complete. Best score: ${bestScore}`);
|
|
9143
|
+
console.log(`Best configuration: ${JSON.stringify(bestConfig)}`);
|
|
9144
|
+
}
|
|
9145
|
+
this.applyConfigToProgram(
|
|
9146
|
+
this.program,
|
|
9147
|
+
bestConfig,
|
|
9148
|
+
bootstrappedDemos,
|
|
9149
|
+
labeledExamples
|
|
9150
|
+
);
|
|
9151
|
+
return this.program;
|
|
9152
|
+
}
|
|
9153
|
+
};
|
|
9154
|
+
|
|
8353
9155
|
// ai/mock/api.ts
|
|
8354
9156
|
var AxMockAIService = class {
|
|
8355
9157
|
constructor(config = {}) {
|
|
@@ -10527,6 +11329,7 @@ var AxRAG = class extends AxChainOfThought {
|
|
|
10527
11329
|
AxMCPHTTPTransport,
|
|
10528
11330
|
AxMCPStdioTransport,
|
|
10529
11331
|
AxMemory,
|
|
11332
|
+
AxMiPRO,
|
|
10530
11333
|
AxMockAIService,
|
|
10531
11334
|
AxMultiServiceRouter,
|
|
10532
11335
|
AxProgram,
|