textopt 0.1.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.
Files changed (56) hide show
  1. package/README.md +24 -6
  2. package/dist/bootstrap-search/index.cjs +29 -23
  3. package/dist/bootstrap-search/index.d.cts +3 -3
  4. package/dist/bootstrap-search/index.d.mts +3 -3
  5. package/dist/bootstrap-search/index.mjs +9 -3
  6. package/dist/{demos-D2o0qSSo.cjs → demos-9v5ts7F3.cjs} +4 -4
  7. package/dist/{demos-1b7JiUue.d.mts → demos-ASsSXYXA.d.mts} +1 -1
  8. package/dist/{demos-DE2oxNWX.mjs → demos-Brobjfuc.mjs} +1 -1
  9. package/dist/{demos-CU9dy2oT.d.cts → demos-ByaLZy-Z.d.cts} +1 -1
  10. package/dist/file-cache.cjs +16 -5
  11. package/dist/file-cache.d.cts +13 -0
  12. package/dist/file-cache.d.mts +13 -0
  13. package/dist/file-cache.mjs +16 -5
  14. package/dist/gepa/index.cjs +87 -44
  15. package/dist/gepa/index.d.cts +8 -6
  16. package/dist/gepa/index.d.mts +8 -6
  17. package/dist/gepa/index.mjs +55 -12
  18. package/dist/index.cjs +44 -19
  19. package/dist/index.d.cts +37 -5
  20. package/dist/index.d.mts +37 -5
  21. package/dist/index.mjs +29 -6
  22. package/dist/mipro/index.cjs +31 -25
  23. package/dist/mipro/index.d.cts +3 -3
  24. package/dist/mipro/index.d.mts +3 -3
  25. package/dist/mipro/index.mjs +9 -3
  26. package/dist/opro/index.cjs +31 -25
  27. package/dist/opro/index.d.cts +2 -2
  28. package/dist/opro/index.d.mts +2 -2
  29. package/dist/opro/index.mjs +8 -2
  30. package/dist/{optimizer-Bh5DPRMH.d.cts → optimizer-4Zv-Zt2t.d.cts} +41 -2
  31. package/dist/{optimizer-Ck6-e_8o.d.mts → optimizer-Ds5mzYjz.d.mts} +41 -2
  32. package/dist/random-search/index.cjs +27 -21
  33. package/dist/random-search/index.d.cts +2 -2
  34. package/dist/random-search/index.d.mts +2 -2
  35. package/dist/random-search/index.mjs +8 -2
  36. package/dist/{reflection-LRaAZP4e.d.mts → reflection-CMezGu6u.d.mts} +32 -4
  37. package/dist/{reflection-Dt3QrXhM.d.cts → reflection-D0A7eahD.d.cts} +32 -4
  38. package/dist/{reporting-DQbAohc9.d.cts → reporting-bq007_2z.d.cts} +55 -1
  39. package/dist/{reporting-DQbAohc9.d.mts → reporting-bq007_2z.d.mts} +55 -1
  40. package/dist/simba/index.cjs +31 -25
  41. package/dist/simba/index.d.cts +24 -5
  42. package/dist/simba/index.d.mts +24 -5
  43. package/dist/simba/index.mjs +9 -3
  44. package/dist/testing.d.cts +2 -2
  45. package/dist/testing.d.mts +2 -2
  46. package/dist/{reporting-CNHzbJC-.cjs → warnings-CWRJF-jA.cjs} +63 -0
  47. package/dist/{reporting-DY-DC4HG.mjs → warnings-OxvDi9kN.mjs} +52 -1
  48. package/docs/adapters.md +169 -0
  49. package/docs/benchmark.md +90 -0
  50. package/docs/data-prep.md +113 -0
  51. package/docs/distillation.md +128 -0
  52. package/docs/evaluation.md +87 -0
  53. package/docs/metric-preflight.md +132 -0
  54. package/docs/optimizers.md +293 -0
  55. package/docs/tuning.md +130 -0
  56. package/package.json +3 -2
@@ -1,4 +1,4 @@
1
- import { _ as TextModel, a as RunFinished, c as Adapter, d as EvaluationBatch, l as Candidate, m as EvaluationSplit, p as EvaluationPhase, t as CandidateAccepted, v as UsageTotals } from "./reporting-DQbAohc9.mjs";
1
+ import { S as UsageTotals, _ as EvaluationPhase, a as RunFinished, f as Adapter, h as EvaluationBatch, m as EvaluateArgs, p as Candidate, t as CandidateAccepted, v as EvaluationSplit, x as TextModel } from "./reporting-bq007_2z.mjs";
2
2
  import { t as CachedScore } from "./cache-CuSo0NJ8.mjs";
3
3
  import { t as Rng } from "./rng-BR5MOedA.mjs";
4
4
  //#region src/gepa/types.d.ts
@@ -56,12 +56,29 @@ interface ProposeArgs<K extends string = string> {
56
56
  reflect: TextModel;
57
57
  signal?: AbortSignal;
58
58
  }
59
+ /**
60
+ * A scored batch that carries the per-instance diagnosis reflection is written
61
+ * from. `feedback` is optional on `EvaluationBatch` because the searches that
62
+ * never reflect have no use for it; here it is the input to the whole method,
63
+ * so it is required.
64
+ *
65
+ * An adapter that returns scores and no prose reduces every rollout to a
66
+ * number, and reflection then rewrites the instruction from a prompt whose
67
+ * feedback blocks are empty. That run spends its whole budget, reports a
68
+ * normal-looking `stopReason`, and has been doing blind search — which is
69
+ * exactly the failure no reading of the result can distinguish from a hard
70
+ * task. It is a type error instead.
71
+ */
72
+ type ReflectiveBatch<Trajectory = unknown, Output = unknown> = EvaluationBatch<Trajectory, Output> & {
73
+ feedback: string[];
74
+ };
59
75
  /**
60
76
  * An adapter GEPA can reflect against: evaluation, plus the traces reflection
61
77
  * reads. `makeReflectiveDataset` is what turns a scored batch into the
62
78
  * per-component evidence a reflection call is written from.
63
79
  */
64
80
  interface GepaAdapter<Datum, Trajectory = unknown, Output = unknown, K extends string = string> extends Adapter<Datum, Trajectory, Output, K> {
81
+ evaluate(args: EvaluateArgs<Datum, K>): Promise<ReflectiveBatch<Trajectory, Output>> | ReflectiveBatch<Trajectory, Output>;
65
82
  makeReflectiveDataset(args: MakeReflectiveDatasetArgs<Datum, Trajectory, Output, K>): Promise<ReflectiveDataset<K>> | ReflectiveDataset<K>;
66
83
  proposeNewTexts?(args: ProposeArgs<K>): Promise<ComponentPatch<K>> | ComponentPatch<K>;
67
84
  }
@@ -111,10 +128,21 @@ type ComponentSelector<K extends string = string> = (args: {
111
128
  iteration: number;
112
129
  rng: Rng;
113
130
  }) => K[];
114
- type AcceptancePolicy = (args: {
131
+ type AcceptancePolicy = ((args: {
115
132
  parentScores: readonly number[];
116
133
  childScores: readonly number[];
117
- }) => boolean;
134
+ }) => boolean) & {
135
+ /**
136
+ * Smallest minibatch this policy could ever accept on, when it has one. A
137
+ * policy that tests for significance has a floor its batch size must clear
138
+ * — a sign-flip test over three instances cannot report a p-value below
139
+ * 0.125 — and below it every proposal is rejected on arithmetic rather than
140
+ * on evidence. The run that results looks exactly like a search that found
141
+ * nothing, so the optimizer refuses the combination at construction instead
142
+ * of spending the budget discovering it.
143
+ */
144
+ minimumPairs?: number;
145
+ };
118
146
  /**
119
147
  * Which validation instances a candidate is scored on, and how the best
120
148
  * candidate is read back out of possibly partial coverage.
@@ -276,4 +304,4 @@ declare function buildRewritePrompt(args: ReflectionPromptArgs): string;
276
304
  */
277
305
  declare function diverseReflectionStrategies(): ReflectionPromptBuilder[];
278
306
  //#endregion
279
- export { RejectedProposal as C, ReflectiveRecord as S, ValEvaluationPolicy as T, GepaStopReason as _, buildRewritePrompt as a, ProposeArgs as b, AcceptancePolicy as c, CandidateSource as d, ComponentPatch as f, GepaSnapshot as g, GepaEvent as h, buildReflectionPrompt as i, CandidateRecord as l, GepaAdapter as m, ReflectionPromptBuilder as n, buildSimplifyPrompt as o, ComponentSelector as p, buildGeneralizePrompt as r, diverseReflectionStrategies as s, ReflectionPromptArgs as t, CandidateSelector as u, MakeReflectiveDatasetArgs as v, SelectionState as w, ReflectiveDataset as x, ParetoFrontier as y };
307
+ export { ReflectiveRecord as C, ValEvaluationPolicy as E, ReflectiveDataset as S, SelectionState as T, GepaStopReason as _, buildRewritePrompt as a, ProposeArgs as b, AcceptancePolicy as c, CandidateSource as d, ComponentPatch as f, GepaSnapshot as g, GepaEvent as h, buildReflectionPrompt as i, CandidateRecord as l, GepaAdapter as m, ReflectionPromptBuilder as n, buildSimplifyPrompt as o, ComponentSelector as p, buildGeneralizePrompt as r, diverseReflectionStrategies as s, ReflectionPromptArgs as t, CandidateSelector as u, MakeReflectiveDatasetArgs as v, RejectedProposal as w, ReflectiveBatch as x, ParetoFrontier as y };
@@ -1,4 +1,4 @@
1
- import { _ as TextModel, a as RunFinished, c as Adapter, d as EvaluationBatch, l as Candidate, m as EvaluationSplit, p as EvaluationPhase, t as CandidateAccepted, v as UsageTotals } from "./reporting-DQbAohc9.cjs";
1
+ import { S as UsageTotals, _ as EvaluationPhase, a as RunFinished, f as Adapter, h as EvaluationBatch, m as EvaluateArgs, p as Candidate, t as CandidateAccepted, v as EvaluationSplit, x as TextModel } from "./reporting-bq007_2z.cjs";
2
2
  import { t as CachedScore } from "./cache-CuSo0NJ8.cjs";
3
3
  import { t as Rng } from "./rng-BR5MOedA.cjs";
4
4
  //#region src/gepa/types.d.ts
@@ -56,12 +56,29 @@ interface ProposeArgs<K extends string = string> {
56
56
  reflect: TextModel;
57
57
  signal?: AbortSignal;
58
58
  }
59
+ /**
60
+ * A scored batch that carries the per-instance diagnosis reflection is written
61
+ * from. `feedback` is optional on `EvaluationBatch` because the searches that
62
+ * never reflect have no use for it; here it is the input to the whole method,
63
+ * so it is required.
64
+ *
65
+ * An adapter that returns scores and no prose reduces every rollout to a
66
+ * number, and reflection then rewrites the instruction from a prompt whose
67
+ * feedback blocks are empty. That run spends its whole budget, reports a
68
+ * normal-looking `stopReason`, and has been doing blind search — which is
69
+ * exactly the failure no reading of the result can distinguish from a hard
70
+ * task. It is a type error instead.
71
+ */
72
+ type ReflectiveBatch<Trajectory = unknown, Output = unknown> = EvaluationBatch<Trajectory, Output> & {
73
+ feedback: string[];
74
+ };
59
75
  /**
60
76
  * An adapter GEPA can reflect against: evaluation, plus the traces reflection
61
77
  * reads. `makeReflectiveDataset` is what turns a scored batch into the
62
78
  * per-component evidence a reflection call is written from.
63
79
  */
64
80
  interface GepaAdapter<Datum, Trajectory = unknown, Output = unknown, K extends string = string> extends Adapter<Datum, Trajectory, Output, K> {
81
+ evaluate(args: EvaluateArgs<Datum, K>): Promise<ReflectiveBatch<Trajectory, Output>> | ReflectiveBatch<Trajectory, Output>;
65
82
  makeReflectiveDataset(args: MakeReflectiveDatasetArgs<Datum, Trajectory, Output, K>): Promise<ReflectiveDataset<K>> | ReflectiveDataset<K>;
66
83
  proposeNewTexts?(args: ProposeArgs<K>): Promise<ComponentPatch<K>> | ComponentPatch<K>;
67
84
  }
@@ -111,10 +128,21 @@ type ComponentSelector<K extends string = string> = (args: {
111
128
  iteration: number;
112
129
  rng: Rng;
113
130
  }) => K[];
114
- type AcceptancePolicy = (args: {
131
+ type AcceptancePolicy = ((args: {
115
132
  parentScores: readonly number[];
116
133
  childScores: readonly number[];
117
- }) => boolean;
134
+ }) => boolean) & {
135
+ /**
136
+ * Smallest minibatch this policy could ever accept on, when it has one. A
137
+ * policy that tests for significance has a floor its batch size must clear
138
+ * — a sign-flip test over three instances cannot report a p-value below
139
+ * 0.125 — and below it every proposal is rejected on arithmetic rather than
140
+ * on evidence. The run that results looks exactly like a search that found
141
+ * nothing, so the optimizer refuses the combination at construction instead
142
+ * of spending the budget discovering it.
143
+ */
144
+ minimumPairs?: number;
145
+ };
118
146
  /**
119
147
  * Which validation instances a candidate is scored on, and how the best
120
148
  * candidate is read back out of possibly partial coverage.
@@ -276,4 +304,4 @@ declare function buildRewritePrompt(args: ReflectionPromptArgs): string;
276
304
  */
277
305
  declare function diverseReflectionStrategies(): ReflectionPromptBuilder[];
278
306
  //#endregion
279
- export { RejectedProposal as C, ReflectiveRecord as S, ValEvaluationPolicy as T, GepaStopReason as _, buildRewritePrompt as a, ProposeArgs as b, AcceptancePolicy as c, CandidateSource as d, ComponentPatch as f, GepaSnapshot as g, GepaEvent as h, buildReflectionPrompt as i, CandidateRecord as l, GepaAdapter as m, ReflectionPromptBuilder as n, buildSimplifyPrompt as o, ComponentSelector as p, buildGeneralizePrompt as r, diverseReflectionStrategies as s, ReflectionPromptArgs as t, CandidateSelector as u, MakeReflectiveDatasetArgs as v, SelectionState as w, ReflectiveDataset as x, ParetoFrontier as y };
307
+ export { ReflectiveRecord as C, ValEvaluationPolicy as E, ReflectiveDataset as S, SelectionState as T, GepaStopReason as _, buildRewritePrompt as a, ProposeArgs as b, AcceptancePolicy as c, CandidateSource as d, ComponentPatch as f, GepaSnapshot as g, GepaEvent as h, buildReflectionPrompt as i, CandidateRecord as l, GepaAdapter as m, ReflectionPromptBuilder as n, buildSimplifyPrompt as o, ComponentSelector as p, buildGeneralizePrompt as r, diverseReflectionStrategies as s, ReflectionPromptArgs as t, CandidateSelector as u, MakeReflectiveDatasetArgs as v, RejectedProposal as w, ReflectiveBatch as x, ParetoFrontier as y };
@@ -126,6 +126,54 @@ type TextModel = (args: {
126
126
  */
127
127
  declare function componentNames<K extends string>(candidate: Partial<Candidate<K>>): K[];
128
128
  //#endregion
129
+ //#region src/warnings.d.ts
130
+ /**
131
+ * Something about a run that its own numbers cannot say.
132
+ *
133
+ * A search reports a score, a stop reason and what it spent, and every one of
134
+ * those reads the same whether the run measured what the caller thinks it did
135
+ * or not. These are the conditions under which a normal-looking result means
136
+ * less than it appears to: they never stop a run, and they are carried on the
137
+ * result and the `finish` event so a report can say so next to the number.
138
+ */
139
+ interface RunWarning {
140
+ code: RunWarningCode;
141
+ message: string;
142
+ }
143
+ type RunWarningCode = "validationSetReusesTraining" | "seedScoreSaturated" | "seedScoreFloored";
144
+ /**
145
+ * The validation set a run will actually select against, and whatever the
146
+ * choice costs it.
147
+ *
148
+ * Defaulting to the training set is the right default for a first run and the
149
+ * wrong number to report from one. It is worse than ordinary overfitting under
150
+ * reflective search: the reflection prompt asks the model to mine domain facts
151
+ * out of the traces it is shown, so those facts come out of the very instances
152
+ * that then select the candidate carrying them. `"reuseTraining"` is the same
153
+ * behaviour with the caller's name on it, and silences the warning.
154
+ */
155
+ declare function resolveValidationSet<Datum>(args: {
156
+ validationSet: readonly Datum[] | "reuseTraining" | undefined;
157
+ trainingSet: readonly Datum[];
158
+ }): {
159
+ validationSet: readonly Datum[];
160
+ warnings: RunWarning[];
161
+ };
162
+ /**
163
+ * What the seed's own validation row says about whether the run could have
164
+ * learned anything.
165
+ *
166
+ * A search ranks candidates by how they differ across instances, so a seed row
167
+ * with no spread leaves nothing to rank: at the ceiling every proposal is a tie
168
+ * the acceptance test resolves by noise, and at the floor no proposal has a
169
+ * partial improvement to build on. Both produce a run that spends its whole
170
+ * budget and reports a stop reason that looks like any other.
171
+ */
172
+ declare function seedScoreWarnings(args: {
173
+ scores: readonly (number | undefined)[];
174
+ perfectScore: number;
175
+ }): RunWarning[];
176
+ //#endregion
129
177
  //#region src/reporting.d.ts
130
178
  /**
131
179
  * Where a run's progress goes, for any optimizer. Observability only:
@@ -212,6 +260,12 @@ interface RunFinished {
212
260
  testInstanceScores?: readonly (number | undefined)[];
213
261
  /** Aligned with `testInstanceScores`. Only under `trackBestOutputs`. */
214
262
  testOutputs?: readonly unknown[];
263
+ /**
264
+ * What the run cannot say about itself from its own numbers. A reporter that
265
+ * writes the score somewhere permanent writes these beside it, or the record
266
+ * outlives the only place the caveat was ever stated.
267
+ */
268
+ warnings: readonly RunWarning[];
215
269
  }
216
270
  /**
217
271
  * The two events every optimizer emits with a payload a reporter can read
@@ -237,4 +291,4 @@ declare function isRunFinished(event: OptimizerEvent): event is {
237
291
  type: "finish";
238
292
  } & RunFinished;
239
293
  //#endregion
240
- export { TextModel as _, RunFinished as a, Adapter as c, EvaluationBatch as d, EvaluationContext as f, ScoreResult as g, RolloutUsage as h, Reporter as i, Candidate as l, EvaluationSplit as m, OptimizerEvent as n, isCandidateAccepted as o, EvaluationPhase as p, ReportableEvent as r, isRunFinished as s, CandidateAccepted as t, EvaluateArgs as u, UsageTotals as v, componentNames as y };
294
+ export { componentNames as C, UsageTotals as S, EvaluationPhase as _, RunFinished as a, ScoreResult as b, RunWarning as c, seedScoreWarnings as d, Adapter as f, EvaluationContext as g, EvaluationBatch as h, Reporter as i, RunWarningCode as l, EvaluateArgs as m, OptimizerEvent as n, isCandidateAccepted as o, Candidate as p, ReportableEvent as r, isRunFinished as s, CandidateAccepted as t, resolveValidationSet as u, EvaluationSplit as v, TextModel as x, RolloutUsage as y };
@@ -126,6 +126,54 @@ type TextModel = (args: {
126
126
  */
127
127
  declare function componentNames<K extends string>(candidate: Partial<Candidate<K>>): K[];
128
128
  //#endregion
129
+ //#region src/warnings.d.ts
130
+ /**
131
+ * Something about a run that its own numbers cannot say.
132
+ *
133
+ * A search reports a score, a stop reason and what it spent, and every one of
134
+ * those reads the same whether the run measured what the caller thinks it did
135
+ * or not. These are the conditions under which a normal-looking result means
136
+ * less than it appears to: they never stop a run, and they are carried on the
137
+ * result and the `finish` event so a report can say so next to the number.
138
+ */
139
+ interface RunWarning {
140
+ code: RunWarningCode;
141
+ message: string;
142
+ }
143
+ type RunWarningCode = "validationSetReusesTraining" | "seedScoreSaturated" | "seedScoreFloored";
144
+ /**
145
+ * The validation set a run will actually select against, and whatever the
146
+ * choice costs it.
147
+ *
148
+ * Defaulting to the training set is the right default for a first run and the
149
+ * wrong number to report from one. It is worse than ordinary overfitting under
150
+ * reflective search: the reflection prompt asks the model to mine domain facts
151
+ * out of the traces it is shown, so those facts come out of the very instances
152
+ * that then select the candidate carrying them. `"reuseTraining"` is the same
153
+ * behaviour with the caller's name on it, and silences the warning.
154
+ */
155
+ declare function resolveValidationSet<Datum>(args: {
156
+ validationSet: readonly Datum[] | "reuseTraining" | undefined;
157
+ trainingSet: readonly Datum[];
158
+ }): {
159
+ validationSet: readonly Datum[];
160
+ warnings: RunWarning[];
161
+ };
162
+ /**
163
+ * What the seed's own validation row says about whether the run could have
164
+ * learned anything.
165
+ *
166
+ * A search ranks candidates by how they differ across instances, so a seed row
167
+ * with no spread leaves nothing to rank: at the ceiling every proposal is a tie
168
+ * the acceptance test resolves by noise, and at the floor no proposal has a
169
+ * partial improvement to build on. Both produce a run that spends its whole
170
+ * budget and reports a stop reason that looks like any other.
171
+ */
172
+ declare function seedScoreWarnings(args: {
173
+ scores: readonly (number | undefined)[];
174
+ perfectScore: number;
175
+ }): RunWarning[];
176
+ //#endregion
129
177
  //#region src/reporting.d.ts
130
178
  /**
131
179
  * Where a run's progress goes, for any optimizer. Observability only:
@@ -212,6 +260,12 @@ interface RunFinished {
212
260
  testInstanceScores?: readonly (number | undefined)[];
213
261
  /** Aligned with `testInstanceScores`. Only under `trackBestOutputs`. */
214
262
  testOutputs?: readonly unknown[];
263
+ /**
264
+ * What the run cannot say about itself from its own numbers. A reporter that
265
+ * writes the score somewhere permanent writes these beside it, or the record
266
+ * outlives the only place the caveat was ever stated.
267
+ */
268
+ warnings: readonly RunWarning[];
215
269
  }
216
270
  /**
217
271
  * The two events every optimizer emits with a payload a reporter can read
@@ -237,4 +291,4 @@ declare function isRunFinished(event: OptimizerEvent): event is {
237
291
  type: "finish";
238
292
  } & RunFinished;
239
293
  //#endregion
240
- export { TextModel as _, RunFinished as a, Adapter as c, EvaluationBatch as d, EvaluationContext as f, ScoreResult as g, RolloutUsage as h, Reporter as i, Candidate as l, EvaluationSplit as m, OptimizerEvent as n, isCandidateAccepted as o, EvaluationPhase as p, ReportableEvent as r, isRunFinished as s, CandidateAccepted as t, EvaluateArgs as u, UsageTotals as v, componentNames as y };
294
+ export { componentNames as C, UsageTotals as S, EvaluationPhase as _, RunFinished as a, ScoreResult as b, RunWarning as c, seedScoreWarnings as d, Adapter as f, EvaluationContext as g, EvaluationBatch as h, Reporter as i, RunWarningCode as l, EvaluateArgs as m, OptimizerEvent as n, isCandidateAccepted as o, Candidate as p, ReportableEvent as r, isRunFinished as s, CandidateAccepted as t, resolveValidationSet as u, EvaluationSplit as v, TextModel as x, RolloutUsage as y };
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_reporting = require("../reporting-CNHzbJC-.cjs");
2
+ const require_warnings = require("../warnings-CWRJF-jA.cjs");
3
3
  const require_concurrency = require("../concurrency-C-cFzWW2.cjs");
4
- const require_demos = require("../demos-D2o0qSSo.cjs");
4
+ const require_demos = require("../demos-9v5ts7F3.cjs");
5
5
  const require_rng = require("../rng-DbA_rPIo.cjs");
6
6
  const require_sampling = require("../sampling-Dars7ctR.cjs");
7
7
  //#region src/simba/advice.ts
@@ -246,16 +246,20 @@ var SimbaOptimizer = class {
246
246
  task
247
247
  });
248
248
  } finally {
249
- await require_reporting.flushReporters(task.reporters ?? []);
249
+ await require_warnings.flushReporters(task.reporters ?? []);
250
250
  }
251
251
  }
252
252
  };
253
253
  async function run(args) {
254
254
  const { config, task } = args;
255
255
  const { minibatchSize = DEFAULT_MINIBATCH_SIZE, candidates: candidateCount = DEFAULT_CANDIDATES, concurrency = 1, maxSteps = DEFAULT_MAX_STEPS, maxDemos = DEFAULT_MAX_DEMOS, samplingTemperature = DEFAULT_TEMPERATURE, candidateTemperature = DEFAULT_TEMPERATURE, strategies, maxReflectionCalls, seed = 0, trackBestOutputs = false, checkpointCache = true } = config;
256
- const { seedCandidate, trainingSet, validationSet = trainingSet, testSet, adapter, reflect, demoComponents = [], instructionComponents, renderDemo, buildAdvicePrompt: buildPrompt = buildAdvicePrompt, sampler = require_sampling.createEpochShuffledSampler({ minibatchSize }), maxMetricCalls, cache, cacheNamespace, retry, maxCostUsd, maxWallClockMs, instanceId = require_reporting.defaultInstanceId, reporters = [], onCheckpoint, resumeFrom, signal } = task;
257
- const emit = require_reporting.createEmitter(reporters);
258
- const components = require_reporting.componentNames(seedCandidate);
256
+ const { seedCandidate, trainingSet, validationSet: requestedValidationSet, testSet, adapter, reflect, demoComponents = [], instructionComponents, renderDemo, buildAdvicePrompt: buildPrompt = buildAdvicePrompt, sampler = require_sampling.createEpochShuffledSampler({ minibatchSize }), maxMetricCalls, cache, cacheNamespace, retry, maxCostUsd, maxWallClockMs, instanceId = require_warnings.defaultInstanceId, reporters = [], onCheckpoint, resumeFrom, signal } = task;
257
+ const { validationSet, warnings } = require_warnings.resolveValidationSet({
258
+ validationSet: requestedValidationSet,
259
+ trainingSet
260
+ });
261
+ const emit = require_warnings.createEmitter(reporters);
262
+ const components = require_warnings.componentNames(seedCandidate);
259
263
  const nonDemo = components.filter((name) => !demoComponents.includes(name));
260
264
  const ruleComponents = instructionComponents ?? (nonDemo.length > 0 ? nonDemo : components);
261
265
  const enabled = strategies ?? (demoComponents.length > 0 ? ["appendDemo", "appendRule"] : ["appendRule"]);
@@ -278,25 +282,25 @@ async function run(args) {
278
282
  datum,
279
283
  index
280
284
  })) ?? [];
281
- const fingerprint = require_reporting.runFingerprint({
285
+ const fingerprint = require_warnings.runFingerprint({
282
286
  seedCandidate,
283
287
  trainingIds,
284
288
  validationIds,
285
289
  seed,
286
290
  ...cacheNamespace === void 0 ? {} : { cacheNamespace }
287
291
  });
288
- require_reporting.assertResumable({
292
+ require_warnings.assertResumable({
289
293
  fingerprint,
290
294
  ...resumeFrom === void 0 ? {} : { snapshot: resumeFrom }
291
295
  });
292
- const deadline = require_reporting.createDeadline({ maxWallClockMs });
296
+ const deadline = require_warnings.createDeadline({ maxWallClockMs });
293
297
  const rng = require_rng.createSeededRng(seed, resumeFrom?.rngState);
294
- const budget = require_reporting.createBudget({
298
+ const budget = require_warnings.createBudget({
295
299
  maxMetricCalls,
296
300
  spent: resumeFrom?.metricCalls ?? 0
297
301
  });
298
- const evaluationCache = cache === false ? void 0 : cache ?? require_reporting.createMemoryCache();
299
- const evaluator = require_reporting.createEvaluator({
302
+ const evaluationCache = cache === false ? void 0 : cache ?? require_warnings.createMemoryCache();
303
+ const evaluator = require_warnings.createEvaluator({
300
304
  adapter,
301
305
  budget,
302
306
  ...retry === void 0 ? {} : { retry },
@@ -334,7 +338,7 @@ async function run(args) {
334
338
  stopReason = "aborted";
335
339
  break;
336
340
  }
337
- if (require_reporting.costExhausted({
341
+ if (require_warnings.costExhausted({
338
342
  usage: evaluator.usage(),
339
343
  maxCostUsd
340
344
  })) {
@@ -389,7 +393,7 @@ async function run(args) {
389
393
  outputs: evaluation.outputs,
390
394
  ...evaluation.feedback === void 0 ? {} : { feedback: evaluation.feedback }
391
395
  });
392
- programScores[programIndex].push(require_reporting.measuredMean(evaluation) ?? 0);
396
+ programScores[programIndex].push(require_warnings.measuredMean(evaluation) ?? 0);
393
397
  }
394
398
  if (samples.length === 0) {
395
399
  stopReason = "budgetExhausted";
@@ -463,10 +467,10 @@ async function run(args) {
463
467
  const scored = await mapDistinct({
464
468
  items: scheduled,
465
469
  limit: concurrency,
466
- key: (entry) => require_reporting.candidateHash(entry.candidate),
470
+ key: (entry) => require_warnings.candidateHash(entry.candidate),
467
471
  task: async (entry, index) => {
468
472
  try {
469
- return { score: require_reporting.measuredMean(await evaluator.evaluate({
473
+ return { score: require_warnings.measuredMean(await evaluator.evaluate({
470
474
  candidate: entry.candidate,
471
475
  batch,
472
476
  ids: batchIds,
@@ -476,7 +480,7 @@ async function run(args) {
476
480
  iteration: step
477
481
  })) };
478
482
  } catch (err) {
479
- if (err instanceof require_reporting.BudgetExhausted) return { stop: true };
483
+ if (err instanceof require_warnings.BudgetExhausted) return { stop: true };
480
484
  throw err;
481
485
  }
482
486
  }
@@ -537,7 +541,7 @@ async function run(args) {
537
541
  const sweeps = await mapDistinct({
538
542
  items: contenders,
539
543
  limit: concurrency,
540
- key: (contender) => require_reporting.candidateHash(contender.candidate),
544
+ key: (contender) => require_warnings.candidateHash(contender.candidate),
541
545
  task: async (contender) => {
542
546
  if (signal?.aborted) return { stop: true };
543
547
  try {
@@ -551,11 +555,11 @@ async function run(args) {
551
555
  iteration: step
552
556
  });
553
557
  return {
554
- score: require_reporting.measuredMean(evaluation),
558
+ score: require_warnings.measuredMean(evaluation),
555
559
  evaluation
556
560
  };
557
561
  } catch (err) {
558
- if (err instanceof require_reporting.BudgetExhausted || signal?.aborted) return { stop: true };
562
+ if (err instanceof require_warnings.BudgetExhausted || signal?.aborted) return { stop: true };
559
563
  throw err;
560
564
  }
561
565
  }
@@ -581,7 +585,7 @@ async function run(args) {
581
585
  candidateId: acceptedCandidates,
582
586
  candidate: contender.candidate,
583
587
  aggregateScore: outcome.score,
584
- instanceScores: require_reporting.instanceRow(outcome.evaluation),
588
+ instanceScores: require_warnings.instanceRow(outcome.evaluation),
585
589
  ...trackBestOutputs ? { outputs: outcome.evaluation.outputs } : {}
586
590
  });
587
591
  }
@@ -611,15 +615,16 @@ async function run(args) {
611
615
  iteration: step,
612
616
  charge: false
613
617
  });
614
- const testScore = heldOut === void 0 ? void 0 : require_reporting.measuredMean(heldOut);
618
+ const testScore = heldOut === void 0 ? void 0 : require_warnings.measuredMean(heldOut);
615
619
  emit({
616
620
  type: "finish",
617
621
  reason: stopReason,
622
+ warnings,
618
623
  bestCandidateId: acceptedCandidates,
619
624
  bestScore: best.score,
620
625
  metricCalls: budget.spent(),
621
626
  ...testScore === void 0 ? {} : { testScore },
622
- ...heldOut === void 0 ? {} : { testInstanceScores: require_reporting.instanceRow(heldOut) },
627
+ ...heldOut === void 0 ? {} : { testInstanceScores: require_warnings.instanceRow(heldOut) },
623
628
  ...heldOut === void 0 || !trackBestOutputs ? {} : { testOutputs: heldOut.outputs }
624
629
  });
625
630
  return {
@@ -639,6 +644,7 @@ async function run(args) {
639
644
  testMetricCalls: evaluator.unchargedCalls(),
640
645
  testUsage: evaluator.unchargedUsage()
641
646
  },
647
+ warnings,
642
648
  stopReason
643
649
  };
644
650
  /**
@@ -827,8 +833,8 @@ exports.SimbaOptimizer = SimbaOptimizer;
827
833
  exports.buildAdvicePrompt = buildAdvicePrompt;
828
834
  exports.buildBuckets = buildBuckets;
829
835
  exports.evenlySpacedIndices = evenlySpacedIndices;
830
- exports.isCandidateAccepted = require_reporting.isCandidateAccepted;
831
- exports.isRunFinished = require_reporting.isRunFinished;
836
+ exports.isCandidateAccepted = require_warnings.isCandidateAccepted;
837
+ exports.isRunFinished = require_warnings.isRunFinished;
832
838
  exports.parseAdvice = parseAdvice;
833
839
  exports.percentile = percentile;
834
840
  exports.samplePoisson = samplePoisson;
@@ -1,8 +1,8 @@
1
- import { _ as TextModel, 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.cjs";
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
3
  import { t as Rng } from "../rng-BR5MOedA.cjs";
4
- import { r as DemoRenderer } from "../demos-CU9dy2oT.cjs";
5
- import { n as OptimizerResult, r as OptimizerTask, s as EvaluationEvent, t as Optimizer } from "../optimizer-Bh5DPRMH.cjs";
4
+ import { r as DemoRenderer } from "../demos-ByaLZy-Z.cjs";
5
+ import { n as OptimizerResult, r as OptimizerTask, s as EvaluationEvent, t as Optimizer } from "../optimizer-4Zv-Zt2t.cjs";
6
6
  import { t as BatchSampler } from "../sampling-axOwfZf5.cjs";
7
7
  //#region src/simba/advice.d.ts
8
8
  interface AdviceTrajectory<Output = unknown> {
@@ -58,7 +58,15 @@ interface SimbaFinalist<K extends string = string> {
58
58
  step: number;
59
59
  }
60
60
  interface SimbaConfig {
61
- /** Instances per step. Default 32. */
61
+ /**
62
+ * Instances per step. Default 32.
63
+ *
64
+ * Minibatch defaults do not transfer between optimizers — GEPA's 3 and
65
+ * MIPRO's 35 mean different things, and SIMBA's ranks instances within a
66
+ * batch by how much its programs disagreed.
67
+ *
68
+ * @see docs/tuning.md
69
+ */
62
70
  minibatchSize?: number;
63
71
  /** Programs sampled per step, and candidates built from them. Default 6. */
64
72
  candidates?: number;
@@ -73,7 +81,18 @@ interface SimbaConfig {
73
81
  * which call returned first.
74
82
  */
75
83
  concurrency?: number;
76
- /** Steps to run. Default 8. */
84
+ /**
85
+ * Steps to run. Default 8.
86
+ *
87
+ * A run has to be funded past the finalist reserve before any step happens:
88
+ * `min(candidates + 1, maxSteps + 1) * validationSet.length` rollouts are
89
+ * held back to sweep the finalists, and each step then costs
90
+ * `candidates * minibatchSize + minibatchSize`. Fund only the steps and the
91
+ * run stops after one, reporting `budgetExhausted` like any other exhausted
92
+ * budget.
93
+ *
94
+ * @see docs/tuning.md
95
+ */
77
96
  maxSteps?: number;
78
97
  /** Demos a candidate may hold before the loop starts dropping them. Default 4. */
79
98
  maxDemos?: number;
@@ -1,8 +1,8 @@
1
- import { _ as TextModel, 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";
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
3
  import { t as Rng } from "../rng-BR5MOedA.mjs";
4
- import { r as DemoRenderer } from "../demos-1b7JiUue.mjs";
5
- import { n as OptimizerResult, r as OptimizerTask, s as EvaluationEvent, t as Optimizer } from "../optimizer-Ck6-e_8o.mjs";
4
+ import { r as DemoRenderer } from "../demos-ASsSXYXA.mjs";
5
+ import { n as OptimizerResult, r as OptimizerTask, s as EvaluationEvent, t as Optimizer } from "../optimizer-Ds5mzYjz.mjs";
6
6
  import { t as BatchSampler } from "../sampling-DFo_7RNJ.mjs";
7
7
  //#region src/simba/advice.d.ts
8
8
  interface AdviceTrajectory<Output = unknown> {
@@ -58,7 +58,15 @@ interface SimbaFinalist<K extends string = string> {
58
58
  step: number;
59
59
  }
60
60
  interface SimbaConfig {
61
- /** Instances per step. Default 32. */
61
+ /**
62
+ * Instances per step. Default 32.
63
+ *
64
+ * Minibatch defaults do not transfer between optimizers — GEPA's 3 and
65
+ * MIPRO's 35 mean different things, and SIMBA's ranks instances within a
66
+ * batch by how much its programs disagreed.
67
+ *
68
+ * @see docs/tuning.md
69
+ */
62
70
  minibatchSize?: number;
63
71
  /** Programs sampled per step, and candidates built from them. Default 6. */
64
72
  candidates?: number;
@@ -73,7 +81,18 @@ interface SimbaConfig {
73
81
  * which call returned first.
74
82
  */
75
83
  concurrency?: number;
76
- /** Steps to run. Default 8. */
84
+ /**
85
+ * Steps to run. Default 8.
86
+ *
87
+ * A run has to be funded past the finalist reserve before any step happens:
88
+ * `min(candidates + 1, maxSteps + 1) * validationSet.length` rollouts are
89
+ * held back to sweep the finalists, and each step then costs
90
+ * `candidates * minibatchSize + minibatchSize`. Fund only the steps and the
91
+ * run stops after one, reporting `budgetExhausted` like any other exhausted
92
+ * budget.
93
+ *
94
+ * @see docs/tuning.md
95
+ */
77
96
  maxSteps?: number;
78
97
  /** Demos a candidate may hold before the loop starts dropping them. Default 4. */
79
98
  maxDemos?: number;
@@ -1,6 +1,6 @@
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, v as defaultInstanceId } from "../reporting-DY-DC4HG.mjs";
1
+ import { S as createBudget, _ as componentNames, a as instanceRow, b as defaultInstanceId, c as BudgetExhausted, d as measuredMean, g as runFingerprint, i as flushReporters, l as costExhausted, m as assertResumable, o as isCandidateAccepted, p as createDeadline, r as createEmitter, s as isRunFinished, t as resolveValidationSet, u as createEvaluator, v as candidateHash, y as createMemoryCache } from "../warnings-OxvDi9kN.mjs";
2
2
  import { t as mapWithConcurrency } from "../concurrency-D58PWeSk.mjs";
3
- import { i as replaceDemos, r as parseDemos } from "../demos-DE2oxNWX.mjs";
3
+ import { i as replaceDemos, r as parseDemos } from "../demos-Brobjfuc.mjs";
4
4
  import { t as createSeededRng } from "../rng-Dtc5eZ_W.mjs";
5
5
  import { t as createEpochShuffledSampler } from "../sampling-CfHt7Gue.mjs";
6
6
  //#region src/simba/advice.ts
@@ -252,7 +252,11 @@ var SimbaOptimizer = class {
252
252
  async function run(args) {
253
253
  const { config, task } = args;
254
254
  const { minibatchSize = DEFAULT_MINIBATCH_SIZE, candidates: candidateCount = DEFAULT_CANDIDATES, concurrency = 1, maxSteps = DEFAULT_MAX_STEPS, maxDemos = DEFAULT_MAX_DEMOS, samplingTemperature = DEFAULT_TEMPERATURE, candidateTemperature = DEFAULT_TEMPERATURE, strategies, maxReflectionCalls, seed = 0, trackBestOutputs = false, checkpointCache = true } = config;
255
- const { seedCandidate, trainingSet, validationSet = trainingSet, testSet, adapter, reflect, demoComponents = [], instructionComponents, renderDemo, buildAdvicePrompt: buildPrompt = buildAdvicePrompt, sampler = createEpochShuffledSampler({ minibatchSize }), maxMetricCalls, cache, cacheNamespace, retry, maxCostUsd, maxWallClockMs, instanceId = defaultInstanceId, reporters = [], onCheckpoint, resumeFrom, signal } = task;
255
+ const { seedCandidate, trainingSet, validationSet: requestedValidationSet, testSet, adapter, reflect, demoComponents = [], instructionComponents, renderDemo, buildAdvicePrompt: buildPrompt = buildAdvicePrompt, sampler = createEpochShuffledSampler({ minibatchSize }), maxMetricCalls, cache, cacheNamespace, retry, maxCostUsd, maxWallClockMs, instanceId = defaultInstanceId, reporters = [], onCheckpoint, resumeFrom, signal } = task;
256
+ const { validationSet, warnings } = resolveValidationSet({
257
+ validationSet: requestedValidationSet,
258
+ trainingSet
259
+ });
256
260
  const emit = createEmitter(reporters);
257
261
  const components = componentNames(seedCandidate);
258
262
  const nonDemo = components.filter((name) => !demoComponents.includes(name));
@@ -614,6 +618,7 @@ async function run(args) {
614
618
  emit({
615
619
  type: "finish",
616
620
  reason: stopReason,
621
+ warnings,
617
622
  bestCandidateId: acceptedCandidates,
618
623
  bestScore: best.score,
619
624
  metricCalls: budget.spent(),
@@ -638,6 +643,7 @@ async function run(args) {
638
643
  testMetricCalls: evaluator.unchargedCalls(),
639
644
  testUsage: evaluator.unchargedUsage()
640
645
  },
646
+ warnings,
641
647
  stopReason
642
648
  };
643
649
  /**
@@ -1,5 +1,5 @@
1
- import { _ as TextModel } from "./reporting-DQbAohc9.cjs";
2
- import { i as buildReflectionPrompt, m as GepaAdapter } from "./reflection-Dt3QrXhM.cjs";
1
+ import { x as TextModel } from "./reporting-bq007_2z.cjs";
2
+ import { i as buildReflectionPrompt, m as GepaAdapter } from "./reflection-D0A7eahD.cjs";
3
3
  //#region src/testing.d.ts
4
4
  /**
5
5
  * A deterministic, LLM-free system under optimization.
@@ -1,5 +1,5 @@
1
- import { _ as TextModel } from "./reporting-DQbAohc9.mjs";
2
- import { i as buildReflectionPrompt, m as GepaAdapter } from "./reflection-LRaAZP4e.mjs";
1
+ import { x as TextModel } from "./reporting-bq007_2z.mjs";
2
+ import { i as buildReflectionPrompt, m as GepaAdapter } from "./reflection-CMezGu6u.mjs";
3
3
  //#region src/testing.d.ts
4
4
  /**
5
5
  * A deterministic, LLM-free system under optimization.