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
@@ -0,0 +1,155 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_reflection = require("./reflection-DRfbk6hu.cjs");
3
+ //#region src/testing.ts
4
+ const KEYWORD_EXAMPLES = [
5
+ {
6
+ question: "How do I reset a device?",
7
+ required: ["hold", "ten seconds"]
8
+ },
9
+ {
10
+ question: "How do I contact support?",
11
+ required: ["ticket", "portal"]
12
+ },
13
+ {
14
+ question: "What is the refund window?",
15
+ required: ["thirty days"]
16
+ },
17
+ {
18
+ question: "How do I upgrade a plan?",
19
+ required: ["billing", "prorated"]
20
+ }
21
+ ];
22
+ /** Terms the keyword metric rewards, interleaved with terms it ignores. */
23
+ const SAMPLING_POOL = [
24
+ "hold",
25
+ "sprocket",
26
+ "ten seconds",
27
+ "lorem",
28
+ "ticket",
29
+ "widget",
30
+ "portal",
31
+ "colour",
32
+ "thirty days",
33
+ "ipsum",
34
+ "billing",
35
+ "gizmo",
36
+ "prorated",
37
+ "flange"
38
+ ];
39
+ function createKeywordAdapter() {
40
+ return {
41
+ evaluate: ({ batch, candidate }) => {
42
+ const answer = Object.values(candidate).join(" ");
43
+ const trajectories = [];
44
+ const scores = [];
45
+ const feedback = [];
46
+ for (const example of batch) {
47
+ const missing = example.required.filter((term) => !answer.toLowerCase().includes(term.toLowerCase()));
48
+ const score = (example.required.length - missing.length) / example.required.length;
49
+ scores.push(score);
50
+ feedback.push(missing.length === 0 ? "All required terms present." : `Missing required terms: ${missing.join(", ")}`);
51
+ trajectories.push({
52
+ question: example.question,
53
+ instruction: answer,
54
+ answer,
55
+ missing
56
+ });
57
+ }
58
+ return {
59
+ outputs: trajectories.map((trajectory) => trajectory.answer),
60
+ scores,
61
+ feedback,
62
+ trajectories
63
+ };
64
+ },
65
+ makeReflectiveDataset: ({ batch, evaluation, componentsToUpdate }) => {
66
+ const records = batch.map((example, index) => ({
67
+ inputs: { question: example.question },
68
+ generatedOutputs: evaluation.outputs[index] ?? "",
69
+ feedback: evaluation.feedback?.[index] ?? "",
70
+ score: evaluation.scores[index]
71
+ }));
72
+ return Object.fromEntries(componentsToUpdate.map((component) => [component, records]));
73
+ }
74
+ };
75
+ }
76
+ /**
77
+ * A deterministic stand-in for a reflection model: it reads the feedback in the
78
+ * prompt and folds the missing terms into the current instruction.
79
+ */
80
+ function createKeywordReflector() {
81
+ return async ({ prompt }) => {
82
+ const current = extractCurrentInstruction(prompt);
83
+ return `\`\`\`\n${[current, ...extractMissingTerms(prompt).filter((term) => !current.toLowerCase().includes(term.toLowerCase()))].filter(Boolean).join(" ")}\n\`\`\``;
84
+ };
85
+ }
86
+ /**
87
+ * A stand-in for a model asked to rewrite text it has been told nothing about.
88
+ * It appends one term per call, cycling a pool in which only every other entry
89
+ * is useful — which is what blind proposal actually is: a draw from a space
90
+ * where some samples happen to help.
91
+ *
92
+ * Feedback-driven reflectors read the prompt; this one deliberately does not,
93
+ * so a search using it cannot benefit from evidence even if it is offered.
94
+ */
95
+ function createSamplingReflector(args = {}) {
96
+ const { pool = SAMPLING_POOL } = args;
97
+ let cursor = 0;
98
+ return async ({ prompt }) => {
99
+ const term = pool[cursor % pool.length];
100
+ cursor += 1;
101
+ return `\`\`\`\n${[extractCurrentInstruction(prompt), term].filter(Boolean).join(" ")}\n\`\`\``;
102
+ };
103
+ }
104
+ /**
105
+ * A stand-in for a model that reads a score history and climbs it: it takes
106
+ * the highest-scoring attempt it is shown, keeps it, and extends it by one
107
+ * term. Unlike `createSamplingReflector` it depends on the prompt carrying
108
+ * scores, so a search that shows it none makes no progress with it.
109
+ */
110
+ function createHillClimbingReflector(args = {}) {
111
+ const { pool = SAMPLING_POOL } = args;
112
+ let cursor = 0;
113
+ return async ({ prompt }) => {
114
+ const best = extractBestAttempt(prompt);
115
+ const term = pool[cursor % pool.length];
116
+ cursor += 1;
117
+ return `\`\`\`\n${[best, term].filter(Boolean).join(" ")}\n\`\`\``;
118
+ };
119
+ }
120
+ /** A reflection model that always proposes something strictly worse. */
121
+ function createDegradingReflector() {
122
+ return async () => "```\nno useful information\n```";
123
+ }
124
+ function extractCurrentInstruction(prompt) {
125
+ return prompt.match(/<current_instruction>\n([\s\S]*?)\n<\/current_instruction>/)?.[1]?.trim() ?? "";
126
+ }
127
+ /** The instruction beside the highest score in a scored-attempt prompt. */
128
+ function extractBestAttempt(prompt) {
129
+ let bestScore = Number.NEGATIVE_INFINITY;
130
+ let best = "";
131
+ for (const match of prompt.matchAll(/score:\s*([\d.]+)[\s\S]*?<instruction>\n?([\s\S]*?)\n?<\/instruction>/g)) {
132
+ const score = Number(match[1]);
133
+ if (score > bestScore) {
134
+ bestScore = score;
135
+ best = (match[2] ?? "").trim();
136
+ }
137
+ }
138
+ return best;
139
+ }
140
+ function extractMissingTerms(prompt) {
141
+ const terms = /* @__PURE__ */ new Set();
142
+ for (const match of prompt.matchAll(/Missing required terms: ([^"\\\n]+)/g)) for (const term of (match[1] ?? "").split(",")) {
143
+ const trimmed = term.trim();
144
+ if (trimmed.length > 0) terms.add(trimmed);
145
+ }
146
+ return [...terms];
147
+ }
148
+ //#endregion
149
+ exports.KEYWORD_EXAMPLES = KEYWORD_EXAMPLES;
150
+ exports.buildReflectionPrompt = require_reflection.buildReflectionPrompt;
151
+ exports.createDegradingReflector = createDegradingReflector;
152
+ exports.createHillClimbingReflector = createHillClimbingReflector;
153
+ exports.createKeywordAdapter = createKeywordAdapter;
154
+ exports.createKeywordReflector = createKeywordReflector;
155
+ exports.createSamplingReflector = createSamplingReflector;
@@ -0,0 +1,53 @@
1
+ import { u as TextModel } from "./types-CWv4IQFF.cjs";
2
+ import { i as buildReflectionPrompt, m as GepaAdapter } from "./reflection-CQToe-5B.cjs";
3
+ //#region src/testing.d.ts
4
+ /**
5
+ * A deterministic, LLM-free system under optimization.
6
+ *
7
+ * It exists so the engine, and any adapter you write, can be exercised end to
8
+ * end in milliseconds: the "model" answers with the candidate text itself and
9
+ * the metric rewards covering the required terms. Optimization therefore has a
10
+ * real gradient to climb without a single network call.
11
+ */
12
+ interface KeywordExample {
13
+ question: string;
14
+ required: string[];
15
+ }
16
+ interface KeywordTrajectory {
17
+ question: string;
18
+ instruction: string;
19
+ answer: string;
20
+ missing: string[];
21
+ }
22
+ declare const KEYWORD_EXAMPLES: KeywordExample[];
23
+ declare function createKeywordAdapter(): GepaAdapter<KeywordExample, KeywordTrajectory, string>;
24
+ /**
25
+ * A deterministic stand-in for a reflection model: it reads the feedback in the
26
+ * prompt and folds the missing terms into the current instruction.
27
+ */
28
+ declare function createKeywordReflector(): TextModel;
29
+ /**
30
+ * A stand-in for a model asked to rewrite text it has been told nothing about.
31
+ * It appends one term per call, cycling a pool in which only every other entry
32
+ * is useful — which is what blind proposal actually is: a draw from a space
33
+ * where some samples happen to help.
34
+ *
35
+ * Feedback-driven reflectors read the prompt; this one deliberately does not,
36
+ * so a search using it cannot benefit from evidence even if it is offered.
37
+ */
38
+ declare function createSamplingReflector(args?: {
39
+ pool?: readonly string[];
40
+ }): TextModel;
41
+ /**
42
+ * A stand-in for a model that reads a score history and climbs it: it takes
43
+ * the highest-scoring attempt it is shown, keeps it, and extends it by one
44
+ * term. Unlike `createSamplingReflector` it depends on the prompt carrying
45
+ * scores, so a search that shows it none makes no progress with it.
46
+ */
47
+ declare function createHillClimbingReflector(args?: {
48
+ pool?: readonly string[];
49
+ }): TextModel;
50
+ /** A reflection model that always proposes something strictly worse. */
51
+ declare function createDegradingReflector(): TextModel;
52
+ //#endregion
53
+ export { KEYWORD_EXAMPLES, KeywordExample, KeywordTrajectory, buildReflectionPrompt, createDegradingReflector, createHillClimbingReflector, createKeywordAdapter, createKeywordReflector, createSamplingReflector };
@@ -0,0 +1,53 @@
1
+ import { u as TextModel } from "./types-CWv4IQFF.mjs";
2
+ import { i as buildReflectionPrompt, m as GepaAdapter } from "./reflection-Cr_upzU0.mjs";
3
+ //#region src/testing.d.ts
4
+ /**
5
+ * A deterministic, LLM-free system under optimization.
6
+ *
7
+ * It exists so the engine, and any adapter you write, can be exercised end to
8
+ * end in milliseconds: the "model" answers with the candidate text itself and
9
+ * the metric rewards covering the required terms. Optimization therefore has a
10
+ * real gradient to climb without a single network call.
11
+ */
12
+ interface KeywordExample {
13
+ question: string;
14
+ required: string[];
15
+ }
16
+ interface KeywordTrajectory {
17
+ question: string;
18
+ instruction: string;
19
+ answer: string;
20
+ missing: string[];
21
+ }
22
+ declare const KEYWORD_EXAMPLES: KeywordExample[];
23
+ declare function createKeywordAdapter(): GepaAdapter<KeywordExample, KeywordTrajectory, string>;
24
+ /**
25
+ * A deterministic stand-in for a reflection model: it reads the feedback in the
26
+ * prompt and folds the missing terms into the current instruction.
27
+ */
28
+ declare function createKeywordReflector(): TextModel;
29
+ /**
30
+ * A stand-in for a model asked to rewrite text it has been told nothing about.
31
+ * It appends one term per call, cycling a pool in which only every other entry
32
+ * is useful — which is what blind proposal actually is: a draw from a space
33
+ * where some samples happen to help.
34
+ *
35
+ * Feedback-driven reflectors read the prompt; this one deliberately does not,
36
+ * so a search using it cannot benefit from evidence even if it is offered.
37
+ */
38
+ declare function createSamplingReflector(args?: {
39
+ pool?: readonly string[];
40
+ }): TextModel;
41
+ /**
42
+ * A stand-in for a model that reads a score history and climbs it: it takes
43
+ * the highest-scoring attempt it is shown, keeps it, and extends it by one
44
+ * term. Unlike `createSamplingReflector` it depends on the prompt carrying
45
+ * scores, so a search that shows it none makes no progress with it.
46
+ */
47
+ declare function createHillClimbingReflector(args?: {
48
+ pool?: readonly string[];
49
+ }): TextModel;
50
+ /** A reflection model that always proposes something strictly worse. */
51
+ declare function createDegradingReflector(): TextModel;
52
+ //#endregion
53
+ export { KEYWORD_EXAMPLES, KeywordExample, KeywordTrajectory, buildReflectionPrompt, createDegradingReflector, createHillClimbingReflector, createKeywordAdapter, createKeywordReflector, createSamplingReflector };
@@ -0,0 +1,148 @@
1
+ import { n as buildReflectionPrompt } from "./reflection-mwMhrjs_.mjs";
2
+ //#region src/testing.ts
3
+ const KEYWORD_EXAMPLES = [
4
+ {
5
+ question: "How do I reset a device?",
6
+ required: ["hold", "ten seconds"]
7
+ },
8
+ {
9
+ question: "How do I contact support?",
10
+ required: ["ticket", "portal"]
11
+ },
12
+ {
13
+ question: "What is the refund window?",
14
+ required: ["thirty days"]
15
+ },
16
+ {
17
+ question: "How do I upgrade a plan?",
18
+ required: ["billing", "prorated"]
19
+ }
20
+ ];
21
+ /** Terms the keyword metric rewards, interleaved with terms it ignores. */
22
+ const SAMPLING_POOL = [
23
+ "hold",
24
+ "sprocket",
25
+ "ten seconds",
26
+ "lorem",
27
+ "ticket",
28
+ "widget",
29
+ "portal",
30
+ "colour",
31
+ "thirty days",
32
+ "ipsum",
33
+ "billing",
34
+ "gizmo",
35
+ "prorated",
36
+ "flange"
37
+ ];
38
+ function createKeywordAdapter() {
39
+ return {
40
+ evaluate: ({ batch, candidate }) => {
41
+ const answer = Object.values(candidate).join(" ");
42
+ const trajectories = [];
43
+ const scores = [];
44
+ const feedback = [];
45
+ for (const example of batch) {
46
+ const missing = example.required.filter((term) => !answer.toLowerCase().includes(term.toLowerCase()));
47
+ const score = (example.required.length - missing.length) / example.required.length;
48
+ scores.push(score);
49
+ feedback.push(missing.length === 0 ? "All required terms present." : `Missing required terms: ${missing.join(", ")}`);
50
+ trajectories.push({
51
+ question: example.question,
52
+ instruction: answer,
53
+ answer,
54
+ missing
55
+ });
56
+ }
57
+ return {
58
+ outputs: trajectories.map((trajectory) => trajectory.answer),
59
+ scores,
60
+ feedback,
61
+ trajectories
62
+ };
63
+ },
64
+ makeReflectiveDataset: ({ batch, evaluation, componentsToUpdate }) => {
65
+ const records = batch.map((example, index) => ({
66
+ inputs: { question: example.question },
67
+ generatedOutputs: evaluation.outputs[index] ?? "",
68
+ feedback: evaluation.feedback?.[index] ?? "",
69
+ score: evaluation.scores[index]
70
+ }));
71
+ return Object.fromEntries(componentsToUpdate.map((component) => [component, records]));
72
+ }
73
+ };
74
+ }
75
+ /**
76
+ * A deterministic stand-in for a reflection model: it reads the feedback in the
77
+ * prompt and folds the missing terms into the current instruction.
78
+ */
79
+ function createKeywordReflector() {
80
+ return async ({ prompt }) => {
81
+ const current = extractCurrentInstruction(prompt);
82
+ return `\`\`\`\n${[current, ...extractMissingTerms(prompt).filter((term) => !current.toLowerCase().includes(term.toLowerCase()))].filter(Boolean).join(" ")}\n\`\`\``;
83
+ };
84
+ }
85
+ /**
86
+ * A stand-in for a model asked to rewrite text it has been told nothing about.
87
+ * It appends one term per call, cycling a pool in which only every other entry
88
+ * is useful — which is what blind proposal actually is: a draw from a space
89
+ * where some samples happen to help.
90
+ *
91
+ * Feedback-driven reflectors read the prompt; this one deliberately does not,
92
+ * so a search using it cannot benefit from evidence even if it is offered.
93
+ */
94
+ function createSamplingReflector(args = {}) {
95
+ const { pool = SAMPLING_POOL } = args;
96
+ let cursor = 0;
97
+ return async ({ prompt }) => {
98
+ const term = pool[cursor % pool.length];
99
+ cursor += 1;
100
+ return `\`\`\`\n${[extractCurrentInstruction(prompt), term].filter(Boolean).join(" ")}\n\`\`\``;
101
+ };
102
+ }
103
+ /**
104
+ * A stand-in for a model that reads a score history and climbs it: it takes
105
+ * the highest-scoring attempt it is shown, keeps it, and extends it by one
106
+ * term. Unlike `createSamplingReflector` it depends on the prompt carrying
107
+ * scores, so a search that shows it none makes no progress with it.
108
+ */
109
+ function createHillClimbingReflector(args = {}) {
110
+ const { pool = SAMPLING_POOL } = args;
111
+ let cursor = 0;
112
+ return async ({ prompt }) => {
113
+ const best = extractBestAttempt(prompt);
114
+ const term = pool[cursor % pool.length];
115
+ cursor += 1;
116
+ return `\`\`\`\n${[best, term].filter(Boolean).join(" ")}\n\`\`\``;
117
+ };
118
+ }
119
+ /** A reflection model that always proposes something strictly worse. */
120
+ function createDegradingReflector() {
121
+ return async () => "```\nno useful information\n```";
122
+ }
123
+ function extractCurrentInstruction(prompt) {
124
+ return prompt.match(/<current_instruction>\n([\s\S]*?)\n<\/current_instruction>/)?.[1]?.trim() ?? "";
125
+ }
126
+ /** The instruction beside the highest score in a scored-attempt prompt. */
127
+ function extractBestAttempt(prompt) {
128
+ let bestScore = Number.NEGATIVE_INFINITY;
129
+ let best = "";
130
+ for (const match of prompt.matchAll(/score:\s*([\d.]+)[\s\S]*?<instruction>\n?([\s\S]*?)\n?<\/instruction>/g)) {
131
+ const score = Number(match[1]);
132
+ if (score > bestScore) {
133
+ bestScore = score;
134
+ best = (match[2] ?? "").trim();
135
+ }
136
+ }
137
+ return best;
138
+ }
139
+ function extractMissingTerms(prompt) {
140
+ const terms = /* @__PURE__ */ new Set();
141
+ for (const match of prompt.matchAll(/Missing required terms: ([^"\\\n]+)/g)) for (const term of (match[1] ?? "").split(",")) {
142
+ const trimmed = term.trim();
143
+ if (trimmed.length > 0) terms.add(trimmed);
144
+ }
145
+ return [...terms];
146
+ }
147
+ //#endregion
148
+ export { KEYWORD_EXAMPLES, buildReflectionPrompt, createDegradingReflector, createHillClimbingReflector, createKeywordAdapter, createKeywordReflector, createSamplingReflector };
@@ -0,0 +1,21 @@
1
+ //#region src/text.ts
2
+ const LANGUAGE_TAG = /^[a-zA-Z0-9_+.-]*\n/;
3
+ const DANGLING_OPEN_FENCE = /^\s*```\S*\n?/;
4
+ const DANGLING_CLOSE_FENCE = /\n?```\s*$/;
5
+ /**
6
+ * Pull the proposed text out of the reflection model's response.
7
+ *
8
+ * Spans the *first* fence to the *last* one rather than matching blocks
9
+ * individually: proposed instructions routinely contain their own fenced
10
+ * examples, and per-block matching would silently return only the trailing
11
+ * fragment. A response with a single fence was truncated mid-generation, so the
12
+ * stray fence is stripped and the partial text kept.
13
+ */
14
+ function parseProposedText(response) {
15
+ const start = response.indexOf("```");
16
+ const end = response.lastIndexOf("```");
17
+ if (start !== -1 && start !== end) return response.slice(start + 3, end).replace(LANGUAGE_TAG, "").trim();
18
+ return response.replace(DANGLING_OPEN_FENCE, "").replace(DANGLING_CLOSE_FENCE, "").trim();
19
+ }
20
+ //#endregion
21
+ export { parseProposedText as t };
@@ -0,0 +1,26 @@
1
+ //#region src/text.ts
2
+ const LANGUAGE_TAG = /^[a-zA-Z0-9_+.-]*\n/;
3
+ const DANGLING_OPEN_FENCE = /^\s*```\S*\n?/;
4
+ const DANGLING_CLOSE_FENCE = /\n?```\s*$/;
5
+ /**
6
+ * Pull the proposed text out of the reflection model's response.
7
+ *
8
+ * Spans the *first* fence to the *last* one rather than matching blocks
9
+ * individually: proposed instructions routinely contain their own fenced
10
+ * examples, and per-block matching would silently return only the trailing
11
+ * fragment. A response with a single fence was truncated mid-generation, so the
12
+ * stray fence is stripped and the partial text kept.
13
+ */
14
+ function parseProposedText(response) {
15
+ const start = response.indexOf("```");
16
+ const end = response.lastIndexOf("```");
17
+ if (start !== -1 && start !== end) return response.slice(start + 3, end).replace(LANGUAGE_TAG, "").trim();
18
+ return response.replace(DANGLING_OPEN_FENCE, "").replace(DANGLING_CLOSE_FENCE, "").trim();
19
+ }
20
+ //#endregion
21
+ Object.defineProperty(exports, "parseProposedText", {
22
+ enumerable: true,
23
+ get: function() {
24
+ return parseProposedText;
25
+ }
26
+ });
@@ -0,0 +1,129 @@
1
+ //#region src/types.d.ts
2
+ /**
3
+ * A candidate is a map of named text components to their current text. This is
4
+ * the unit of optimization — prompts, instructions, code, tool descriptions,
5
+ * anything expressible as a named string.
6
+ *
7
+ * `K` is the union of component names, inferred from the seed candidate, so a
8
+ * misspelled component is a compile error rather than a silent no-op.
9
+ */
10
+ type Candidate<K extends string = string> = Record<K, string>;
11
+ /**
12
+ * What one rollout consumed. Every field is optional because providers report
13
+ * different subsets, and a partial reading is still worth more than none.
14
+ */
15
+ interface RolloutUsage {
16
+ inputTokens?: number;
17
+ outputTokens?: number;
18
+ /** Defaults to the sum of the two token counts when they are reported. */
19
+ totalTokens?: number;
20
+ costUsd?: number;
21
+ }
22
+ /** Usage summed over a run, alongside the rollouts that produced it. */
23
+ interface UsageTotals {
24
+ inputTokens: number;
25
+ outputTokens: number;
26
+ totalTokens: number;
27
+ costUsd: number;
28
+ /** Fresh rollouts counted here. Cached instances buy nothing. */
29
+ rollouts: number;
30
+ }
31
+ /**
32
+ * Result of running a candidate over a batch of data instances.
33
+ *
34
+ * `scores` is the load-bearing field: one number per instance, higher is
35
+ * better. `feedback` is a per-instance textual diagnosis of what went wrong,
36
+ * which a reflective optimizer reads to write a better candidate.
37
+ */
38
+ interface EvaluationBatch<Trajectory = unknown, Output = unknown> {
39
+ outputs: Output[];
40
+ scores: number[];
41
+ /**
42
+ * What each rollout consumed. Rollout counts are the budget, but they are a
43
+ * poor proxy for spend: reflective search grows the text it optimizes, so
44
+ * the same rollout costs more late in a run than early in it.
45
+ */
46
+ usage?: RolloutUsage[];
47
+ feedback?: string[];
48
+ trajectories?: Trajectory[];
49
+ objectiveScores?: Record<string, number>[];
50
+ /**
51
+ * Per-instance: true when the score reflects an infrastructure failure
52
+ * rather than the candidate's behaviour. Transient scores are never written
53
+ * to the evaluation cache.
54
+ */
55
+ transient?: boolean[];
56
+ }
57
+ /**
58
+ * What a per-instance scorer returns. Shared by every adapter so scorers are
59
+ * portable between them — a Braintrust scorer works in a LangChain run.
60
+ */
61
+ interface ScoreResult {
62
+ score: number;
63
+ feedback?: string;
64
+ objectiveScores?: Record<string, number>;
65
+ /** What this rollout consumed, when the caller can see it. */
66
+ usage?: RolloutUsage;
67
+ /**
68
+ * Marks a score produced by an infrastructure failure — a rate limit, a
69
+ * network blip, a provider 5xx — rather than by the candidate. Without this
70
+ * the engine cannot tell such a zero from a genuine one, and would cache it
71
+ * permanently against the candidate.
72
+ */
73
+ transient?: boolean;
74
+ }
75
+ interface EvaluateArgs<Datum, K extends string = string> {
76
+ batch: readonly Datum[];
77
+ candidate: Candidate<K>;
78
+ captureTraces: boolean;
79
+ /**
80
+ * Where this batch sits in the run. Forward it to whatever tracing the
81
+ * system under optimization already has — without it a run is thousands of
82
+ * indistinguishable rollouts, and no trace can be tied back to the iteration
83
+ * whose score moved.
84
+ */
85
+ run: EvaluationContext;
86
+ signal?: AbortSignal;
87
+ }
88
+ /**
89
+ * Identifies one evaluation within a run. `candidateId` is null while the
90
+ * candidate is still a proposal being screened on a minibatch: it has no
91
+ * record, and inventing an id for it would collide with the one it gets if it
92
+ * is accepted.
93
+ */
94
+ interface EvaluationContext {
95
+ iteration: number;
96
+ phase: EvaluationPhase;
97
+ split: EvaluationSplit;
98
+ candidateId: number | null;
99
+ }
100
+ type EvaluationPhase = "seed" | "minibatch" | "validation" | "test";
101
+ /**
102
+ * Which dataset an instance id was drawn from. Each split numbers its ids
103
+ * independently, so the same id can name three different instances; the cache
104
+ * key has to keep them apart.
105
+ */
106
+ type EvaluationSplit = "train" | "val" | "test";
107
+ /**
108
+ * The single integration seam between an optimizer and a system under
109
+ * optimization. Everything framework-specific — LangChain, the AI SDK,
110
+ * Braintrust — lives in an implementation of this interface.
111
+ */
112
+ interface Adapter<Datum, Trajectory = unknown, Output = unknown, K extends string = string> {
113
+ evaluate(args: EvaluateArgs<Datum, K>): Promise<EvaluationBatch<Trajectory, Output>> | EvaluationBatch<Trajectory, Output>;
114
+ }
115
+ /** Provider-agnostic text model: text in, text out. */
116
+ type TextModel = (args: {
117
+ prompt: string;
118
+ signal?: AbortSignal;
119
+ }) => Promise<string>;
120
+ /**
121
+ * The component names of a candidate, as the union they were inferred from.
122
+ *
123
+ * `Object.keys` widens a closed key union back to `string`. This is the one
124
+ * place that narrowing happens, so every other caller stays assertion-free.
125
+ * Accepts a partial so it also names the components of a component patch.
126
+ */
127
+ declare function componentNames<K extends string>(candidate: Partial<Candidate<K>>): K[];
128
+ //#endregion
129
+ export { EvaluationContext as a, RolloutUsage as c, UsageTotals as d, componentNames as f, EvaluationBatch as i, ScoreResult as l, Candidate as n, EvaluationPhase as o, EvaluateArgs as r, EvaluationSplit as s, Adapter as t, TextModel as u };