textopt 0.0.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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +509 -0
  3. package/dist/bootstrap-search/index.cjs +308 -0
  4. package/dist/bootstrap-search/index.d.cts +162 -0
  5. package/dist/bootstrap-search/index.d.mts +162 -0
  6. package/dist/bootstrap-search/index.mjs +307 -0
  7. package/dist/cache-CuSo0NJ8.d.cts +24 -0
  8. package/dist/cache-CuSo0NJ8.d.mts +24 -0
  9. package/dist/concurrency-C-cFzWW2.cjs +44 -0
  10. package/dist/concurrency-D58PWeSk.mjs +39 -0
  11. package/dist/demos-B0pVQjYC.d.mts +88 -0
  12. package/dist/demos-B9BJiNKz.cjs +143 -0
  13. package/dist/demos-BTuzFNsp.d.cts +88 -0
  14. package/dist/demos-Degx6UmP.mjs +126 -0
  15. package/dist/evaluation-BV0nSZVx.mjs +521 -0
  16. package/dist/evaluation-OZOp6TB7.cjs +598 -0
  17. package/dist/file-cache.cjs +70 -0
  18. package/dist/file-cache.d.cts +21 -0
  19. package/dist/file-cache.d.mts +21 -0
  20. package/dist/file-cache.mjs +69 -0
  21. package/dist/gepa/index.cjs +1671 -0
  22. package/dist/gepa/index.d.cts +385 -0
  23. package/dist/gepa/index.d.mts +385 -0
  24. package/dist/gepa/index.mjs +1652 -0
  25. package/dist/index.cjs +266 -0
  26. package/dist/index.d.cts +221 -0
  27. package/dist/index.d.mts +221 -0
  28. package/dist/index.mjs +245 -0
  29. package/dist/math-COOofUyv.cjs +101 -0
  30. package/dist/math-DhrDmpFS.mjs +78 -0
  31. package/dist/mipro/index.cjs +739 -0
  32. package/dist/mipro/index.d.cts +372 -0
  33. package/dist/mipro/index.d.mts +372 -0
  34. package/dist/mipro/index.mjs +736 -0
  35. package/dist/opro/index.cjs +487 -0
  36. package/dist/opro/index.d.cts +230 -0
  37. package/dist/opro/index.d.mts +230 -0
  38. package/dist/opro/index.mjs +485 -0
  39. package/dist/optimizer-B7SpRwl7.d.cts +288 -0
  40. package/dist/optimizer-DqCoth_w.d.mts +288 -0
  41. package/dist/random-search/index.cjs +321 -0
  42. package/dist/random-search/index.d.cts +156 -0
  43. package/dist/random-search/index.d.mts +156 -0
  44. package/dist/random-search/index.mjs +319 -0
  45. package/dist/reflection-CQToe-5B.d.cts +283 -0
  46. package/dist/reflection-Cr_upzU0.d.mts +283 -0
  47. package/dist/reflection-DRfbk6hu.cjs +249 -0
  48. package/dist/reflection-mwMhrjs_.mjs +214 -0
  49. package/dist/rng-BR5MOedA.d.cts +22 -0
  50. package/dist/rng-BR5MOedA.d.mts +22 -0
  51. package/dist/rng-DbA_rPIo.cjs +67 -0
  52. package/dist/rng-Dtc5eZ_W.mjs +62 -0
  53. package/dist/sampling-CfHt7Gue.mjs +59 -0
  54. package/dist/sampling-DFo_7RNJ.d.mts +23 -0
  55. package/dist/sampling-Dars7ctR.cjs +64 -0
  56. package/dist/sampling-axOwfZf5.d.cts +23 -0
  57. package/dist/simba/index.cjs +709 -0
  58. package/dist/simba/index.d.cts +289 -0
  59. package/dist/simba/index.d.mts +289 -0
  60. package/dist/simba/index.mjs +700 -0
  61. package/dist/testing.cjs +155 -0
  62. package/dist/testing.d.cts +53 -0
  63. package/dist/testing.d.mts +53 -0
  64. package/dist/testing.mjs +148 -0
  65. package/dist/text--v4Ffbus.mjs +21 -0
  66. package/dist/text-CK_HB3su.cjs +26 -0
  67. package/dist/types-CWv4IQFF.d.cts +129 -0
  68. package/dist/types-CWv4IQFF.d.mts +129 -0
  69. package/package.json +135 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,266 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_evaluation = require("./evaluation-OZOp6TB7.cjs");
3
+ const require_concurrency = require("./concurrency-C-cFzWW2.cjs");
4
+ const require_math = require("./math-COOofUyv.cjs");
5
+ const require_demos = require("./demos-B9BJiNKz.cjs");
6
+ const require_text = require("./text-CK_HB3su.cjs");
7
+ //#region src/compare.ts
8
+ const EXACT_LIMIT = 16;
9
+ /**
10
+ * Run several optimizers over the same seeds and report which one actually won.
11
+ *
12
+ * Two things make this worth a helper rather than a for-loop. The first is that
13
+ * it ranks on `testScore` where a run reports one: the validation score is the
14
+ * number the search selected against for its whole run, so an entrant that
15
+ * overfits looks strongest on exactly the number it fitted. The second is that
16
+ * a difference in means over a handful of seeds is usually noise, and the
17
+ * paired sign-flip p-value against the winner is what says whether it is.
18
+ *
19
+ * Entrants are functions of a seed rather than optimizer instances, because the
20
+ * seed is constructor config and every optimizer here is deterministic given
21
+ * one — comparing two entrants at a single seed compares two anecdotes. It also
22
+ * leaves the task where the caller builds it, which is the only place the
23
+ * optimizer-specific parts of it (`reflect`, `cache`, `onEvent`) are known.
24
+ */
25
+ async function compare(args) {
26
+ const { entrants, seeds, concurrency = 1 } = args;
27
+ const names = Object.keys(entrants);
28
+ if (names.length === 0) throw new Error("compare requires at least one entrant");
29
+ if (seeds.length === 0) throw new Error("compare requires at least one seed");
30
+ const grid = names.flatMap((entrant) => seeds.map((seed) => ({
31
+ entrant,
32
+ seed
33
+ })));
34
+ const runs = await require_concurrency.mapWithConcurrency({
35
+ items: grid,
36
+ limit: concurrency,
37
+ task: async ({ entrant, seed }) => {
38
+ const result = await entrants[entrant]({ seed });
39
+ return {
40
+ entrant,
41
+ seed,
42
+ score: result.testScore ?? result.bestScore,
43
+ bestScore: result.bestScore,
44
+ ...result.testScore === void 0 ? {} : { testScore: result.testScore },
45
+ metricCalls: result.metricCalls,
46
+ costUsd: result.usage.costUsd,
47
+ stopReason: result.stopReason
48
+ };
49
+ }
50
+ });
51
+ const summaries = names.map((entrant) => summarize({
52
+ entrant,
53
+ runs: runs.filter((run) => run.entrant === entrant)
54
+ }));
55
+ const winner = summaries.reduce((best, summary) => summary.meanScore > best.meanScore ? summary : best);
56
+ return {
57
+ winner: winner.entrant,
58
+ summaries: summaries.map((summary) => summary.entrant === winner.entrant ? summary : {
59
+ ...summary,
60
+ pValueVsWinner: margin({
61
+ winner: winner.entrant,
62
+ entrant: summary.entrant,
63
+ runs,
64
+ seeds
65
+ })
66
+ }),
67
+ runs
68
+ };
69
+ }
70
+ function summarize(args) {
71
+ const { entrant, runs } = args;
72
+ const scores = runs.map((run) => run.score);
73
+ return {
74
+ entrant,
75
+ runs: runs.length,
76
+ meanScore: mean(scores),
77
+ sdScore: standardDeviation(scores),
78
+ minScore: Math.min(...scores),
79
+ maxScore: Math.max(...scores),
80
+ meanMetricCalls: mean(runs.map((run) => run.metricCalls)),
81
+ meanCostUsd: mean(runs.map((run) => run.costUsd))
82
+ };
83
+ }
84
+ /**
85
+ * Paired across seeds rather than pooled: the same seed puts both entrants on
86
+ * the same sampling order, so the difference at a seed is a comparison and the
87
+ * spread between seeds is not.
88
+ */
89
+ function margin(args) {
90
+ const { winner, entrant, runs, seeds } = args;
91
+ const differences = seeds.map((seed) => {
92
+ return scoreOf({
93
+ runs,
94
+ entrant: winner,
95
+ seed
96
+ }) - scoreOf({
97
+ runs,
98
+ entrant,
99
+ seed
100
+ });
101
+ });
102
+ return require_math.signFlipPValue({
103
+ differences,
104
+ observed: differences.reduce((total, value) => total + value, 0),
105
+ maxExact: EXACT_LIMIT
106
+ });
107
+ }
108
+ function scoreOf(args) {
109
+ const { runs, entrant, seed } = args;
110
+ return runs.find((candidate) => candidate.entrant === entrant && candidate.seed === seed)?.score ?? 0;
111
+ }
112
+ function mean(values) {
113
+ return values.reduce((total, value) => total + value, 0) / values.length;
114
+ }
115
+ function standardDeviation(values) {
116
+ if (values.length < 2) return 0;
117
+ const average = mean(values);
118
+ const variance = values.reduce((total, value) => total + (value - average) ** 2, 0) / (values.length - 1);
119
+ return Math.sqrt(variance);
120
+ }
121
+ //#endregion
122
+ //#region src/judge.ts
123
+ const DEFAULT_SCALE = 5;
124
+ const SCORE = /<score\s+name="([^"]+)"\s*>\s*([\d.]+)\s*<\/score>/g;
125
+ const FEEDBACK = /<feedback>([\s\S]*?)<\/feedback>/;
126
+ /**
127
+ * A model-graded metric that returns written feedback alongside the score.
128
+ *
129
+ * The feedback is the point. A judge that returns only a number reduces a whole
130
+ * paragraph of diagnosis to one scalar, and reflective search — the thing most
131
+ * likely to be pointed at a task too open-ended to score by string match — runs
132
+ * on exactly that diagnosis. So the prompt demands feedback, and demands it be
133
+ * addressed to the instructions rather than to the graded output: "this answer
134
+ * should have mentioned the refund window" tells a rewriting model nothing that
135
+ * "the instruction never says to state the refund window" does not say better.
136
+ *
137
+ * Grades on a small integer scale and normalizes afterwards. Models discriminate
138
+ * between 2 and 4 far more reliably than between 0.4 and 0.8, and the scale is
139
+ * the caller's to widen once they have seen the judge bunch its answers.
140
+ */
141
+ function createJudge(args) {
142
+ const { model, criteria, scale = DEFAULT_SCALE, renderInput = stringify, renderOutput = stringify, buildPrompt = buildJudgePrompt } = args;
143
+ if (criteria.length === 0) throw new Error("createJudge requires at least one criterion");
144
+ return async ({ input, output, expected, signal }) => {
145
+ return readVerdict({
146
+ response: await model({
147
+ prompt: buildPrompt({
148
+ input: renderInput(input),
149
+ output: renderOutput(output),
150
+ expected: expected === void 0 ? void 0 : renderOutput(expected),
151
+ criteria,
152
+ scale
153
+ }),
154
+ signal
155
+ }),
156
+ criteria,
157
+ scale
158
+ });
159
+ };
160
+ }
161
+ function buildJudgePrompt(args) {
162
+ const { input, output, expected, criteria, scale } = args;
163
+ return [
164
+ "You are grading one output of an automated system against the criteria below.",
165
+ "",
166
+ "<input>",
167
+ input,
168
+ "</input>",
169
+ "",
170
+ "<output>",
171
+ output,
172
+ "</output>",
173
+ ...expected === void 0 ? [] : [
174
+ "",
175
+ "<expected_answer>",
176
+ expected,
177
+ "</expected_answer>"
178
+ ],
179
+ "",
180
+ "<criteria>",
181
+ criteria.map((criterion) => `<${criterion.name}>${criterion.description}</${criterion.name}>`).join("\n"),
182
+ "</criteria>",
183
+ "",
184
+ `Grade each criterion from 0 to ${scale}, where ${scale} is a perfect answer.`,
185
+ "",
186
+ "Then write feedback. It is read by a program that rewrites the system's instructions, not by a person reviewing this output, so say what the instructions should tell the system to do differently. Feedback about this particular answer is of no use to it.",
187
+ "",
188
+ "Reply in exactly this format and nothing else:",
189
+ ...criteria.map((criterion) => `<score name="${criterion.name}">…</score>`),
190
+ "<feedback>…</feedback>"
191
+ ].join("\n");
192
+ }
193
+ /**
194
+ * A judge that answered off-format graded nothing, so the result is unknown
195
+ * rather than bad. Reporting it as transient is what keeps a formatting failure
196
+ * out of the cache and off the candidate's record — the same treatment a rate
197
+ * limit gets, for the same reason.
198
+ */
199
+ function readVerdict(args) {
200
+ const { response, criteria, scale } = args;
201
+ const feedback = response.match(FEEDBACK)?.[1]?.trim() ?? "";
202
+ const graded = /* @__PURE__ */ new Map();
203
+ for (const match of response.matchAll(SCORE)) graded.set(match[1], Number(match[2]));
204
+ const objectiveScores = {};
205
+ for (const criterion of criteria) {
206
+ const grade = graded.get(criterion.name);
207
+ if (grade === void 0 || Number.isNaN(grade)) return {
208
+ score: 0,
209
+ feedback: `Judge did not grade "${criterion.name}".`,
210
+ transient: true
211
+ };
212
+ objectiveScores[criterion.name] = clamp(grade / scale);
213
+ }
214
+ const grades = Object.values(objectiveScores);
215
+ return {
216
+ score: grades.reduce((total, grade) => total + grade, 0) / grades.length,
217
+ feedback,
218
+ objectiveScores
219
+ };
220
+ }
221
+ function stringify(value) {
222
+ return typeof value === "string" ? value : JSON.stringify(value);
223
+ }
224
+ function clamp(value) {
225
+ return Math.min(1, Math.max(0, value));
226
+ }
227
+ //#endregion
228
+ //#region src/usage.ts
229
+ const TOKENS_PER_PRICED_UNIT = 1e6;
230
+ /**
231
+ * Costs a token reading, leaving it untouched when no price list is given.
232
+ *
233
+ * Prices belong to the caller rather than to this library: they change without
234
+ * warning, differ per account, and a stale table baked in here would report
235
+ * confident numbers that are quietly wrong.
236
+ */
237
+ function priceUsage(args) {
238
+ const { usage, pricing } = args;
239
+ if (pricing === void 0) return usage;
240
+ return {
241
+ ...usage,
242
+ costUsd: ((usage.inputTokens ?? 0) * pricing.inputPerMillionUsd + (usage.outputTokens ?? 0) * pricing.outputPerMillionUsd) / TOKENS_PER_PRICED_UNIT
243
+ };
244
+ }
245
+ //#endregion
246
+ exports.BudgetExhausted = require_evaluation.BudgetExhausted;
247
+ exports.assertResumable = require_evaluation.assertResumable;
248
+ exports.bootstrapDemos = require_demos.bootstrapDemos;
249
+ exports.buildJudgePrompt = buildJudgePrompt;
250
+ exports.candidateFingerprint = require_evaluation.candidateFingerprint;
251
+ exports.compare = compare;
252
+ exports.componentNames = require_evaluation.componentNames;
253
+ exports.costExhausted = require_evaluation.costExhausted;
254
+ exports.createBudget = require_evaluation.createBudget;
255
+ exports.createDeadline = require_evaluation.createDeadline;
256
+ exports.createEvaluator = require_evaluation.createEvaluator;
257
+ exports.createJudge = createJudge;
258
+ exports.createMemoryCache = require_evaluation.createMemoryCache;
259
+ exports.formatDemos = require_demos.formatDemos;
260
+ exports.mapWithConcurrency = require_concurrency.mapWithConcurrency;
261
+ exports.measuredMean = require_evaluation.measuredMean;
262
+ exports.parseDemos = require_demos.parseDemos;
263
+ exports.parseProposedText = require_text.parseProposedText;
264
+ exports.priceUsage = priceUsage;
265
+ exports.requireMeasuredMean = require_evaluation.requireMeasuredMean;
266
+ exports.runFingerprint = require_evaluation.runFingerprint;
@@ -0,0 +1,221 @@
1
+ import { a as EvaluationContext, c as RolloutUsage, d as UsageTotals, f as componentNames, i as EvaluationBatch, l as ScoreResult, n as Candidate, o as EvaluationPhase, r as EvaluateArgs, s as EvaluationSplit, t as Adapter, u as TextModel } from "./types-CWv4IQFF.cjs";
2
+ import { n as EvaluationCache, r as createMemoryCache, t as CachedScore } from "./cache-CuSo0NJ8.cjs";
3
+ import { t as Rng } from "./rng-BR5MOedA.cjs";
4
+ import { a as formatDemos, i as bootstrapDemos, n as Demo, o as parseDemos, r as DemoRenderer, t as BootstrapResult } from "./demos-BTuzFNsp.cjs";
5
+ import { a as EvaluateBatchArgs, c as Evaluator, d as costExhausted, f as createEvaluator, g as createBudget, h as Budget, i as BudgetExhausted, l as RetryPolicy, m as requireMeasuredMean, n as OptimizerResult, o as EvaluateTracedArgs, p as measuredMean, r as OptimizerTask, s as EvaluationEvent, t as Optimizer, u as ScoredBatch } from "./optimizer-B7SpRwl7.cjs";
6
+ import { t as BatchSampler } from "./sampling-axOwfZf5.cjs";
7
+ //#region src/checkpoint.d.ts
8
+ /**
9
+ * Identifies the run a checkpoint came from: seed candidate, instance ids,
10
+ * seed, and cache namespace.
11
+ *
12
+ * Hashed rather than embedded, because it goes into every snapshot and is only
13
+ * ever compared for equality. The namespace is part of it because a snapshot
14
+ * carries cached scores, and resuming under a different one would replay
15
+ * measurements of a system the run is no longer running. The test set is
16
+ * deliberately absent: it never touches selection, so adding one to a resumed
17
+ * run changes nothing about what that run would have done.
18
+ */
19
+ declare function runFingerprint(args: {
20
+ seedCandidate: Candidate;
21
+ trainingIds: readonly string[];
22
+ validationIds: readonly string[];
23
+ seed?: number;
24
+ cacheNamespace?: string;
25
+ }): string;
26
+ /**
27
+ * Refuses a checkpoint from a different run rather than silently scoring old
28
+ * candidates against new data — the failure mode that produces a plausible
29
+ * result nobody can reproduce.
30
+ */
31
+ declare function assertResumable(args: {
32
+ fingerprint: string;
33
+ snapshot?: {
34
+ fingerprint: string;
35
+ };
36
+ }): void;
37
+ /** A candidate's identity: component names and their text, order-independent. */
38
+ declare function candidateFingerprint<K extends string>(candidate: Candidate<K>): string;
39
+ //#endregion
40
+ //#region src/compare.d.ts
41
+ interface ComparisonRun {
42
+ entrant: string;
43
+ seed: number;
44
+ /** What the entrants are ranked on: the held-out score when there is one. */
45
+ score: number;
46
+ bestScore: number;
47
+ testScore?: number;
48
+ metricCalls: number;
49
+ costUsd: number;
50
+ stopReason: string;
51
+ }
52
+ interface ComparisonSummary {
53
+ entrant: string;
54
+ runs: number;
55
+ meanScore: number;
56
+ sdScore: number;
57
+ minScore: number;
58
+ maxScore: number;
59
+ meanMetricCalls: number;
60
+ meanCostUsd: number;
61
+ /**
62
+ * How often the winner's margin over this entrant would arise if the two
63
+ * were equally good and each seed's outcome were a coin flip. Absent for the
64
+ * winner itself.
65
+ */
66
+ pValueVsWinner?: number;
67
+ }
68
+ interface Comparison {
69
+ /** Highest mean score. Read `pValueVsWinner` before believing it. */
70
+ winner: string;
71
+ summaries: ComparisonSummary[];
72
+ runs: ComparisonRun[];
73
+ }
74
+ /**
75
+ * Run several optimizers over the same seeds and report which one actually won.
76
+ *
77
+ * Two things make this worth a helper rather than a for-loop. The first is that
78
+ * it ranks on `testScore` where a run reports one: the validation score is the
79
+ * number the search selected against for its whole run, so an entrant that
80
+ * overfits looks strongest on exactly the number it fitted. The second is that
81
+ * a difference in means over a handful of seeds is usually noise, and the
82
+ * paired sign-flip p-value against the winner is what says whether it is.
83
+ *
84
+ * Entrants are functions of a seed rather than optimizer instances, because the
85
+ * seed is constructor config and every optimizer here is deterministic given
86
+ * one — comparing two entrants at a single seed compares two anecdotes. It also
87
+ * leaves the task where the caller builds it, which is the only place the
88
+ * optimizer-specific parts of it (`reflect`, `cache`, `onEvent`) are known.
89
+ */
90
+ declare function compare<K extends string, Output = unknown>(args: {
91
+ entrants: Record<string, (args: {
92
+ seed: number;
93
+ }) => Promise<OptimizerResult<K, string, Output>>>;
94
+ seeds: readonly number[];
95
+ /** Runs in flight at once. Default 1. */
96
+ concurrency?: number;
97
+ }): Promise<Comparison>;
98
+ //#endregion
99
+ //#region src/concurrency.d.ts
100
+ /**
101
+ * Order-preserving concurrency-limited map. An optimization run's workload is
102
+ * entirely IO bound, so adapters use this to fan out a batch across a bounded
103
+ * number of in-flight model calls.
104
+ */
105
+ declare function mapWithConcurrency<Item, Result>(args: {
106
+ items: readonly Item[];
107
+ limit: number;
108
+ task: (item: Item, index: number) => Promise<Result>;
109
+ /**
110
+ * Checked before each dispatch. Aborting stops the fan-out rather than
111
+ * letting the remaining batch items spend rollouts on a cancelled run.
112
+ */
113
+ signal?: AbortSignal;
114
+ }): Promise<Result[]>;
115
+ //#endregion
116
+ //#region src/deadline.d.ts
117
+ interface Deadline {
118
+ exceeded(): boolean;
119
+ /** Milliseconds left, `Infinity` when no limit was set. Never negative. */
120
+ remainingMs(): number;
121
+ }
122
+ /**
123
+ * A wall-clock limit on a run.
124
+ *
125
+ * Rollout and cost ceilings both bound what a run *spends*, and neither bounds
126
+ * how long it takes: a run waiting on a rate-limited provider can sit for an
127
+ * hour without spending a dollar. A deadline is what makes an optimizer safe to
128
+ * put behind a request timeout or a nightly job.
129
+ *
130
+ * Checked between evaluations, so a run overruns by at most the length of one.
131
+ * The clock is injectable because a deadline that can only be tested by waiting
132
+ * is a deadline nobody tests.
133
+ */
134
+ declare function createDeadline(args: {
135
+ maxWallClockMs?: number;
136
+ now?: () => number;
137
+ }): Deadline;
138
+ //#endregion
139
+ //#region src/judge.d.ts
140
+ /** One thing the judge grades, and what a perfect answer looks like for it. */
141
+ interface JudgeCriterion {
142
+ name: string;
143
+ description: string;
144
+ }
145
+ type JudgePromptBuilder = (args: {
146
+ input: string;
147
+ output: string;
148
+ expected?: string;
149
+ criteria: readonly JudgeCriterion[];
150
+ scale: number;
151
+ }) => string;
152
+ type Judge<Datum, Output> = (args: {
153
+ input: Datum;
154
+ output: Output;
155
+ /** The gold answer, when the caller has one. */
156
+ expected?: Output;
157
+ signal?: AbortSignal;
158
+ }) => Promise<ScoreResult>;
159
+ /**
160
+ * A model-graded metric that returns written feedback alongside the score.
161
+ *
162
+ * The feedback is the point. A judge that returns only a number reduces a whole
163
+ * paragraph of diagnosis to one scalar, and reflective search — the thing most
164
+ * likely to be pointed at a task too open-ended to score by string match — runs
165
+ * on exactly that diagnosis. So the prompt demands feedback, and demands it be
166
+ * addressed to the instructions rather than to the graded output: "this answer
167
+ * should have mentioned the refund window" tells a rewriting model nothing that
168
+ * "the instruction never says to state the refund window" does not say better.
169
+ *
170
+ * Grades on a small integer scale and normalizes afterwards. Models discriminate
171
+ * between 2 and 4 far more reliably than between 0.4 and 0.8, and the scale is
172
+ * the caller's to widen once they have seen the judge bunch its answers.
173
+ */
174
+ declare function createJudge<Datum = string, Output = string>(args: {
175
+ model: TextModel;
176
+ criteria: readonly JudgeCriterion[];
177
+ /** Highest grade the judge may award per criterion. Default 5. */
178
+ scale?: number;
179
+ renderInput?: (input: Datum) => string;
180
+ renderOutput?: (output: Output) => string;
181
+ buildPrompt?: JudgePromptBuilder;
182
+ }): Judge<Datum, Output>;
183
+ declare function buildJudgePrompt(args: {
184
+ input: string;
185
+ output: string;
186
+ expected?: string;
187
+ criteria: readonly JudgeCriterion[];
188
+ scale: number;
189
+ }): string;
190
+ //#endregion
191
+ //#region src/text.d.ts
192
+ /**
193
+ * Pull the proposed text out of the reflection model's response.
194
+ *
195
+ * Spans the *first* fence to the *last* one rather than matching blocks
196
+ * individually: proposed instructions routinely contain their own fenced
197
+ * examples, and per-block matching would silently return only the trailing
198
+ * fragment. A response with a single fence was truncated mid-generation, so the
199
+ * stray fence is stripped and the partial text kept.
200
+ */
201
+ declare function parseProposedText(response: string): string;
202
+ //#endregion
203
+ //#region src/usage.d.ts
204
+ /** What a model charges, in the per-million-tokens units every vendor quotes. */
205
+ interface TokenPricing {
206
+ inputPerMillionUsd: number;
207
+ outputPerMillionUsd: number;
208
+ }
209
+ /**
210
+ * Costs a token reading, leaving it untouched when no price list is given.
211
+ *
212
+ * Prices belong to the caller rather than to this library: they change without
213
+ * warning, differ per account, and a stale table baked in here would report
214
+ * confident numbers that are quietly wrong.
215
+ */
216
+ declare function priceUsage(args: {
217
+ usage: RolloutUsage;
218
+ pricing?: TokenPricing;
219
+ }): RolloutUsage;
220
+ //#endregion
221
+ export { type Adapter, type BatchSampler, type BootstrapResult, type Budget, BudgetExhausted, type CachedScore, type Candidate, type Comparison, type ComparisonRun, type ComparisonSummary, type Deadline, type Demo, type DemoRenderer, type EvaluateArgs, type EvaluateBatchArgs, type EvaluateTracedArgs, type EvaluationBatch, type EvaluationCache, type EvaluationContext, type EvaluationEvent, type EvaluationPhase, type EvaluationSplit, type Evaluator, type Judge, type JudgeCriterion, type JudgePromptBuilder, type Optimizer, type OptimizerResult, type OptimizerTask, type RetryPolicy, type Rng, type RolloutUsage, type ScoreResult, type ScoredBatch, type TextModel, type TokenPricing, type UsageTotals, assertResumable, bootstrapDemos, buildJudgePrompt, candidateFingerprint, compare, componentNames, costExhausted, createBudget, createDeadline, createEvaluator, createJudge, createMemoryCache, formatDemos, mapWithConcurrency, measuredMean, parseDemos, parseProposedText, priceUsage, requireMeasuredMean, runFingerprint };