textopt 0.0.0 → 0.2.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/README.md +65 -25
- package/dist/bootstrap-search/index.cjs +159 -73
- package/dist/bootstrap-search/index.d.cts +32 -10
- package/dist/bootstrap-search/index.d.mts +32 -10
- package/dist/bootstrap-search/index.mjs +150 -66
- package/dist/demos-9v5ts7F3.cjs +244 -0
- package/dist/{demos-B0pVQjYC.d.mts → demos-ASsSXYXA.d.mts} +10 -3
- package/dist/demos-Brobjfuc.mjs +215 -0
- package/dist/{demos-BTuzFNsp.d.cts → demos-ByaLZy-Z.d.cts} +10 -3
- package/dist/file-cache.cjs +27 -8
- package/dist/file-cache.d.cts +13 -0
- package/dist/file-cache.d.mts +13 -0
- package/dist/file-cache.mjs +27 -8
- package/dist/gepa/index.cjs +128 -80
- package/dist/gepa/index.d.cts +15 -7
- package/dist/gepa/index.d.mts +15 -7
- package/dist/gepa/index.mjs +101 -55
- package/dist/index.cjs +157 -30
- package/dist/index.d.cts +177 -7
- package/dist/index.d.mts +177 -7
- package/dist/index.mjs +139 -18
- package/dist/{math-COOofUyv.cjs → math-BhlziRPc.cjs} +60 -9
- package/dist/math-Dqme4rYz.mjs +123 -0
- package/dist/mipro/index.cjs +104 -70
- package/dist/mipro/index.d.cts +17 -14
- package/dist/mipro/index.d.mts +17 -14
- package/dist/mipro/index.mjs +90 -58
- package/dist/opro/index.cjs +136 -51
- package/dist/opro/index.d.cts +17 -9
- package/dist/opro/index.d.mts +17 -9
- package/dist/opro/index.mjs +121 -38
- package/dist/{optimizer-B7SpRwl7.d.cts → optimizer-4Zv-Zt2t.d.cts} +90 -5
- package/dist/{optimizer-DqCoth_w.d.mts → optimizer-Ds5mzYjz.d.mts} +90 -5
- package/dist/random-search/index.cjs +99 -49
- package/dist/random-search/index.d.cts +15 -13
- package/dist/random-search/index.d.mts +15 -13
- package/dist/random-search/index.mjs +89 -41
- package/dist/{reflection-Cr_upzU0.d.mts → reflection-CMezGu6u.d.mts} +38 -14
- package/dist/{reflection-CQToe-5B.d.cts → reflection-D0A7eahD.d.cts} +38 -14
- package/dist/reporting-bq007_2z.d.cts +294 -0
- package/dist/reporting-bq007_2z.d.mts +294 -0
- package/dist/simba/index.cjs +216 -83
- package/dist/simba/index.d.cts +53 -13
- package/dist/simba/index.d.mts +53 -13
- package/dist/simba/index.mjs +206 -75
- package/dist/testing.cjs +1 -0
- package/dist/testing.d.cts +5 -3
- package/dist/testing.d.mts +5 -3
- package/dist/testing.mjs +1 -1
- package/dist/{evaluation-OZOp6TB7.cjs → warnings-CWRJF-jA.cjs} +228 -5
- package/dist/{evaluation-BV0nSZVx.mjs → warnings-OxvDi9kN.mjs} +175 -6
- package/docs/adapters.md +169 -0
- package/docs/benchmark.md +90 -0
- package/docs/data-prep.md +113 -0
- package/docs/distillation.md +128 -0
- package/docs/evaluation.md +87 -0
- package/docs/metric-preflight.md +132 -0
- package/docs/optimizers.md +293 -0
- package/docs/tuning.md +130 -0
- package/package.json +6 -4
- package/dist/demos-B9BJiNKz.cjs +0 -143
- package/dist/demos-Degx6UmP.mjs +0 -126
- package/dist/math-DhrDmpFS.mjs +0 -78
- package/dist/types-CWv4IQFF.d.cts +0 -129
- package/dist/types-CWv4IQFF.d.mts +0 -129
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as UsageTotals, _ as EvaluationPhase, c as RunWarning, f as Adapter, h as EvaluationBatch, p as Candidate, v as EvaluationSplit } from "./reporting-bq007_2z.mjs";
|
|
2
2
|
import { n as EvaluationCache, t as CachedScore } from "./cache-CuSo0NJ8.mjs";
|
|
3
3
|
//#region src/budget.d.ts
|
|
4
4
|
interface Budget {
|
|
@@ -106,8 +106,24 @@ interface Evaluator<Datum, Trajectory, Output, K extends string> {
|
|
|
106
106
|
cacheHits(): number;
|
|
107
107
|
/** Rollouts made with `charge: false`, tracked apart from the budget. */
|
|
108
108
|
unchargedCalls(): number;
|
|
109
|
-
/**
|
|
109
|
+
/**
|
|
110
|
+
* Tokens and money the search has spent, as far as adapters have reported
|
|
111
|
+
* it. `maxCostUsd` is checked against this, so what the ceiling does not
|
|
112
|
+
* bound is not counted in it: rollouts made with `charge: false` are in
|
|
113
|
+
* `unchargedUsage` instead.
|
|
114
|
+
*/
|
|
110
115
|
usage(): UsageTotals;
|
|
116
|
+
/**
|
|
117
|
+
* What the rollouts made with `charge: false` cost. Held-out measurement is
|
|
118
|
+
* taken after the search has stopped, so no ceiling bounds it and reporting
|
|
119
|
+
* it inside `usage` would describe a run as having overrun one.
|
|
120
|
+
*/
|
|
121
|
+
unchargedUsage(): UsageTotals;
|
|
122
|
+
/**
|
|
123
|
+
* Folds in usage spent outside this evaluator — harvesting runs its own, and
|
|
124
|
+
* a cost ceiling that cannot see it bounds only part of the run.
|
|
125
|
+
*/
|
|
126
|
+
absorbUsage(spent: UsageTotals): void;
|
|
111
127
|
/** Cache contents for checkpointing, when the cache can enumerate them. */
|
|
112
128
|
entries(): [string, CachedScore][] | undefined;
|
|
113
129
|
restore(entries: Iterable<readonly [string, CachedScore]>): void;
|
|
@@ -140,6 +156,12 @@ declare function createEvaluator<Datum, Trajectory, Output, K extends string>(ar
|
|
|
140
156
|
signal?: AbortSignal;
|
|
141
157
|
/** Resumed counters, so a continued run reports totals rather than deltas. */
|
|
142
158
|
cacheHits?: number;
|
|
159
|
+
/**
|
|
160
|
+
* Usage the interrupted run had already spent. Without it `maxCostUsd` is a
|
|
161
|
+
* ceiling on the segment rather than on the run, and resuming repeatedly
|
|
162
|
+
* spends it again each time.
|
|
163
|
+
*/
|
|
164
|
+
usage?: UsageTotals;
|
|
143
165
|
/**
|
|
144
166
|
* Rate limits and 5xx responses are the common case in a long run, and a
|
|
145
167
|
* transient row costs the instance whichever optimizer is driving: it is
|
|
@@ -192,8 +214,28 @@ declare function requireMeasuredMean(args: {
|
|
|
192
214
|
*/
|
|
193
215
|
interface OptimizerTask<Datum, Trajectory = unknown, Output = unknown, K extends string = string> {
|
|
194
216
|
seedCandidate: Candidate<K>;
|
|
217
|
+
/**
|
|
218
|
+
* Instances the search draws evidence from. Reflective optimizers mine these
|
|
219
|
+
* for what a candidate got wrong, so a training row earns its place by being
|
|
220
|
+
* diagnostic — a row every candidate already passes teaches the rewriter
|
|
221
|
+
* nothing.
|
|
222
|
+
*
|
|
223
|
+
* @see docs/data-prep.md
|
|
224
|
+
*/
|
|
195
225
|
trainingSet: readonly Datum[];
|
|
196
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Instances the search selects candidates against. Defaults to
|
|
228
|
+
* `trainingSet`, which is the right default for a first run and the wrong
|
|
229
|
+
* number to report from one — the result carries a warning saying so.
|
|
230
|
+
* `"reuseTraining"` is that same default with the caller's name on it, and
|
|
231
|
+
* carries no warning.
|
|
232
|
+
*
|
|
233
|
+
* Split by group rather than by row: near-duplicate instances that straddle
|
|
234
|
+
* the boundary leak, and the run reports a score nothing earned.
|
|
235
|
+
*
|
|
236
|
+
* @see docs/data-prep.md
|
|
237
|
+
*/
|
|
238
|
+
validationSet?: readonly Datum[] | "reuseTraining";
|
|
197
239
|
/**
|
|
198
240
|
* `NoInfer` keeps the adapter out of `K`'s inference: an adapter built by a
|
|
199
241
|
* factory knows nothing about component names, and one inference candidate of
|
|
@@ -207,6 +249,18 @@ interface OptimizerTask<Datum, Trajectory = unknown, Output = unknown, K extends
|
|
|
207
249
|
* number in a result that no candidate was ever selected against.
|
|
208
250
|
*/
|
|
209
251
|
testSet?: readonly Datum[];
|
|
252
|
+
/**
|
|
253
|
+
* Scored rollouts the search may spend. Cache hits do not count, and test
|
|
254
|
+
* rollouts are outside it entirely.
|
|
255
|
+
*
|
|
256
|
+
* Spending it is only worth anything if the metric separates candidates
|
|
257
|
+
* first: a metric that scores every candidate alike turns the whole budget
|
|
258
|
+
* into ranked ties, and the run reports a stop reason that looks like any
|
|
259
|
+
* other.
|
|
260
|
+
*
|
|
261
|
+
* @see docs/metric-preflight.md
|
|
262
|
+
* @see docs/tuning.md
|
|
263
|
+
*/
|
|
210
264
|
maxMetricCalls: number;
|
|
211
265
|
/**
|
|
212
266
|
* Dollars the run may spend, as reported by the adapter's usage. Checked
|
|
@@ -252,8 +306,25 @@ interface OptimizerResult<K extends string, Stop extends string, Output = unknow
|
|
|
252
306
|
bestOutputs?: (Output | undefined)[];
|
|
253
307
|
metricCalls: number;
|
|
254
308
|
/**
|
|
255
|
-
*
|
|
256
|
-
*
|
|
309
|
+
* Rollouts served from the cache rather than charged to `metricCalls`. Every
|
|
310
|
+
* optimizer here caches by default, so the same `maxMetricCalls` can buy a
|
|
311
|
+
* search that revisits scored candidates a longer effective run than one
|
|
312
|
+
* that never does — a comparison over `metricCalls` alone hides that. Zero
|
|
313
|
+
* for a run with caching disabled.
|
|
314
|
+
*/
|
|
315
|
+
cacheHits: number;
|
|
316
|
+
/**
|
|
317
|
+
* Calls made to a proposal or reflection model, which no metric budget
|
|
318
|
+
* covers — see each optimizer's own accounting for what a call costs there.
|
|
319
|
+
* Absent from a search that proposes nothing of its own: bootstrap search
|
|
320
|
+
* only accepts or rejects rollouts the metric already scored.
|
|
321
|
+
*/
|
|
322
|
+
reflectionCalls?: number;
|
|
323
|
+
/**
|
|
324
|
+
* Tokens and dollars the search spent, summed from what the adapter reported.
|
|
325
|
+
* Zero throughout when the adapter reports no usage. `maxCostUsd` is checked
|
|
326
|
+
* against this, so the held-out sweep — which runs after the search has
|
|
327
|
+
* stopped, under no ceiling — is reported apart from it, in `testUsage`.
|
|
257
328
|
*/
|
|
258
329
|
usage: UsageTotals;
|
|
259
330
|
/**
|
|
@@ -267,7 +338,21 @@ interface OptimizerResult<K extends string, Stop extends string, Output = unknow
|
|
|
267
338
|
* measurement rather than search, and so is not charged to `maxMetricCalls`.
|
|
268
339
|
*/
|
|
269
340
|
testMetricCalls?: number;
|
|
341
|
+
/**
|
|
342
|
+
* Tokens and dollars the held-out sweep cost, for the same reason: no ceiling
|
|
343
|
+
* bounds it, so a caller adding up what a run spent has to see it as its own
|
|
344
|
+
* number rather than find it folded into one `maxCostUsd` was supposed to
|
|
345
|
+
* hold. Absent when no testSet was given.
|
|
346
|
+
*/
|
|
347
|
+
testUsage?: UsageTotals;
|
|
270
348
|
stopReason: Stop;
|
|
349
|
+
/**
|
|
350
|
+
* What this run cannot say about itself from its own numbers — selection
|
|
351
|
+
* that reused the training instances, a seed the metric could not separate.
|
|
352
|
+
* Empty when there is nothing to say. Never fatal, and repeated on the
|
|
353
|
+
* `finish` event so a reporter sees them next to the score.
|
|
354
|
+
*/
|
|
355
|
+
warnings: RunWarning[];
|
|
271
356
|
}
|
|
272
357
|
/**
|
|
273
358
|
* An optimizer: a task in, the best candidate it found out. Exactly one method.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
2
|
+
const require_warnings = require("../warnings-CWRJF-jA.cjs");
|
|
3
3
|
const require_concurrency = require("../concurrency-C-cFzWW2.cjs");
|
|
4
4
|
const require_text = require("../text-CK_HB3su.cjs");
|
|
5
5
|
//#region src/random-search/optimize.ts
|
|
@@ -33,10 +33,14 @@ var RandomSearchOptimizer = class {
|
|
|
33
33
|
this.#config = config;
|
|
34
34
|
}
|
|
35
35
|
async optimize(task) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
try {
|
|
37
|
+
return await runRandomSearch({
|
|
38
|
+
config: this.#config,
|
|
39
|
+
task
|
|
40
|
+
});
|
|
41
|
+
} finally {
|
|
42
|
+
await require_warnings.flushReporters(task.reporters ?? []);
|
|
43
|
+
}
|
|
40
44
|
}
|
|
41
45
|
};
|
|
42
46
|
/**
|
|
@@ -63,9 +67,14 @@ function buildParaphrasePrompt(args) {
|
|
|
63
67
|
async function runRandomSearch(args) {
|
|
64
68
|
const { config, task } = args;
|
|
65
69
|
const { variants = DEFAULT_VARIANTS, concurrency = 1, maxRounds = Number.POSITIVE_INFINITY, buildPrompt = buildParaphrasePrompt, trackBestOutputs = false, checkpointCache = true } = config;
|
|
66
|
-
const { seedCandidate, trainingSet, validationSet
|
|
67
|
-
const
|
|
68
|
-
|
|
70
|
+
const { seedCandidate, trainingSet, validationSet: requestedValidationSet, testSet, adapter, reflect, maxMetricCalls, cache, cacheNamespace, retry, maxCostUsd, maxWallClockMs, instanceId = require_warnings.defaultInstanceId, reporters = [], onCheckpoint, resumeFrom, signal } = task;
|
|
71
|
+
const { validationSet, warnings } = require_warnings.resolveValidationSet({
|
|
72
|
+
validationSet: requestedValidationSet,
|
|
73
|
+
trainingSet
|
|
74
|
+
});
|
|
75
|
+
const emit = require_warnings.createEmitter(reporters);
|
|
76
|
+
const deadline = require_warnings.createDeadline({ maxWallClockMs });
|
|
77
|
+
const components = require_warnings.componentNames(seedCandidate);
|
|
69
78
|
if (trainingSet.length === 0) throw new Error("optimize requires a non-empty trainingSet");
|
|
70
79
|
if (validationSet.length === 0) throw new Error("optimize requires a non-empty validationSet");
|
|
71
80
|
if (components.length === 0) throw new Error("optimize requires a seed candidate with at least one component");
|
|
@@ -78,7 +87,7 @@ async function runRandomSearch(args) {
|
|
|
78
87
|
datum,
|
|
79
88
|
index
|
|
80
89
|
})) ?? [];
|
|
81
|
-
const fingerprint =
|
|
90
|
+
const fingerprint = require_warnings.runFingerprint({
|
|
82
91
|
seedCandidate,
|
|
83
92
|
trainingIds: trainingSet.map((datum, index) => instanceId({
|
|
84
93
|
datum,
|
|
@@ -87,16 +96,16 @@ async function runRandomSearch(args) {
|
|
|
87
96
|
validationIds,
|
|
88
97
|
...cacheNamespace === void 0 ? {} : { cacheNamespace }
|
|
89
98
|
});
|
|
90
|
-
|
|
99
|
+
require_warnings.assertResumable({
|
|
91
100
|
fingerprint,
|
|
92
101
|
...resumeFrom === void 0 ? {} : { snapshot: resumeFrom }
|
|
93
102
|
});
|
|
94
|
-
const budget =
|
|
103
|
+
const budget = require_warnings.createBudget({
|
|
95
104
|
maxMetricCalls,
|
|
96
105
|
spent: resumeFrom?.metricCalls ?? 0
|
|
97
106
|
});
|
|
98
|
-
const evaluationCache = cache === false ? void 0 : cache ??
|
|
99
|
-
const evaluator =
|
|
107
|
+
const evaluationCache = cache === false ? void 0 : cache ?? require_warnings.createMemoryCache();
|
|
108
|
+
const evaluator = require_warnings.createEvaluator({
|
|
100
109
|
adapter,
|
|
101
110
|
budget,
|
|
102
111
|
...retry === void 0 ? {} : { retry },
|
|
@@ -104,8 +113,9 @@ async function runRandomSearch(args) {
|
|
|
104
113
|
...evaluationCache === void 0 ? {} : { cache: evaluationCache },
|
|
105
114
|
trackOutputs: trackBestOutputs,
|
|
106
115
|
cacheHits: resumeFrom?.cacheHits ?? 0,
|
|
116
|
+
...resumeFrom?.usage === void 0 ? {} : { usage: resumeFrom.usage },
|
|
107
117
|
...signal === void 0 ? {} : { signal },
|
|
108
|
-
onEvaluation: (event) =>
|
|
118
|
+
onEvaluation: (event) => emit({
|
|
109
119
|
type: "evaluation",
|
|
110
120
|
...event
|
|
111
121
|
})
|
|
@@ -123,7 +133,7 @@ async function runRandomSearch(args) {
|
|
|
123
133
|
* no budget here bounds.
|
|
124
134
|
*/
|
|
125
135
|
let stalledRounds = 0;
|
|
126
|
-
|
|
136
|
+
emit({
|
|
127
137
|
type: "start",
|
|
128
138
|
components,
|
|
129
139
|
validationSetSize: validationSet.length
|
|
@@ -152,6 +162,8 @@ async function runRandomSearch(args) {
|
|
|
152
162
|
reflectionCalls,
|
|
153
163
|
metricCalls: budget.spent(),
|
|
154
164
|
cacheHits: evaluator.cacheHits(),
|
|
165
|
+
usage: evaluator.usage(),
|
|
166
|
+
acceptedCandidates,
|
|
155
167
|
...cached === void 0 ? {} : { cache: cached }
|
|
156
168
|
};
|
|
157
169
|
}
|
|
@@ -163,21 +175,31 @@ async function runRandomSearch(args) {
|
|
|
163
175
|
candidate: seedCandidate,
|
|
164
176
|
phase: "seed"
|
|
165
177
|
}) : void 0;
|
|
166
|
-
const seedScore = seedEvaluation === void 0 ? resumeFrom.seedScore :
|
|
178
|
+
const seedScore = seedEvaluation === void 0 ? resumeFrom.seedScore : require_warnings.requireMeasuredMean({
|
|
167
179
|
batch: seedEvaluation,
|
|
168
180
|
phase: "seed"
|
|
169
181
|
});
|
|
182
|
+
if (seedEvaluation !== void 0) emit({
|
|
183
|
+
type: "candidateAccepted",
|
|
184
|
+
round: 0,
|
|
185
|
+
candidateId: 0,
|
|
186
|
+
candidate: seedCandidate,
|
|
187
|
+
aggregateScore: seedScore,
|
|
188
|
+
instanceScores: require_warnings.instanceRow(seedEvaluation),
|
|
189
|
+
...trackBestOutputs ? { outputs: seedEvaluation.outputs } : {}
|
|
190
|
+
});
|
|
170
191
|
let best = resumeFrom?.best ?? seedCandidate;
|
|
171
192
|
let bestScore = resumeFrom?.bestScore ?? seedScore;
|
|
172
193
|
/** Absent on a resumed run until a variant wins: outputs are not checkpointed. */
|
|
173
194
|
let bestOutputs = seedEvaluation?.outputs;
|
|
195
|
+
let acceptedCandidates = resumeFrom?.acceptedCandidates ?? 0;
|
|
174
196
|
await checkpoint();
|
|
175
197
|
while (round < maxRounds) {
|
|
176
198
|
if (signal?.aborted) {
|
|
177
199
|
stopReason = "aborted";
|
|
178
200
|
break;
|
|
179
201
|
}
|
|
180
|
-
if (
|
|
202
|
+
if (require_warnings.costExhausted({
|
|
181
203
|
usage: evaluator.usage(),
|
|
182
204
|
maxCostUsd
|
|
183
205
|
})) {
|
|
@@ -188,12 +210,12 @@ async function runRandomSearch(args) {
|
|
|
188
210
|
stopReason = "deadlineReached";
|
|
189
211
|
break;
|
|
190
212
|
}
|
|
191
|
-
if (!budget.canAfford(
|
|
213
|
+
if (!budget.canAfford(validationSet.length)) {
|
|
192
214
|
stopReason = "budgetExhausted";
|
|
193
215
|
break;
|
|
194
216
|
}
|
|
195
217
|
const component = components[round % components.length];
|
|
196
|
-
|
|
218
|
+
emit({
|
|
197
219
|
type: "roundStart",
|
|
198
220
|
round,
|
|
199
221
|
component
|
|
@@ -220,41 +242,64 @@ async function runRandomSearch(args) {
|
|
|
220
242
|
});
|
|
221
243
|
const unique = [...new Set(drawn)].filter((text) => text.length > 0 && text !== currentText);
|
|
222
244
|
let roundStop;
|
|
245
|
+
const scheduled = [];
|
|
246
|
+
let owed = 0;
|
|
223
247
|
for (const text of unique) {
|
|
224
248
|
const candidate = {
|
|
225
249
|
...best,
|
|
226
250
|
[component]: text
|
|
227
251
|
};
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
252
|
+
const uncached = evaluator.countUncached({
|
|
253
|
+
candidate,
|
|
254
|
+
ids: validationIds,
|
|
255
|
+
split: "val"
|
|
256
|
+
});
|
|
257
|
+
if (!budget.canAfford(owed + uncached)) {
|
|
258
|
+
roundStop = "budgetExhausted";
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
owed += uncached;
|
|
262
|
+
scheduled.push(candidate);
|
|
263
|
+
}
|
|
264
|
+
const swept = await require_concurrency.mapWithConcurrency({
|
|
265
|
+
items: scheduled,
|
|
266
|
+
limit: concurrency,
|
|
267
|
+
task: async (candidate) => {
|
|
268
|
+
if (signal?.aborted) return { stop: "aborted" };
|
|
269
|
+
try {
|
|
270
|
+
return { evaluation: await sweep({
|
|
271
|
+
candidate,
|
|
272
|
+
phase: "validation"
|
|
273
|
+
}) };
|
|
274
|
+
} catch (err) {
|
|
275
|
+
if (err instanceof require_warnings.BudgetExhausted) return { stop: "budgetExhausted" };
|
|
276
|
+
if (signal?.aborted) return { stop: "aborted" };
|
|
277
|
+
throw err;
|
|
242
278
|
}
|
|
243
|
-
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
for (const [index, outcome] of swept.entries()) {
|
|
282
|
+
if (outcome.stop !== void 0) {
|
|
283
|
+
roundStop = outcome.stop;
|
|
284
|
+
break;
|
|
244
285
|
}
|
|
245
286
|
variantsEvaluated += 1;
|
|
246
|
-
const score =
|
|
287
|
+
const score = require_warnings.measuredMean(outcome.evaluation);
|
|
247
288
|
if (score !== void 0 && score > bestScore) {
|
|
248
|
-
|
|
289
|
+
const candidate = scheduled[index];
|
|
290
|
+
acceptedCandidates += 1;
|
|
291
|
+
emit({
|
|
249
292
|
type: "candidateAccepted",
|
|
250
293
|
round,
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
294
|
+
candidateId: acceptedCandidates,
|
|
295
|
+
candidate,
|
|
296
|
+
aggregateScore: score,
|
|
297
|
+
instanceScores: require_warnings.instanceRow(outcome.evaluation),
|
|
298
|
+
...trackBestOutputs ? { outputs: outcome.evaluation.outputs } : {}
|
|
254
299
|
});
|
|
255
300
|
best = candidate;
|
|
256
301
|
bestScore = score;
|
|
257
|
-
bestOutputs = evaluation.outputs;
|
|
302
|
+
bestOutputs = outcome.evaluation.outputs;
|
|
258
303
|
}
|
|
259
304
|
}
|
|
260
305
|
round += 1;
|
|
@@ -270,7 +315,7 @@ async function runRandomSearch(args) {
|
|
|
270
315
|
}
|
|
271
316
|
}
|
|
272
317
|
if (signal?.aborted) stopReason = "aborted";
|
|
273
|
-
const
|
|
318
|
+
const heldOut = testSet === void 0 ? void 0 : await evaluator.evaluate({
|
|
274
319
|
candidate: best,
|
|
275
320
|
batch: testSet,
|
|
276
321
|
ids: testIds,
|
|
@@ -279,13 +324,18 @@ async function runRandomSearch(args) {
|
|
|
279
324
|
candidateId: null,
|
|
280
325
|
iteration: round,
|
|
281
326
|
charge: false
|
|
282
|
-
})
|
|
283
|
-
|
|
327
|
+
});
|
|
328
|
+
const testScore = heldOut === void 0 ? void 0 : require_warnings.measuredMean(heldOut);
|
|
329
|
+
emit({
|
|
284
330
|
type: "finish",
|
|
285
331
|
reason: stopReason,
|
|
332
|
+
warnings,
|
|
333
|
+
bestCandidateId: acceptedCandidates,
|
|
286
334
|
bestScore,
|
|
287
335
|
metricCalls: budget.spent(),
|
|
288
|
-
...testScore === void 0 ? {} : { testScore }
|
|
336
|
+
...testScore === void 0 ? {} : { testScore },
|
|
337
|
+
...heldOut === void 0 ? {} : { testInstanceScores: require_warnings.instanceRow(heldOut) },
|
|
338
|
+
...heldOut === void 0 || !trackBestOutputs ? {} : { testOutputs: heldOut.outputs }
|
|
289
339
|
});
|
|
290
340
|
return {
|
|
291
341
|
bestCandidate: best,
|
|
@@ -296,13 +346,15 @@ async function runRandomSearch(args) {
|
|
|
296
346
|
...trackBestOutputs ? { bestOutputs } : {},
|
|
297
347
|
...testScore === void 0 ? {} : {
|
|
298
348
|
testScore,
|
|
299
|
-
testMetricCalls: evaluator.unchargedCalls()
|
|
349
|
+
testMetricCalls: evaluator.unchargedCalls(),
|
|
350
|
+
testUsage: evaluator.unchargedUsage()
|
|
300
351
|
},
|
|
301
352
|
rounds: round,
|
|
302
353
|
variantsEvaluated,
|
|
303
354
|
metricCalls: budget.spent(),
|
|
304
355
|
reflectionCalls,
|
|
305
356
|
cacheHits: evaluator.cacheHits(),
|
|
357
|
+
warnings,
|
|
306
358
|
stopReason
|
|
307
359
|
};
|
|
308
360
|
}
|
|
@@ -312,10 +364,8 @@ function assertConfig(config) {
|
|
|
312
364
|
if (!Number.isInteger(concurrency) || concurrency < 1) throw new Error(`concurrency must be a positive integer, received ${concurrency}`);
|
|
313
365
|
if (maxRounds !== void 0 && (!Number.isInteger(maxRounds) || maxRounds < 1)) throw new Error(`maxRounds must be a positive integer, received ${maxRounds}`);
|
|
314
366
|
}
|
|
315
|
-
function defaultInstanceId(args) {
|
|
316
|
-
const hash = require_evaluation.stableHash(args.datum);
|
|
317
|
-
return hash === "" ? String(args.index) : hash;
|
|
318
|
-
}
|
|
319
367
|
//#endregion
|
|
320
368
|
exports.RandomSearchOptimizer = RandomSearchOptimizer;
|
|
321
369
|
exports.buildParaphrasePrompt = buildParaphrasePrompt;
|
|
370
|
+
exports.isCandidateAccepted = require_warnings.isCandidateAccepted;
|
|
371
|
+
exports.isRunFinished = require_warnings.isRunFinished;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as Candidate, t as
|
|
1
|
+
import { S as UsageTotals, a as RunFinished, f as Adapter, i as Reporter, n as OptimizerEvent, o as isCandidateAccepted, p as Candidate, r as ReportableEvent, s as isRunFinished, t as CandidateAccepted, x as TextModel } from "../reporting-bq007_2z.cjs";
|
|
2
2
|
import { n as EvaluationCache, t as CachedScore } from "../cache-CuSo0NJ8.cjs";
|
|
3
|
-
import { n as OptimizerResult, r as OptimizerTask, s as EvaluationEvent, t as Optimizer } from "../optimizer-
|
|
3
|
+
import { n as OptimizerResult, r as OptimizerTask, s as EvaluationEvent, t as Optimizer } from "../optimizer-4Zv-Zt2t.cjs";
|
|
4
4
|
//#region src/random-search/optimize.d.ts
|
|
5
5
|
/** Builds the prompt one variant is drawn from. */
|
|
6
6
|
type ParaphrasePromptBuilder = (args: {
|
|
@@ -54,6 +54,13 @@ interface RandomSearchSnapshot {
|
|
|
54
54
|
reflectionCalls: number;
|
|
55
55
|
metricCalls: number;
|
|
56
56
|
cacheHits: number;
|
|
57
|
+
/** Usage already spent, so a resumed run reports totals and honours ceilings. */
|
|
58
|
+
usage?: UsageTotals;
|
|
59
|
+
/**
|
|
60
|
+
* Candidates accepted so far. Reporters key rows by this id, so restarting it
|
|
61
|
+
* at zero makes a resumed run collide with the run it continues.
|
|
62
|
+
*/
|
|
63
|
+
acceptedCandidates?: number;
|
|
57
64
|
/** Cached instance scores, when the cache can enumerate them. */
|
|
58
65
|
cache?: [string, CachedScore][];
|
|
59
66
|
}
|
|
@@ -71,7 +78,8 @@ interface RandomSearchTask<Datum, Trajectory = unknown, Output = unknown, K exte
|
|
|
71
78
|
}) => string;
|
|
72
79
|
/** Pass `false` to disable caching entirely. */
|
|
73
80
|
cache?: EvaluationCache | false;
|
|
74
|
-
|
|
81
|
+
/** Observers of the run. Every one sees every event; none can fail it. */
|
|
82
|
+
reporters?: readonly Reporter<RandomSearchEvent<NoInfer<K>>>[];
|
|
75
83
|
/**
|
|
76
84
|
* Called with a resumable snapshot after the seed is scored and after every
|
|
77
85
|
* round. Persist it and a killed run costs the last round, not all of them.
|
|
@@ -91,19 +99,13 @@ type RandomSearchEvent<K extends string = string> = {
|
|
|
91
99
|
component: K;
|
|
92
100
|
} | ({
|
|
93
101
|
type: "evaluation";
|
|
94
|
-
} & EvaluationEvent) | {
|
|
102
|
+
} & EvaluationEvent) | ({
|
|
95
103
|
type: "candidateAccepted";
|
|
96
104
|
round: number;
|
|
97
|
-
|
|
98
|
-
score: number;
|
|
99
|
-
previousScore: number;
|
|
100
|
-
} | {
|
|
105
|
+
} & CandidateAccepted<K>) | ({
|
|
101
106
|
type: "finish";
|
|
102
107
|
reason: RandomSearchStopReason;
|
|
103
|
-
|
|
104
|
-
metricCalls: number;
|
|
105
|
-
testScore?: number;
|
|
106
|
-
};
|
|
108
|
+
} & RunFinished);
|
|
107
109
|
interface RandomSearchResult<K extends string = string, Output = unknown> extends OptimizerResult<K, RandomSearchStopReason, Output> {
|
|
108
110
|
/** The seed's score, so the lift the search bought is readable directly. */
|
|
109
111
|
seedScore: number;
|
|
@@ -153,4 +155,4 @@ declare function buildParaphrasePrompt(args: {
|
|
|
153
155
|
attempt: number;
|
|
154
156
|
}): string;
|
|
155
157
|
//#endregion
|
|
156
|
-
export { type ParaphrasePromptBuilder, type RandomSearchConfig, type RandomSearchEvent, RandomSearchOptimizer, type RandomSearchResult, type RandomSearchSnapshot, type RandomSearchStopReason, type RandomSearchTask, buildParaphrasePrompt };
|
|
158
|
+
export { type CandidateAccepted, type OptimizerEvent, type ParaphrasePromptBuilder, type RandomSearchConfig, type RandomSearchEvent, RandomSearchOptimizer, type RandomSearchResult, type RandomSearchSnapshot, type RandomSearchStopReason, type RandomSearchTask, type ReportableEvent, type Reporter, type RunFinished, buildParaphrasePrompt, isCandidateAccepted, isRunFinished };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as Candidate, t as
|
|
1
|
+
import { S as UsageTotals, a as RunFinished, f as Adapter, i as Reporter, n as OptimizerEvent, o as isCandidateAccepted, p as Candidate, r as ReportableEvent, s as isRunFinished, t as CandidateAccepted, x as TextModel } from "../reporting-bq007_2z.mjs";
|
|
2
2
|
import { n as EvaluationCache, t as CachedScore } from "../cache-CuSo0NJ8.mjs";
|
|
3
|
-
import { n as OptimizerResult, r as OptimizerTask, s as EvaluationEvent, t as Optimizer } from "../optimizer-
|
|
3
|
+
import { n as OptimizerResult, r as OptimizerTask, s as EvaluationEvent, t as Optimizer } from "../optimizer-Ds5mzYjz.mjs";
|
|
4
4
|
//#region src/random-search/optimize.d.ts
|
|
5
5
|
/** Builds the prompt one variant is drawn from. */
|
|
6
6
|
type ParaphrasePromptBuilder = (args: {
|
|
@@ -54,6 +54,13 @@ interface RandomSearchSnapshot {
|
|
|
54
54
|
reflectionCalls: number;
|
|
55
55
|
metricCalls: number;
|
|
56
56
|
cacheHits: number;
|
|
57
|
+
/** Usage already spent, so a resumed run reports totals and honours ceilings. */
|
|
58
|
+
usage?: UsageTotals;
|
|
59
|
+
/**
|
|
60
|
+
* Candidates accepted so far. Reporters key rows by this id, so restarting it
|
|
61
|
+
* at zero makes a resumed run collide with the run it continues.
|
|
62
|
+
*/
|
|
63
|
+
acceptedCandidates?: number;
|
|
57
64
|
/** Cached instance scores, when the cache can enumerate them. */
|
|
58
65
|
cache?: [string, CachedScore][];
|
|
59
66
|
}
|
|
@@ -71,7 +78,8 @@ interface RandomSearchTask<Datum, Trajectory = unknown, Output = unknown, K exte
|
|
|
71
78
|
}) => string;
|
|
72
79
|
/** Pass `false` to disable caching entirely. */
|
|
73
80
|
cache?: EvaluationCache | false;
|
|
74
|
-
|
|
81
|
+
/** Observers of the run. Every one sees every event; none can fail it. */
|
|
82
|
+
reporters?: readonly Reporter<RandomSearchEvent<NoInfer<K>>>[];
|
|
75
83
|
/**
|
|
76
84
|
* Called with a resumable snapshot after the seed is scored and after every
|
|
77
85
|
* round. Persist it and a killed run costs the last round, not all of them.
|
|
@@ -91,19 +99,13 @@ type RandomSearchEvent<K extends string = string> = {
|
|
|
91
99
|
component: K;
|
|
92
100
|
} | ({
|
|
93
101
|
type: "evaluation";
|
|
94
|
-
} & EvaluationEvent) | {
|
|
102
|
+
} & EvaluationEvent) | ({
|
|
95
103
|
type: "candidateAccepted";
|
|
96
104
|
round: number;
|
|
97
|
-
|
|
98
|
-
score: number;
|
|
99
|
-
previousScore: number;
|
|
100
|
-
} | {
|
|
105
|
+
} & CandidateAccepted<K>) | ({
|
|
101
106
|
type: "finish";
|
|
102
107
|
reason: RandomSearchStopReason;
|
|
103
|
-
|
|
104
|
-
metricCalls: number;
|
|
105
|
-
testScore?: number;
|
|
106
|
-
};
|
|
108
|
+
} & RunFinished);
|
|
107
109
|
interface RandomSearchResult<K extends string = string, Output = unknown> extends OptimizerResult<K, RandomSearchStopReason, Output> {
|
|
108
110
|
/** The seed's score, so the lift the search bought is readable directly. */
|
|
109
111
|
seedScore: number;
|
|
@@ -153,4 +155,4 @@ declare function buildParaphrasePrompt(args: {
|
|
|
153
155
|
attempt: number;
|
|
154
156
|
}): string;
|
|
155
157
|
//#endregion
|
|
156
|
-
export { type ParaphrasePromptBuilder, type RandomSearchConfig, type RandomSearchEvent, RandomSearchOptimizer, type RandomSearchResult, type RandomSearchSnapshot, type RandomSearchStopReason, type RandomSearchTask, buildParaphrasePrompt };
|
|
158
|
+
export { type CandidateAccepted, type OptimizerEvent, type ParaphrasePromptBuilder, type RandomSearchConfig, type RandomSearchEvent, RandomSearchOptimizer, type RandomSearchResult, type RandomSearchSnapshot, type RandomSearchStopReason, type RandomSearchTask, type ReportableEvent, type Reporter, type RunFinished, buildParaphrasePrompt, isCandidateAccepted, isRunFinished };
|