textopt 0.0.0 → 0.1.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.
Files changed (55) hide show
  1. package/README.md +44 -22
  2. package/dist/bootstrap-search/index.cjs +153 -73
  3. package/dist/bootstrap-search/index.d.cts +32 -10
  4. package/dist/bootstrap-search/index.d.mts +32 -10
  5. package/dist/bootstrap-search/index.mjs +144 -66
  6. package/dist/{demos-B0pVQjYC.d.mts → demos-1b7JiUue.d.mts} +10 -3
  7. package/dist/{demos-BTuzFNsp.d.cts → demos-CU9dy2oT.d.cts} +10 -3
  8. package/dist/demos-D2o0qSSo.cjs +244 -0
  9. package/dist/demos-DE2oxNWX.mjs +215 -0
  10. package/dist/file-cache.cjs +11 -3
  11. package/dist/file-cache.mjs +11 -3
  12. package/dist/gepa/index.cjs +76 -71
  13. package/dist/gepa/index.d.cts +12 -6
  14. package/dist/gepa/index.d.mts +12 -6
  15. package/dist/gepa/index.mjs +49 -46
  16. package/dist/index.cjs +129 -27
  17. package/dist/index.d.cts +145 -7
  18. package/dist/index.d.mts +145 -7
  19. package/dist/index.mjs +113 -15
  20. package/dist/{math-COOofUyv.cjs → math-BhlziRPc.cjs} +60 -9
  21. package/dist/math-Dqme4rYz.mjs +123 -0
  22. package/dist/mipro/index.cjs +98 -70
  23. package/dist/mipro/index.d.cts +17 -14
  24. package/dist/mipro/index.d.mts +17 -14
  25. package/dist/mipro/index.mjs +84 -58
  26. package/dist/opro/index.cjs +130 -51
  27. package/dist/opro/index.d.cts +17 -9
  28. package/dist/opro/index.d.mts +17 -9
  29. package/dist/opro/index.mjs +115 -38
  30. package/dist/{optimizer-B7SpRwl7.d.cts → optimizer-Bh5DPRMH.d.cts} +50 -4
  31. package/dist/{optimizer-DqCoth_w.d.mts → optimizer-Ck6-e_8o.d.mts} +50 -4
  32. package/dist/random-search/index.cjs +93 -49
  33. package/dist/random-search/index.d.cts +15 -13
  34. package/dist/random-search/index.d.mts +15 -13
  35. package/dist/random-search/index.mjs +83 -41
  36. package/dist/{reflection-CQToe-5B.d.cts → reflection-Dt3QrXhM.d.cts} +7 -11
  37. package/dist/{reflection-Cr_upzU0.d.mts → reflection-LRaAZP4e.d.mts} +7 -11
  38. package/dist/{evaluation-OZOp6TB7.cjs → reporting-CNHzbJC-.cjs} +165 -5
  39. package/dist/reporting-DQbAohc9.d.cts +240 -0
  40. package/dist/reporting-DQbAohc9.d.mts +240 -0
  41. package/dist/{evaluation-BV0nSZVx.mjs → reporting-DY-DC4HG.mjs} +124 -6
  42. package/dist/simba/index.cjs +210 -83
  43. package/dist/simba/index.d.cts +32 -11
  44. package/dist/simba/index.d.mts +32 -11
  45. package/dist/simba/index.mjs +200 -75
  46. package/dist/testing.cjs +1 -0
  47. package/dist/testing.d.cts +5 -3
  48. package/dist/testing.d.mts +5 -3
  49. package/dist/testing.mjs +1 -1
  50. package/package.json +4 -3
  51. package/dist/demos-B9BJiNKz.cjs +0 -143
  52. package/dist/demos-Degx6UmP.mjs +0 -126
  53. package/dist/math-DhrDmpFS.mjs +0 -78
  54. package/dist/types-CWv4IQFF.d.cts +0 -129
  55. package/dist/types-CWv4IQFF.d.mts +0 -129
@@ -1,7 +1,7 @@
1
- import { n as Candidate, t as Adapter } from "../types-CWv4IQFF.mjs";
1
+ import { a as RunFinished, c as Adapter, i as Reporter, l as Candidate, n as OptimizerEvent, o as isCandidateAccepted, r as ReportableEvent, s as isRunFinished, t as CandidateAccepted, v as UsageTotals } from "../reporting-DQbAohc9.mjs";
2
2
  import { n as EvaluationCache, t as CachedScore } from "../cache-CuSo0NJ8.mjs";
3
- import { r as DemoRenderer } from "../demos-B0pVQjYC.mjs";
4
- import { n as OptimizerResult, r as OptimizerTask, s as EvaluationEvent, t as Optimizer } from "../optimizer-DqCoth_w.mjs";
3
+ import { r as DemoRenderer } from "../demos-1b7JiUue.mjs";
4
+ import { n as OptimizerResult, r as OptimizerTask, s as EvaluationEvent, t as Optimizer } from "../optimizer-Ck6-e_8o.mjs";
5
5
  //#region src/bootstrap-search/optimize.d.ts
6
6
  /**
7
7
  * Where a candidate's demo block came from. `zeroShot` holds no demos at all,
@@ -35,6 +35,18 @@ interface BootstrapSearchConfig {
35
35
  * every candidate, which is the reliable reading and the expensive one.
36
36
  */
37
37
  stopAtScore?: number;
38
+ /**
39
+ * How many candidates may be swept at once. Default 1.
40
+ *
41
+ * Harvesting stays in plan order however this is set — every harvest draws
42
+ * from the same random stream, and reordering them would make a seeded run
43
+ * unreproducible — so what overlaps is a sweep with the harvest of the
44
+ * candidates behind it. Two costs come with raising it: a checkpoint is
45
+ * taken per wave rather than per candidate, so a killed run loses up to this
46
+ * many candidates instead of one, and `stopAtScore` is honoured by sweeping
47
+ * one at a time, since a wave cannot know it has already passed the target.
48
+ */
49
+ concurrency?: number;
38
50
  seed?: number;
39
51
  trackBestOutputs?: boolean;
40
52
  /**
@@ -61,6 +73,13 @@ interface BootstrapSearchSnapshot {
61
73
  metricCalls: number;
62
74
  bootstrapMetricCalls: number;
63
75
  cacheHits: number;
76
+ /** Usage already spent, so a resumed run reports totals and honours ceilings. */
77
+ usage?: UsageTotals;
78
+ /**
79
+ * Candidates accepted so far. Reporters key rows by this id, so restarting it
80
+ * at zero makes a resumed run collide with the run it continues.
81
+ */
82
+ acceptedCandidates?: number;
64
83
  rngState: number;
65
84
  cache?: [string, CachedScore][];
66
85
  }
@@ -92,7 +111,8 @@ interface BootstrapSearchTask<Datum, Trajectory = unknown, Output = unknown, K e
92
111
  }) => string;
93
112
  /** Pass `false` to disable caching entirely. */
94
113
  cache?: EvaluationCache | false;
95
- onEvent?: (event: BootstrapSearchEvent<NoInfer<K>>) => void;
114
+ /** Observers of the run. Every one sees every event; none can fail it. */
115
+ reporters?: readonly Reporter<BootstrapSearchEvent<NoInfer<K>>>[];
96
116
  /** Called with a resumable snapshot after every candidate is scored. */
97
117
  onCheckpoint?: (snapshot: BootstrapSearchSnapshot) => void | Promise<void>;
98
118
  /** Snapshot to continue from. */
@@ -112,13 +132,15 @@ type BootstrapSearchEvent<K extends string = string> = {
112
132
  demos: number;
113
133
  score: number;
114
134
  accepted: boolean;
115
- } | {
135
+ } | ({
136
+ type: "candidateAccepted";
137
+ /** Which construction produced the demo block that won. */
138
+ source: DemoSource;
139
+ demos: number;
140
+ } & CandidateAccepted<K>) | ({
116
141
  type: "finish";
117
142
  reason: BootstrapSearchStopReason;
118
- bestScore: number;
119
- metricCalls: number;
120
- testScore?: number;
121
- };
143
+ } & RunFinished);
122
144
  interface BootstrapSearchResult<K extends string = string, Output = unknown> extends OptimizerResult<K, BootstrapSearchStopReason, Output> {
123
145
  /** The seed's score, so the lift the demos bought is readable directly. */
124
146
  seedScore: number;
@@ -159,4 +181,4 @@ declare class BootstrapSearchOptimizer implements Optimizer<BootstrapSearchStopR
159
181
  optimize<Datum, Trajectory = unknown, Output = unknown, const K extends string = string>(task: BootstrapSearchTask<Datum, Trajectory, Output, K>): Promise<BootstrapSearchResult<K, Output>>;
160
182
  }
161
183
  //#endregion
162
- export { type BootstrapCandidate, type BootstrapSearchConfig, type BootstrapSearchEvent, BootstrapSearchOptimizer, type BootstrapSearchResult, type BootstrapSearchSnapshot, type BootstrapSearchStopReason, type BootstrapSearchTask, type DemoSource };
184
+ export { type BootstrapCandidate, type BootstrapSearchConfig, type BootstrapSearchEvent, BootstrapSearchOptimizer, type BootstrapSearchResult, type BootstrapSearchSnapshot, type BootstrapSearchStopReason, type BootstrapSearchTask, type CandidateAccepted, type DemoSource, type OptimizerEvent, type ReportableEvent, type Reporter, type RunFinished, isCandidateAccepted, isRunFinished };
@@ -1,5 +1,5 @@
1
- import { a as requireMeasuredMean, d as createMemoryCache, i as measuredMean, l as runFingerprint, n as costExhausted, o as createDeadline, p as createBudget, r as createEvaluator, s as assertResumable, t as BudgetExhausted, u as componentNames } from "../evaluation-BV0nSZVx.mjs";
2
- import { n as formatDemos, t as bootstrapDemos } from "../demos-Degx6UmP.mjs";
1
+ import { _ as createMemoryCache, a as isRunFinished, b as createBudget, c as createEvaluator, d as createDeadline, f as assertResumable, g as candidateHash, h as componentNames, i as isCandidateAccepted, l as measuredMean, m as runFingerprint, n as flushReporters, o as BudgetExhausted, r as instanceRow, s as costExhausted, t as createEmitter, u as requireMeasuredMean, v as defaultInstanceId } from "../reporting-DY-DC4HG.mjs";
2
+ import { n as harvestFewShotExamples, t as formatDemos } from "../demos-DE2oxNWX.mjs";
3
3
  import { t as createSeededRng } from "../rng-Dtc5eZ_W.mjs";
4
4
  //#region src/bootstrap-search/optimize.ts
5
5
  const DEFAULT_CANDIDATES = 16;
@@ -33,19 +33,25 @@ const DEFAULT_MAX_LABELED_DEMOS = 16;
33
33
  var BootstrapSearchOptimizer = class {
34
34
  #config;
35
35
  constructor(config = {}) {
36
+ assertBootstrapSearchConfig(config);
36
37
  this.#config = config;
37
38
  }
38
- optimize(task) {
39
- return run({
40
- config: this.#config,
41
- task
42
- });
39
+ async optimize(task) {
40
+ try {
41
+ return await run({
42
+ config: this.#config,
43
+ task
44
+ });
45
+ } finally {
46
+ await flushReporters(task.reporters ?? []);
47
+ }
43
48
  }
44
49
  };
45
50
  async function run(args) {
46
51
  const { config, task } = args;
47
- const { candidates: shuffledHarvests = DEFAULT_CANDIDATES, maxDemos = DEFAULT_MAX_DEMOS, minDemos = DEFAULT_MIN_DEMOS, maxLabeledDemos = DEFAULT_MAX_LABELED_DEMOS, demoMinScore, stopAtScore, seed = 0, trackBestOutputs = false, checkpointCache = true } = config;
48
- const { seedCandidate, trainingSet, validationSet = trainingSet, testSet, adapter, demoComponents, renderDemo, goldOutput, maxMetricCalls, cache, cacheNamespace, retry, maxCostUsd, maxWallClockMs, instanceId = defaultInstanceId, onEvent, onCheckpoint, resumeFrom, signal } = task;
52
+ const { candidates: shuffledHarvests = DEFAULT_CANDIDATES, maxDemos = DEFAULT_MAX_DEMOS, minDemos = DEFAULT_MIN_DEMOS, maxLabeledDemos = DEFAULT_MAX_LABELED_DEMOS, demoMinScore, stopAtScore, concurrency = 1, seed = 0, trackBestOutputs = false, checkpointCache = true } = config;
53
+ const { seedCandidate, trainingSet, validationSet = trainingSet, testSet, adapter, demoComponents, renderDemo, goldOutput, maxMetricCalls, cache, cacheNamespace, retry, maxCostUsd, maxWallClockMs, instanceId = defaultInstanceId, reporters = [], onCheckpoint, resumeFrom, signal } = task;
54
+ const emit = createEmitter(reporters);
49
55
  const deadline = createDeadline({ maxWallClockMs });
50
56
  const components = componentNames(seedCandidate);
51
57
  if (trainingSet.length === 0) throw new Error("optimize requires a non-empty trainingSet");
@@ -88,8 +94,9 @@ async function run(args) {
88
94
  ...evaluationCache === void 0 ? {} : { cache: evaluationCache },
89
95
  trackOutputs: trackBestOutputs,
90
96
  cacheHits: resumeFrom?.cacheHits ?? 0,
97
+ ...resumeFrom?.usage === void 0 ? {} : { usage: resumeFrom.usage },
91
98
  ...signal === void 0 ? {} : { signal },
92
- onEvaluation: (event) => onEvent?.({
99
+ onEvaluation: (event) => emit({
93
100
  type: "evaluation",
94
101
  ...event
95
102
  })
@@ -99,7 +106,7 @@ async function run(args) {
99
106
  let drawn = resumeFrom?.drawn ?? 0;
100
107
  let bootstrapMetricCalls = resumeFrom?.bootstrapMetricCalls ?? 0;
101
108
  let stopReason = "candidatesExhausted";
102
- onEvent?.({
109
+ emit({
103
110
  type: "start",
104
111
  components,
105
112
  validationSetSize: validationSet.length
@@ -115,13 +122,25 @@ async function run(args) {
115
122
  iteration: evaluated.length
116
123
  });
117
124
  }
118
- const seedScore = resumeFrom?.seedScore ?? requireMeasuredMean({
119
- batch: await sweep(seedCandidate, "seed"),
125
+ const seedEvaluation = resumeFrom === void 0 ? await sweep(seedCandidate, "seed") : void 0;
126
+ const seedScore = seedEvaluation === void 0 ? resumeFrom.seedScore : requireMeasuredMean({
127
+ batch: seedEvaluation,
120
128
  phase: "seed"
121
129
  });
122
130
  let best = resumeFrom?.best ?? seedCandidate;
123
131
  let bestScore = resumeFrom?.bestScore ?? seedScore;
124
132
  let bestOutputs;
133
+ let acceptedCandidates = resumeFrom?.acceptedCandidates ?? 0;
134
+ if (seedEvaluation !== void 0) emit({
135
+ type: "candidateAccepted",
136
+ source: "zeroShot",
137
+ demos: 0,
138
+ candidateId: 0,
139
+ candidate: seedCandidate,
140
+ aggregateScore: seedScore,
141
+ instanceScores: instanceRow(seedEvaluation),
142
+ ...trackBestOutputs ? { outputs: seedEvaluation.outputs } : {}
143
+ });
125
144
  function takeSnapshot() {
126
145
  const cached = checkpointCache ? evaluationCache?.entries?.() : void 0;
127
146
  return {
@@ -135,6 +154,8 @@ async function run(args) {
135
154
  metricCalls: budget.spent(),
136
155
  bootstrapMetricCalls,
137
156
  cacheHits: evaluator.cacheHits(),
157
+ usage: evaluator.usage(),
158
+ acceptedCandidates,
138
159
  rngState: rng.state(),
139
160
  ...cached === void 0 ? {} : { cache: cached }
140
161
  };
@@ -147,7 +168,8 @@ async function run(args) {
147
168
  shuffledHarvests,
148
169
  labeled: goldOutput !== void 0
149
170
  });
150
- for (; drawn < plan.length; drawn += 1) {
171
+ const waveSize = stopAtScore === void 0 ? concurrency : 1;
172
+ while (drawn < plan.length) {
151
173
  if (signal?.aborted) {
152
174
  stopReason = "aborted";
153
175
  break;
@@ -163,58 +185,95 @@ async function run(args) {
163
185
  stopReason = "deadlineReached";
164
186
  break;
165
187
  }
166
- if (!budget.canAfford(validationSet.length + 1)) {
167
- stopReason = "budgetExhausted";
168
- break;
169
- }
170
- const source = plan[drawn];
171
- const block = await buildBlock(source);
172
- const candidate = withDemos(block);
173
- let evaluation;
174
- try {
175
- evaluation = await sweep(candidate, "validation");
176
- } catch (err) {
177
- if (err instanceof BudgetExhausted) {
178
- stopReason = "budgetExhausted";
179
- break;
180
- }
181
- if (signal?.aborted) {
182
- stopReason = "aborted";
188
+ const wave = [];
189
+ const inFlight = /* @__PURE__ */ new Map();
190
+ let waveStop;
191
+ while (wave.length < waveSize && drawn + wave.length < plan.length) {
192
+ if (!budget.canAfford(validationSet.length + 1)) {
193
+ waveStop = "budgetExhausted";
183
194
  break;
184
195
  }
185
- throw err;
196
+ const source = plan[drawn + wave.length];
197
+ const block = await buildBlock(source);
198
+ const candidate = withDemos(block);
199
+ const key = candidateHash(candidate);
200
+ const prior = inFlight.get(key);
201
+ const sweeping = prior === void 0 ? settled(sweep(candidate, "validation")) : prior.then(() => settled(sweep(candidate, "validation")));
202
+ inFlight.set(key, sweeping);
203
+ wave.push({
204
+ source,
205
+ candidate,
206
+ block,
207
+ sweep: sweeping
208
+ });
186
209
  }
187
- const score = measuredMean(evaluation);
188
- if (score === void 0) continue;
189
- const accepted = score > bestScore;
190
- evaluated.push({
191
- candidate,
192
- source,
193
- demos: countDemos(block),
194
- score
195
- });
196
- onEvent?.({
197
- type: "candidate",
198
- index: evaluated.length - 1,
199
- source,
200
- demos: countDemos(block),
201
- score,
202
- accepted
203
- });
204
- if (accepted) {
205
- best = candidate;
206
- bestScore = score;
207
- bestOutputs = evaluation.outputs;
210
+ let waveError;
211
+ let draining = false;
212
+ for (const entry of wave) {
213
+ const outcome = await entry.sweep;
214
+ if (draining) continue;
215
+ drawn += 1;
216
+ if (outcome.failed === true) {
217
+ draining = true;
218
+ if (outcome.err instanceof BudgetExhausted) {
219
+ waveStop = "budgetExhausted";
220
+ continue;
221
+ }
222
+ if (signal?.aborted) {
223
+ waveStop = "aborted";
224
+ continue;
225
+ }
226
+ waveError = outcome.err;
227
+ continue;
228
+ }
229
+ const evaluation = outcome.evaluation;
230
+ const score = measuredMean(evaluation);
231
+ if (score === void 0) continue;
232
+ const accepted = score > bestScore;
233
+ evaluated.push({
234
+ candidate: entry.candidate,
235
+ source: entry.source,
236
+ demos: countDemos(entry.block),
237
+ score
238
+ });
239
+ emit({
240
+ type: "candidate",
241
+ index: evaluated.length - 1,
242
+ source: entry.source,
243
+ demos: countDemos(entry.block),
244
+ score,
245
+ accepted
246
+ });
247
+ if (accepted) {
248
+ acceptedCandidates += 1;
249
+ emit({
250
+ type: "candidateAccepted",
251
+ source: entry.source,
252
+ demos: countDemos(entry.block),
253
+ candidateId: acceptedCandidates,
254
+ candidate: entry.candidate,
255
+ aggregateScore: score,
256
+ instanceScores: instanceRow(evaluation),
257
+ ...trackBestOutputs ? { outputs: evaluation.outputs } : {}
258
+ });
259
+ best = entry.candidate;
260
+ bestScore = score;
261
+ bestOutputs = evaluation.outputs;
262
+ }
263
+ if (stopAtScore !== void 0 && score >= stopAtScore) {
264
+ waveStop = "scoreReached";
265
+ draining = true;
266
+ }
208
267
  }
268
+ if (waveError !== void 0) throw waveError;
209
269
  await checkpoint();
210
- if (stopAtScore !== void 0 && score >= stopAtScore) {
211
- stopReason = "scoreReached";
212
- drawn += 1;
270
+ if (waveStop !== void 0) {
271
+ stopReason = waveStop;
213
272
  break;
214
273
  }
215
274
  }
216
275
  if (signal?.aborted) stopReason = "aborted";
217
- const testScore = testSet === void 0 ? void 0 : measuredMean(await evaluator.evaluate({
276
+ const heldOut = testSet === void 0 ? void 0 : await evaluator.evaluate({
218
277
  candidate: best,
219
278
  batch: testSet,
220
279
  ids: testIds,
@@ -223,13 +282,17 @@ async function run(args) {
223
282
  candidateId: null,
224
283
  iteration: evaluated.length,
225
284
  charge: false
226
- }));
227
- onEvent?.({
285
+ });
286
+ const testScore = heldOut === void 0 ? void 0 : measuredMean(heldOut);
287
+ emit({
228
288
  type: "finish",
229
289
  reason: stopReason,
290
+ bestCandidateId: acceptedCandidates,
230
291
  bestScore,
231
292
  metricCalls: budget.spent(),
232
- ...testScore === void 0 ? {} : { testScore }
293
+ ...testScore === void 0 ? {} : { testScore },
294
+ ...heldOut === void 0 ? {} : { testInstanceScores: instanceRow(heldOut) },
295
+ ...heldOut === void 0 || !trackBestOutputs ? {} : { testOutputs: heldOut.outputs }
233
296
  });
234
297
  return {
235
298
  bestCandidate: best,
@@ -244,7 +307,8 @@ async function run(args) {
244
307
  ...trackBestOutputs && bestOutputs !== void 0 ? { bestOutputs } : {},
245
308
  ...testScore === void 0 ? {} : {
246
309
  testScore,
247
- testMetricCalls: testSet?.length ?? 0
310
+ testMetricCalls: evaluator.unchargedCalls(),
311
+ testUsage: evaluator.unchargedUsage()
248
312
  },
249
313
  stopReason
250
314
  };
@@ -259,19 +323,21 @@ async function run(args) {
259
323
  const requested = source === "unshuffled" ? maxDemos : minDemos + rng.nextInt(Math.max(1, maxDemos - minDemos + 1));
260
324
  const affordable = Math.min(trainingSet.length, budget.remaining() - validationSet.length);
261
325
  if (affordable < 1) return "";
262
- const harvest = await bootstrapDemos({
326
+ const harvest = await harvestFewShotExamples({
263
327
  adapter,
264
328
  candidate: seedCandidate,
265
329
  trainingSet,
266
330
  ...demoMinScore === void 0 ? {} : { minScore: demoMinScore },
267
331
  maxDemos: requested,
268
332
  maxMetricCalls: affordable,
333
+ ...maxCostUsd === void 0 ? {} : { maxCostUsd: maxCostUsd - evaluator.usage().costUsd },
269
334
  ...source === "unshuffled" ? {} : { rng },
270
335
  ...renderDemo === void 0 ? {} : { renderDemo },
271
336
  ...signal === void 0 ? {} : { signal }
272
337
  });
273
338
  bootstrapMetricCalls += harvest.metricCalls;
274
339
  budget.reserve(harvest.metricCalls);
340
+ evaluator.absorbUsage(harvest.usage);
275
341
  return harvest.block;
276
342
  }
277
343
  function labeledBlock() {
@@ -297,11 +363,23 @@ function candidatePlan(args) {
297
363
  ...Array.from({ length: shuffledHarvests }, () => "bootstrapped")
298
364
  ];
299
365
  }
366
+ /** Turns a sweep into a value, so a dispatched one never rejects unobserved. */
367
+ function settled(sweeping) {
368
+ return sweeping.then((evaluation) => ({ evaluation }), (err) => ({
369
+ failed: true,
370
+ err
371
+ }));
372
+ }
373
+ /**
374
+ * Range checks on the search knobs, run at construction so a configuration
375
+ * that could never terminate is refused before a task is ever handed to it.
376
+ */
377
+ function assertBootstrapSearchConfig(config) {
378
+ const { concurrency = 1 } = config;
379
+ if (!Number.isInteger(concurrency) || concurrency < 1) throw new Error(`concurrency must be a positive integer, received ${concurrency}`);
380
+ }
300
381
  function countDemos(block) {
301
382
  return block.split("<demo>").length - 1;
302
383
  }
303
- function defaultInstanceId(args) {
304
- return String(args.index);
305
- }
306
384
  //#endregion
307
- export { BootstrapSearchOptimizer };
385
+ export { BootstrapSearchOptimizer, isCandidateAccepted, isRunFinished };
@@ -1,4 +1,4 @@
1
- import { n as Candidate, t as Adapter } from "./types-CWv4IQFF.mjs";
1
+ import { c as Adapter, l as Candidate, v as UsageTotals } from "./reporting-DQbAohc9.mjs";
2
2
  import { t as Rng } from "./rng-BR5MOedA.mjs";
3
3
  //#region src/demos.d.ts
4
4
  /**
@@ -23,6 +23,8 @@ interface BootstrapResult<Datum, Output> {
23
23
  block: string;
24
24
  /** Rollouts this cost. Bootstrapping is cheap, not free. */
25
25
  metricCalls: number;
26
+ /** Tokens and dollars this cost, for a caller that bounds spend. */
27
+ usage: UsageTotals;
26
28
  attempted: number;
27
29
  }
28
30
  /**
@@ -36,7 +38,7 @@ interface BootstrapResult<Datum, Output> {
36
38
  * examples on what the output should look like — so a seed carrying both
37
39
  * starts somewhere neither reaches alone.
38
40
  */
39
- declare function bootstrapDemos<Datum, Trajectory, Output, K extends string = string>(args: {
41
+ declare function harvestFewShotExamples<Datum, Trajectory, Output, K extends string = string>(args: {
40
42
  adapter: Adapter<Datum, Trajectory, Output, K>;
41
43
  /** The candidate to run. Usually the seed, sometimes a run's winner. */
42
44
  candidate: Candidate<K>;
@@ -61,6 +63,11 @@ declare function bootstrapDemos<Datum, Trajectory, Output, K extends string = st
61
63
  batchSize?: number;
62
64
  /** Ceiling on rollouts. Defaults to one pass over the trainingSet. */
63
65
  maxMetricCalls?: number;
66
+ /**
67
+ * Ceiling on dollars this pass may spend, checked between batches. Harvesting
68
+ * runs on its own evaluator, so a caller bounding spend has to say so here.
69
+ */
70
+ maxCostUsd?: number;
64
71
  /** Shuffles the trainingSet first, so demos are not all drawn from its head. */
65
72
  rng?: Rng;
66
73
  renderDemo?: DemoRenderer<Datum, Output>;
@@ -85,4 +92,4 @@ declare function formatDemos<Datum, Output>(demos: readonly Demo<Datum, Output>[
85
92
  */
86
93
  declare function parseDemos(text: string): Demo[];
87
94
  //#endregion
88
- export { formatDemos as a, bootstrapDemos as i, Demo as n, parseDemos as o, DemoRenderer as r, BootstrapResult as t };
95
+ export { harvestFewShotExamples as a, formatDemos as i, Demo as n, parseDemos as o, DemoRenderer as r, BootstrapResult as t };
@@ -1,4 +1,4 @@
1
- import { n as Candidate, t as Adapter } from "./types-CWv4IQFF.cjs";
1
+ import { c as Adapter, l as Candidate, v as UsageTotals } from "./reporting-DQbAohc9.cjs";
2
2
  import { t as Rng } from "./rng-BR5MOedA.cjs";
3
3
  //#region src/demos.d.ts
4
4
  /**
@@ -23,6 +23,8 @@ interface BootstrapResult<Datum, Output> {
23
23
  block: string;
24
24
  /** Rollouts this cost. Bootstrapping is cheap, not free. */
25
25
  metricCalls: number;
26
+ /** Tokens and dollars this cost, for a caller that bounds spend. */
27
+ usage: UsageTotals;
26
28
  attempted: number;
27
29
  }
28
30
  /**
@@ -36,7 +38,7 @@ interface BootstrapResult<Datum, Output> {
36
38
  * examples on what the output should look like — so a seed carrying both
37
39
  * starts somewhere neither reaches alone.
38
40
  */
39
- declare function bootstrapDemos<Datum, Trajectory, Output, K extends string = string>(args: {
41
+ declare function harvestFewShotExamples<Datum, Trajectory, Output, K extends string = string>(args: {
40
42
  adapter: Adapter<Datum, Trajectory, Output, K>;
41
43
  /** The candidate to run. Usually the seed, sometimes a run's winner. */
42
44
  candidate: Candidate<K>;
@@ -61,6 +63,11 @@ declare function bootstrapDemos<Datum, Trajectory, Output, K extends string = st
61
63
  batchSize?: number;
62
64
  /** Ceiling on rollouts. Defaults to one pass over the trainingSet. */
63
65
  maxMetricCalls?: number;
66
+ /**
67
+ * Ceiling on dollars this pass may spend, checked between batches. Harvesting
68
+ * runs on its own evaluator, so a caller bounding spend has to say so here.
69
+ */
70
+ maxCostUsd?: number;
64
71
  /** Shuffles the trainingSet first, so demos are not all drawn from its head. */
65
72
  rng?: Rng;
66
73
  renderDemo?: DemoRenderer<Datum, Output>;
@@ -85,4 +92,4 @@ declare function formatDemos<Datum, Output>(demos: readonly Demo<Datum, Output>[
85
92
  */
86
93
  declare function parseDemos(text: string): Demo[];
87
94
  //#endregion
88
- export { formatDemos as a, bootstrapDemos as i, Demo as n, parseDemos as o, DemoRenderer as r, BootstrapResult as t };
95
+ export { harvestFewShotExamples as a, formatDemos as i, Demo as n, parseDemos as o, DemoRenderer as r, BootstrapResult as t };