@seanhogg/builderforce-memory 2026.9.29 → 2026.9.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bridges/AnthropicBridge.d.ts.map +1 -1
- package/dist/bridges/AnthropicBridge.js +24 -65
- package/dist/bridges/AnthropicBridge.js.map +1 -1
- package/dist/bridges/OpenAIBridge.d.ts.map +1 -1
- package/dist/bridges/OpenAIBridge.js +12 -46
- package/dist/bridges/OpenAIBridge.js.map +1 -1
- package/dist/bridges/VertexAIBridge.d.ts.map +1 -1
- package/dist/bridges/VertexAIBridge.js +3 -34
- package/dist/bridges/VertexAIBridge.js.map +1 -1
- package/dist/distillation/DistillationEngine.d.ts +71 -54
- package/dist/distillation/DistillationEngine.d.ts.map +1 -1
- package/dist/distillation/DistillationEngine.js +112 -95
- package/dist/distillation/DistillationEngine.js.map +1 -1
- package/dist/distillation/index.d.ts +7 -1
- package/dist/distillation/index.d.ts.map +1 -1
- package/dist/distillation/index.js +5 -0
- package/dist/distillation/index.js.map +1 -1
- package/dist/distillation/ports.d.ts +43 -0
- package/dist/distillation/ports.d.ts.map +1 -0
- package/dist/distillation/ports.js +29 -0
- package/dist/distillation/ports.js.map +1 -0
- package/dist/eval/EvalHarness.d.ts +2 -1
- package/dist/eval/EvalHarness.d.ts.map +1 -1
- package/dist/eval/EvalHarness.js +13 -1
- package/dist/eval/EvalHarness.js.map +1 -1
- package/dist/eval/baseline.d.ts +33 -0
- package/dist/eval/baseline.d.ts.map +1 -0
- package/dist/eval/baseline.js +41 -0
- package/dist/eval/baseline.js.map +1 -0
- package/dist/eval/index.d.ts +1 -0
- package/dist/eval/index.d.ts.map +1 -1
- package/dist/eval/index.js +1 -0
- package/dist/eval/index.js.map +1 -1
- package/dist/eval/types.d.ts +7 -0
- package/dist/eval/types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/rag/EnterpriseRetriever.d.ts.map +1 -1
- package/dist/rag/EnterpriseRetriever.js +2 -1
- package/dist/rag/EnterpriseRetriever.js.map +1 -1
- package/dist/retrieval/HybridRetriever.d.ts.map +1 -1
- package/dist/retrieval/HybridRetriever.js +2 -1
- package/dist/retrieval/HybridRetriever.js.map +1 -1
- package/dist/retrieval/decay.d.ts +24 -0
- package/dist/retrieval/decay.d.ts.map +1 -0
- package/dist/retrieval/decay.js +29 -0
- package/dist/retrieval/decay.js.map +1 -0
- package/dist/retrieval/fusion.d.ts +13 -19
- package/dist/retrieval/fusion.d.ts.map +1 -1
- package/dist/retrieval/fusion.js +17 -44
- package/dist/retrieval/fusion.js.map +1 -1
- package/dist/retrieval/index.d.ts +13 -6
- package/dist/retrieval/index.d.ts.map +1 -1
- package/dist/retrieval/index.js +10 -5
- package/dist/retrieval/index.js.map +1 -1
- package/dist/retrieval/mmr.d.ts +60 -0
- package/dist/retrieval/mmr.d.ts.map +1 -0
- package/dist/retrieval/mmr.js +94 -0
- package/dist/retrieval/mmr.js.map +1 -0
- package/dist/retrieval/weightedFusion.d.ts +64 -0
- package/dist/retrieval/weightedFusion.d.ts.map +1 -0
- package/dist/retrieval/weightedFusion.js +80 -0
- package/dist/retrieval/weightedFusion.js.map +1 -0
- package/dist/similarity/index.d.ts +6 -4
- package/dist/similarity/index.d.ts.map +1 -1
- package/dist/similarity/index.js +5 -3
- package/dist/similarity/index.js.map +1 -1
- package/dist/wire/index.d.ts +18 -0
- package/dist/wire/index.d.ts.map +1 -0
- package/dist/wire/index.js +17 -0
- package/dist/wire/index.js.map +1 -0
- package/dist/wire/sse.d.ts +29 -0
- package/dist/wire/sse.d.ts.map +1 -0
- package/dist/wire/sse.js +81 -0
- package/dist/wire/sse.js.map +1 -0
- package/dist/wire/usage.d.ts +46 -0
- package/dist/wire/usage.d.ts.map +1 -0
- package/dist/wire/usage.js +78 -0
- package/dist/wire/usage.js.map +1 -0
- package/package.json +11 -3
- package/src/bridges/AnthropicBridge.ts +24 -68
- package/src/bridges/OpenAIBridge.ts +11 -50
- package/src/bridges/VertexAIBridge.ts +3 -32
- package/src/distillation/DistillationEngine.ts +176 -141
- package/src/distillation/index.ts +15 -1
- package/src/distillation/ports.ts +55 -0
- package/src/eval/EvalHarness.ts +12 -1
- package/src/eval/baseline.ts +51 -0
- package/src/eval/index.ts +1 -0
- package/src/eval/types.ts +7 -0
- package/src/index.ts +5 -2
- package/src/rag/EnterpriseRetriever.ts +2 -1
- package/src/retrieval/HybridRetriever.ts +2 -1
- package/src/retrieval/decay.ts +29 -0
- package/src/retrieval/fusion.ts +19 -52
- package/src/retrieval/index.ts +24 -6
- package/src/retrieval/mmr.ts +126 -0
- package/src/retrieval/weightedFusion.ts +101 -0
- package/src/similarity/index.ts +6 -4
- package/src/wire/index.ts +18 -0
- package/src/wire/sse.ts +74 -0
- package/src/wire/usage.ts +95 -0
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DistillationEngine –
|
|
2
|
+
* DistillationEngine – online knowledge distillation.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* This runs entirely in the browser with no Python or full-retraining required.
|
|
4
|
+
* A *teacher* (a frontier model) writes the ideal response; the *student* is adapted
|
|
5
|
+
* on it. Runs with no Python and no full retraining.
|
|
7
6
|
*
|
|
8
7
|
* Distillation flow:
|
|
9
|
-
* 1.
|
|
10
|
-
* 2.
|
|
11
|
-
* 3.
|
|
8
|
+
* 1. teacher.generate(input) → exemplar
|
|
9
|
+
* 2. quality gate (length / already-learned) → skip, or fall back to the caller's text
|
|
10
|
+
* 3. student.adapt(input + exemplar, + rehearsed past exemplars)
|
|
11
|
+
* 4. log the outcome
|
|
12
|
+
*
|
|
13
|
+
* Teacher and student are ports ({@link ./ports}). Passing an `SSMRuntime` and a
|
|
14
|
+
* `TransformerBridge` — the original pairing — still works unchanged.
|
|
12
15
|
*/
|
|
13
16
|
import { SSMError } from '../errors/SSMError.js';
|
|
17
|
+
import { isDistillationStudent, ssmRuntimeStudent } from './ports.js';
|
|
14
18
|
/** Maximum number of distillation log entries to retain in memory. */
|
|
15
19
|
const MAX_LOG_ENTRIES = 200;
|
|
16
20
|
// ── DistillationEngine ────────────────────────────────────────────────────────
|
|
17
21
|
export class DistillationEngine {
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
_student;
|
|
23
|
+
_teacher;
|
|
20
24
|
_log = [];
|
|
21
25
|
// ── Rehearsal buffer (EVM-5 catastrophic-forgetting guard) ─────────────────
|
|
22
26
|
_rehearsalSize;
|
|
@@ -24,16 +28,16 @@ export class DistillationEngine {
|
|
|
24
28
|
_rehearsal = [];
|
|
25
29
|
_rehearsalState;
|
|
26
30
|
/**
|
|
27
|
-
* @param
|
|
28
|
-
* @param
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* `bufferSize > 0`, each adapt also trains on a sample of past
|
|
32
|
-
* exemplars to guard against catastrophic forgetting.
|
|
31
|
+
* @param student What learns: an `SSMRuntime`, or any {@link DistillationStudent}.
|
|
32
|
+
* @param teacher What teaches: any `TransformerBridge`, or any {@link DistillationTeacher}.
|
|
33
|
+
* @param rehearsal Optional experience-replay config (EVM-5). When `bufferSize > 0`,
|
|
34
|
+
* each adapt also trains on a sample of past exemplars.
|
|
33
35
|
*/
|
|
34
|
-
constructor(
|
|
35
|
-
this.
|
|
36
|
-
|
|
36
|
+
constructor(student, teacher, rehearsal = {}) {
|
|
37
|
+
this._student = isDistillationStudent(student)
|
|
38
|
+
? student
|
|
39
|
+
: ssmRuntimeStudent(student);
|
|
40
|
+
this._teacher = teacher;
|
|
37
41
|
this._rehearsalSize = Math.max(0, rehearsal.bufferSize ?? 0);
|
|
38
42
|
this._rehearsalK = Math.max(0, rehearsal.sampleK ?? 2);
|
|
39
43
|
this._rehearsalState = (rehearsal.seed ?? 1) >>> 0 || 1;
|
|
@@ -73,102 +77,65 @@ export class DistillationEngine {
|
|
|
73
77
|
* Runs a single distillation pass:
|
|
74
78
|
* 1. Teacher generates a response for `input`
|
|
75
79
|
* 2. Quality gate is evaluated (if configured)
|
|
76
|
-
* 3.
|
|
80
|
+
* 3. Student is adapted on `input` + the teacher's output
|
|
77
81
|
*
|
|
78
|
-
* The training signal is the teacher's full response — this teaches the
|
|
79
|
-
*
|
|
80
|
-
* labelled data or a loss function beyond the standard LM objective.
|
|
82
|
+
* The training signal is the teacher's full response — this teaches the student
|
|
83
|
+
* what a good response to that prompt looks like, without labelled data.
|
|
81
84
|
*/
|
|
82
85
|
async distill(input, opts = {}) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
epochs: 3,
|
|
86
|
-
...opts.adapt,
|
|
87
|
-
};
|
|
88
|
-
let teacherOutput;
|
|
86
|
+
let teacherOutput = '';
|
|
87
|
+
let teacherError;
|
|
89
88
|
try {
|
|
90
|
-
teacherOutput = await this.
|
|
89
|
+
teacherOutput = await this._teacher.generate(input, opts.generate);
|
|
91
90
|
}
|
|
92
91
|
catch (err) {
|
|
93
|
-
|
|
92
|
+
if (opts.fallbackText === undefined) {
|
|
93
|
+
throw new SSMError('DISTILL_FAILED', `Teacher bridge failed to generate for distillation: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
94
|
+
}
|
|
95
|
+
teacherError = err;
|
|
96
|
+
}
|
|
97
|
+
if (teacherError !== undefined) {
|
|
98
|
+
return this._learnFallback(input, '', 'teacher_failed', opts, teacherError);
|
|
94
99
|
}
|
|
95
100
|
// ── Quality gate ──────────────────────────────────────────────────────
|
|
96
|
-
// Pre-adapt novelty of this exemplar
|
|
97
|
-
// Measured by the gate below; hoisted so it survives to the TRAINED path instead
|
|
98
|
-
// of being dropped for exactly the exemplars we go on to learn from.
|
|
101
|
+
// Pre-adapt novelty of this exemplar, hoisted so it survives to the TRAINED path.
|
|
99
102
|
let gatePerplexity;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
};
|
|
110
|
-
this._appendLog({
|
|
111
|
-
input,
|
|
112
|
-
teacherOutputLength: teacherOutput.length,
|
|
113
|
-
skipped: true,
|
|
114
|
-
skipReason: 'low_quality',
|
|
115
|
-
epochs: 0,
|
|
116
|
-
});
|
|
117
|
-
return result;
|
|
103
|
+
const gate = opts.qualityGate;
|
|
104
|
+
if (gate?.minLength != null && teacherOutput.length < gate.minLength) {
|
|
105
|
+
if (opts.fallbackText !== undefined)
|
|
106
|
+
return this._learnFallback(input, teacherOutput, 'low_quality', opts);
|
|
107
|
+
return this._skip(input, teacherOutput, 'low_quality');
|
|
108
|
+
}
|
|
109
|
+
if (gate?.maxPerplexity != null && this._student.evaluate) {
|
|
110
|
+
try {
|
|
111
|
+
gatePerplexity = await this._student.evaluate(teacherOutput);
|
|
118
112
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
// Evaluation failure is non-fatal — proceed with adaptation
|
|
125
|
-
}
|
|
126
|
-
if (gatePerplexity != null && gatePerplexity < gate.maxPerplexity) {
|
|
127
|
-
const result = {
|
|
128
|
-
input,
|
|
129
|
-
teacherOutput,
|
|
130
|
-
adaptResult: { losses: [], epochCount: 0, durationMs: 0 },
|
|
131
|
-
skipped: true,
|
|
132
|
-
skipReason: 'already_learned',
|
|
133
|
-
gatePerplexity,
|
|
134
|
-
};
|
|
135
|
-
this._appendLog({
|
|
136
|
-
input,
|
|
137
|
-
teacherOutputLength: teacherOutput.length,
|
|
138
|
-
skipped: true,
|
|
139
|
-
skipReason: 'already_learned',
|
|
140
|
-
epochs: 0,
|
|
141
|
-
gatePerplexity,
|
|
142
|
-
});
|
|
143
|
-
return result;
|
|
144
|
-
}
|
|
113
|
+
catch {
|
|
114
|
+
// Evaluation failure is non-fatal — proceed with adaptation
|
|
115
|
+
}
|
|
116
|
+
if (gatePerplexity != null && gatePerplexity < gate.maxPerplexity) {
|
|
117
|
+
return this._skip(input, teacherOutput, 'already_learned', gatePerplexity);
|
|
145
118
|
}
|
|
146
119
|
}
|
|
147
|
-
// Train the
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
// knowledge instead of overwriting it (catastrophic-forgetting guard).
|
|
120
|
+
// Train on the (prompt → response) mapping. EVM-5: interleave a sample of past
|
|
121
|
+
// exemplars (experience replay) so this adapt reinforces prior knowledge
|
|
122
|
+
// instead of overwriting it.
|
|
151
123
|
const rehearsed = this._sampleRehearsal();
|
|
152
|
-
const
|
|
153
|
-
const trainingText =
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
catch (err) {
|
|
159
|
-
throw new SSMError('DISTILL_FAILED', `SSM adaptation failed during distillation: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
160
|
-
}
|
|
161
|
-
// Record the new exemplar for future rehearsal.
|
|
124
|
+
const context = (i) => (opts.contextChars != null ? i.trim().slice(0, opts.contextChars) : i);
|
|
125
|
+
const trainingText = [...rehearsed, { input, teacherOutput }]
|
|
126
|
+
.map((p) => `${context(p.input)}\n${p.teacherOutput}`)
|
|
127
|
+
.join('\n\n');
|
|
128
|
+
const adaptResult = await this._adapt(trainingText, opts);
|
|
162
129
|
this._pushRehearsal(input, teacherOutput);
|
|
163
130
|
this._appendLog({
|
|
164
131
|
input,
|
|
165
132
|
teacherOutputLength: teacherOutput.length,
|
|
166
133
|
skipped: false,
|
|
167
|
-
|
|
168
|
-
|
|
134
|
+
distilled: true,
|
|
135
|
+
...this._student.describe(adaptResult),
|
|
169
136
|
gatePerplexity,
|
|
170
137
|
});
|
|
171
|
-
return { input, teacherOutput, adaptResult, skipped: false, rehearsed: rehearsed.length, gatePerplexity };
|
|
138
|
+
return { input, teacherOutput, adaptResult, skipped: false, distilled: true, rehearsed: rehearsed.length, gatePerplexity };
|
|
172
139
|
}
|
|
173
140
|
/**
|
|
174
141
|
* Runs distillation for each input in sequence.
|
|
@@ -181,7 +148,7 @@ export class DistillationEngine {
|
|
|
181
148
|
for (const input of inputs) {
|
|
182
149
|
const result = await this.distill(input, opts);
|
|
183
150
|
results.push(result);
|
|
184
|
-
totalEpochs += result.adaptResult.
|
|
151
|
+
totalEpochs += this._student.describe(result.adaptResult).epochs;
|
|
185
152
|
}
|
|
186
153
|
return {
|
|
187
154
|
results,
|
|
@@ -196,6 +163,56 @@ export class DistillationEngine {
|
|
|
196
163
|
return this._log.slice();
|
|
197
164
|
}
|
|
198
165
|
// ── Private helpers ───────────────────────────────────────────────────────
|
|
166
|
+
async _adapt(trainingText, opts) {
|
|
167
|
+
try {
|
|
168
|
+
return await this._student.adapt(trainingText, opts.adapt);
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
throw new SSMError('DISTILL_FAILED', `SSM adaptation failed during distillation: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** No exemplar worth learning: learn the caller's fallback text instead. */
|
|
175
|
+
async _learnFallback(input, teacherOutput, skipReason, opts, teacherError) {
|
|
176
|
+
const adaptResult = await this._adapt(opts.fallbackText, opts);
|
|
177
|
+
this._appendLog({
|
|
178
|
+
input,
|
|
179
|
+
teacherOutputLength: teacherOutput.length,
|
|
180
|
+
skipped: false,
|
|
181
|
+
distilled: false,
|
|
182
|
+
skipReason,
|
|
183
|
+
...this._student.describe(adaptResult),
|
|
184
|
+
});
|
|
185
|
+
return {
|
|
186
|
+
input,
|
|
187
|
+
teacherOutput,
|
|
188
|
+
adaptResult,
|
|
189
|
+
skipped: false,
|
|
190
|
+
distilled: false,
|
|
191
|
+
skipReason,
|
|
192
|
+
...(teacherError !== undefined ? { teacherError } : {}),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/** Nothing adapted. */
|
|
196
|
+
_skip(input, teacherOutput, skipReason, gatePerplexity) {
|
|
197
|
+
this._appendLog({
|
|
198
|
+
input,
|
|
199
|
+
teacherOutputLength: teacherOutput.length,
|
|
200
|
+
skipped: true,
|
|
201
|
+
distilled: false,
|
|
202
|
+
skipReason,
|
|
203
|
+
epochs: 0,
|
|
204
|
+
gatePerplexity,
|
|
205
|
+
});
|
|
206
|
+
return {
|
|
207
|
+
input,
|
|
208
|
+
teacherOutput,
|
|
209
|
+
adaptResult: this._student.skippedResult(),
|
|
210
|
+
skipped: true,
|
|
211
|
+
distilled: false,
|
|
212
|
+
skipReason,
|
|
213
|
+
...(gatePerplexity !== undefined ? { gatePerplexity } : {}),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
199
216
|
_appendLog(entry) {
|
|
200
217
|
this._log.push({ timestamp: Date.now(), ...entry });
|
|
201
218
|
if (this._log.length > MAX_LOG_ENTRIES) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DistillationEngine.js","sourceRoot":"","sources":["../../src/distillation/DistillationEngine.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"DistillationEngine.js","sourceRoot":"","sources":["../../src/distillation/DistillationEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Distillation — a teacher's exemplars adapted into a student, behind two ports.
|
|
3
|
+
* Engine-free: the `@seanhogg/builderforce-memory/distillation` subpath.
|
|
4
|
+
*/
|
|
1
5
|
export { DistillationEngine } from './DistillationEngine.js';
|
|
2
|
-
export type { DistillOptions, DistillResult, DistillBatchResult, DistillationLog, QualityGate, RehearsalOptions } from './DistillationEngine.js';
|
|
6
|
+
export type { DistillOptions, DistillResult, DistillBatchResult, DistillationLog, DistillSkipReason, QualityGate, RehearsalOptions, } from './DistillationEngine.js';
|
|
7
|
+
export { ssmRuntimeStudent, SSM_STUDENT_DEFAULT_ADAPT } from './ports.js';
|
|
8
|
+
export type { DistillationTeacher, DistillationStudent } from './ports.js';
|
|
3
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/distillation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/distillation/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EACR,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,gBAAgB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC1E,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Distillation — a teacher's exemplars adapted into a student, behind two ports.
|
|
3
|
+
* Engine-free: the `@seanhogg/builderforce-memory/distillation` subpath.
|
|
4
|
+
*/
|
|
1
5
|
export { DistillationEngine } from './DistillationEngine.js';
|
|
6
|
+
export { ssmRuntimeStudent, SSM_STUDENT_DEFAULT_ADAPT } from './ports.js';
|
|
2
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/distillation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/distillation/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAU7D,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two ports a {@link DistillationEngine} runs between.
|
|
3
|
+
*
|
|
4
|
+
* Distillation is one recipe — teacher answers, gate, rehearse, adapt, log — over
|
|
5
|
+
* any teacher and any student. The package's own pairing (a `TransformerBridge`
|
|
6
|
+
* teaching an `SSMRuntime`) is one instance; a host that teaches through a metered
|
|
7
|
+
* gateway and adapts a packaged checkpoint into a mergeable diff is another. Both
|
|
8
|
+
* plug in here instead of restating the recipe.
|
|
9
|
+
*/
|
|
10
|
+
import type { AdaptOptions, AdaptResult } from '../session/index.js';
|
|
11
|
+
import type { SSMRuntime } from '../runtime/SSMRuntime.js';
|
|
12
|
+
import type { BridgeGenerateOptions } from '../bridges/TransformerBridge.js';
|
|
13
|
+
/** Produces the exemplar for an input. Any `TransformerBridge` is one. */
|
|
14
|
+
export interface DistillationTeacher {
|
|
15
|
+
/** The exemplar for `input`. Throws when there is none; the engine records the error. */
|
|
16
|
+
generate(input: string, opts?: BridgeGenerateOptions): Promise<string>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Learns from a training text. `R` is whatever one adaptation yields (an `AdaptResult`,
|
|
20
|
+
* a checkpoint diff, …); `O` the per-call options it takes.
|
|
21
|
+
*/
|
|
22
|
+
export interface DistillationStudent<R, O = undefined> {
|
|
23
|
+
adapt(trainingText: string, opts?: O): Promise<R>;
|
|
24
|
+
/** Perplexity on `text` — enables the `maxPerplexity` gate. Optional. */
|
|
25
|
+
evaluate?(text: string): Promise<number>;
|
|
26
|
+
/** The result recorded when nothing was adapted (the gate skipped the input). */
|
|
27
|
+
skippedResult(): R;
|
|
28
|
+
/** Final loss and epoch count of one result, for the log and batch totals. */
|
|
29
|
+
describe(result: R): {
|
|
30
|
+
finalLoss?: number;
|
|
31
|
+
epochs: number;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** The adapt options an {@link SSMRuntime} student uses unless a call overrides them. */
|
|
35
|
+
export declare const SSM_STUDENT_DEFAULT_ADAPT: AdaptOptions;
|
|
36
|
+
/**
|
|
37
|
+
* An {@link SSMRuntime} as a student. WSLA by default: it is fast and targets the
|
|
38
|
+
* selective-projection rows, exactly the parameters that encode token routing.
|
|
39
|
+
*/
|
|
40
|
+
export declare function ssmRuntimeStudent(runtime: SSMRuntime): DistillationStudent<AdaptResult, AdaptOptions>;
|
|
41
|
+
/** True when `x` already speaks the student port (an `SSMRuntime` does not: it has no `describe`). */
|
|
42
|
+
export declare function isDistillationStudent<R, O>(x: unknown): x is DistillationStudent<R, O>;
|
|
43
|
+
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../src/distillation/ports.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAE7E,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAChC,yFAAyF;IACzF,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1E;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS;IACjD,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD,yEAAyE;IACzE,QAAQ,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,iFAAiF;IACjF,aAAa,IAAI,CAAC,CAAC;IACnB,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D;AAED,yFAAyF;AACzF,eAAO,MAAM,yBAAyB,EAAE,YAAwC,CAAC;AAEjF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,mBAAmB,CAAC,WAAW,EAAE,YAAY,CAAC,CAOrG;AAED,sGAAsG;AACtG,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAGtF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two ports a {@link DistillationEngine} runs between.
|
|
3
|
+
*
|
|
4
|
+
* Distillation is one recipe — teacher answers, gate, rehearse, adapt, log — over
|
|
5
|
+
* any teacher and any student. The package's own pairing (a `TransformerBridge`
|
|
6
|
+
* teaching an `SSMRuntime`) is one instance; a host that teaches through a metered
|
|
7
|
+
* gateway and adapts a packaged checkpoint into a mergeable diff is another. Both
|
|
8
|
+
* plug in here instead of restating the recipe.
|
|
9
|
+
*/
|
|
10
|
+
/** The adapt options an {@link SSMRuntime} student uses unless a call overrides them. */
|
|
11
|
+
export const SSM_STUDENT_DEFAULT_ADAPT = { wsla: true, epochs: 3 };
|
|
12
|
+
/**
|
|
13
|
+
* An {@link SSMRuntime} as a student. WSLA by default: it is fast and targets the
|
|
14
|
+
* selective-projection rows, exactly the parameters that encode token routing.
|
|
15
|
+
*/
|
|
16
|
+
export function ssmRuntimeStudent(runtime) {
|
|
17
|
+
return {
|
|
18
|
+
adapt: (text, opts) => runtime.adapt(text, { ...SSM_STUDENT_DEFAULT_ADAPT, ...opts }),
|
|
19
|
+
evaluate: (text) => runtime.evaluate(text),
|
|
20
|
+
skippedResult: () => ({ losses: [], epochCount: 0, durationMs: 0 }),
|
|
21
|
+
describe: (r) => ({ finalLoss: r.losses.at(-1), epochs: r.epochCount }),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** True when `x` already speaks the student port (an `SSMRuntime` does not: it has no `describe`). */
|
|
25
|
+
export function isDistillationStudent(x) {
|
|
26
|
+
return !!x && typeof x.describe === 'function'
|
|
27
|
+
&& typeof x.skippedResult === 'function';
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=ports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.js","sourceRoot":"","sources":["../../src/distillation/ports.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0BH,yFAAyF;AACzF,MAAM,CAAC,MAAM,yBAAyB,GAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AAEjF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAmB;IACjD,OAAO;QACH,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,yBAAyB,EAAE,GAAG,IAAI,EAAE,CAAC;QACrF,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC1C,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;QACnE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC;KAC1E,CAAC;AACN,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,qBAAqB,CAAO,CAAU;IAClD,OAAO,CAAC,CAAC,CAAC,IAAI,OAAQ,CAA4B,CAAC,QAAQ,KAAK,UAAU;WACnE,OAAQ,CAAiC,CAAC,aAAa,KAAK,UAAU,CAAC;AAClF,CAAC"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* and a production bill are denominated identically.
|
|
9
9
|
*/
|
|
10
10
|
import type { Tracer } from '../telemetry/Tracer.js';
|
|
11
|
+
import { type EvalReportSummary } from './baseline.js';
|
|
11
12
|
import type { EvalDataset, EvalGate, EvalReport, EvalTarget, GateVerdict, Grader } from './types.js';
|
|
12
13
|
export interface EvalHarnessOptions {
|
|
13
14
|
graders?: readonly Grader[];
|
|
@@ -31,7 +32,7 @@ export declare class EvalHarness {
|
|
|
31
32
|
private _report;
|
|
32
33
|
}
|
|
33
34
|
/** Applies a gate to a report. Pure, so a build can re-gate an archived report. */
|
|
34
|
-
export declare function evaluateGate(report: EvalReport, gate: EvalGate): GateVerdict;
|
|
35
|
+
export declare function evaluateGate(report: EvalReport, gate: EvalGate, baseline?: EvalReportSummary): GateVerdict;
|
|
35
36
|
/** One-screen summary for CI logs. */
|
|
36
37
|
export declare function formatReport(report: EvalReport): string;
|
|
37
38
|
//# sourceMappingURL=EvalHarness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EvalHarness.d.ts","sourceRoot":"","sources":["../../src/eval/EvalHarness.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAErD,OAAO,KAAK,EAER,WAAW,EACX,QAAQ,EACR,UAAU,EACV,UAAU,EACV,WAAW,EAEX,MAAM,EACT,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,kBAAkB;IAC/B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,IAAI,GAAE,kBAAuB;IAOnC,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IA+CxE,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,OAAO;CAmClB;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"EvalHarness.d.ts","sourceRoot":"","sources":["../../src/eval/EvalHarness.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAErD,OAAO,EAAsD,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC3G,OAAO,KAAK,EAER,WAAW,EACX,QAAQ,EACR,UAAU,EACV,UAAU,EACV,WAAW,EAEX,MAAM,EACT,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,kBAAkB;IAC/B,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,IAAI,GAAE,kBAAuB;IAOnC,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IA+CxE,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,OAAO;CAmClB;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,WAAW,CAuC1G;AAED,sCAAsC;AACtC,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAoCvD"}
|
package/dist/eval/EvalHarness.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { mapWithConcurrency } from '../ingest/IngestionPipeline.js';
|
|
11
11
|
import { percentile } from '../telemetry/MetricsRegistry.js';
|
|
12
12
|
import { DEFAULT_RAG_GRADERS } from './graders.js';
|
|
13
|
+
import { baselineRatio, meetsBaselineRatio, sameEvalProblem } from './baseline.js';
|
|
13
14
|
export class EvalHarness {
|
|
14
15
|
_graders;
|
|
15
16
|
_gate;
|
|
@@ -105,7 +106,7 @@ export class EvalHarness {
|
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
/** Applies a gate to a report. Pure, so a build can re-gate an archived report. */
|
|
108
|
-
export function evaluateGate(report, gate) {
|
|
109
|
+
export function evaluateGate(report, gate, baseline) {
|
|
109
110
|
const failures = [];
|
|
110
111
|
const thresholds = Object.entries(gate).filter(([, v]) => v !== undefined);
|
|
111
112
|
if (gate.minPassRate !== undefined && report.passRate < gate.minPassRate) {
|
|
@@ -123,6 +124,17 @@ export function evaluateGate(report, gate) {
|
|
|
123
124
|
if (gate.maxP95LatencyMs !== undefined && report.p95LatencyMs > gate.maxP95LatencyMs) {
|
|
124
125
|
failures.push(`p95 latency ${Math.round(report.p95LatencyMs)}ms > allowed ${gate.maxP95LatencyMs}ms`);
|
|
125
126
|
}
|
|
127
|
+
if (gate.minBaselineRatio !== undefined) {
|
|
128
|
+
const problem = baseline ? sameEvalProblem(report, baseline) : 'gate needs a baseline report to compare against';
|
|
129
|
+
const ratio = baseline ? baselineRatio(report.meanScore, baseline.meanScore) : null;
|
|
130
|
+
if (problem)
|
|
131
|
+
failures.push(problem);
|
|
132
|
+
else if (!meetsBaselineRatio(ratio, gate.minBaselineRatio)) {
|
|
133
|
+
failures.push(ratio === null
|
|
134
|
+
? 'baseline scored 0, so no ratio can be taken'
|
|
135
|
+
: `score is ${pct(ratio)} of the baseline < required ${pct(gate.minBaselineRatio)}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
126
138
|
for (const [grader, minimum] of Object.entries(gate.minGraderScore ?? {})) {
|
|
127
139
|
const actual = report.graderScores[grader];
|
|
128
140
|
if (actual === undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EvalHarness.js","sourceRoot":"","sources":["../../src/eval/EvalHarness.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"EvalHarness.js","sourceRoot":"","sources":["../../src/eval/EvalHarness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* eval/baseline.ts — gating a candidate RELATIVE to a baseline.
|
|
3
|
+
*
|
|
4
|
+
* "Good enough to launch" is often not an absolute score but a fraction of what an
|
|
5
|
+
* incumbent scores on the same suite: a small model may serve a task once it reaches
|
|
6
|
+
* 90% of the frontier model it replaces. That comparison only means something when
|
|
7
|
+
* both reports came from the SAME eval (same dataset, same cases), and when the
|
|
8
|
+
* baseline scored above zero. These are the rules for it, used by
|
|
9
|
+
* {@link evaluateGate}'s `minBaselineRatio` and by any caller that stores the two
|
|
10
|
+
* scores and re-checks the bar later without the reports.
|
|
11
|
+
*/
|
|
12
|
+
/** The three facts of a report that a baseline comparison reads. */
|
|
13
|
+
export interface EvalReportSummary {
|
|
14
|
+
dataset: string;
|
|
15
|
+
meanScore: number;
|
|
16
|
+
/** The cases array, or just its length. */
|
|
17
|
+
cases: number | readonly unknown[];
|
|
18
|
+
}
|
|
19
|
+
/** Float tolerance for a ratio bar, so an exact 90% (0.81 / 0.9) meets a 0.9 bar. */
|
|
20
|
+
export declare const BASELINE_RATIO_EPSILON = 1e-9;
|
|
21
|
+
/**
|
|
22
|
+
* `score ÷ baselineScore`, or null when the pair cannot be compared — a non-finite or
|
|
23
|
+
* negative score, or a baseline at or below zero, proves nothing.
|
|
24
|
+
*/
|
|
25
|
+
export declare function baselineRatio(score: number, baselineScore: number): number | null;
|
|
26
|
+
/** True when `ratio` reaches `minRatio` (within {@link BASELINE_RATIO_EPSILON}). A null ratio never does. */
|
|
27
|
+
export declare function meetsBaselineRatio(ratio: number | null, minRatio: number): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Why two reports are not the same eval, or null when they are. "The same eval" is
|
|
30
|
+
* enforced, not assumed: a ratio of scores from different suites compares nothing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function sameEvalProblem(candidate: EvalReportSummary, baseline: EvalReportSummary): string | null;
|
|
33
|
+
//# sourceMappingURL=baseline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../src/eval/baseline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,GAAG,SAAS,OAAO,EAAE,CAAC;CACtC;AAED,qFAAqF;AACrF,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjF;AAED,6GAA6G;AAC7G,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAElF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,iBAAiB,EAAE,QAAQ,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CASxG"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* eval/baseline.ts — gating a candidate RELATIVE to a baseline.
|
|
3
|
+
*
|
|
4
|
+
* "Good enough to launch" is often not an absolute score but a fraction of what an
|
|
5
|
+
* incumbent scores on the same suite: a small model may serve a task once it reaches
|
|
6
|
+
* 90% of the frontier model it replaces. That comparison only means something when
|
|
7
|
+
* both reports came from the SAME eval (same dataset, same cases), and when the
|
|
8
|
+
* baseline scored above zero. These are the rules for it, used by
|
|
9
|
+
* {@link evaluateGate}'s `minBaselineRatio` and by any caller that stores the two
|
|
10
|
+
* scores and re-checks the bar later without the reports.
|
|
11
|
+
*/
|
|
12
|
+
/** Float tolerance for a ratio bar, so an exact 90% (0.81 / 0.9) meets a 0.9 bar. */
|
|
13
|
+
export const BASELINE_RATIO_EPSILON = 1e-9;
|
|
14
|
+
/**
|
|
15
|
+
* `score ÷ baselineScore`, or null when the pair cannot be compared — a non-finite or
|
|
16
|
+
* negative score, or a baseline at or below zero, proves nothing.
|
|
17
|
+
*/
|
|
18
|
+
export function baselineRatio(score, baselineScore) {
|
|
19
|
+
if (!Number.isFinite(score) || !Number.isFinite(baselineScore) || score < 0 || baselineScore <= 0)
|
|
20
|
+
return null;
|
|
21
|
+
return score / baselineScore;
|
|
22
|
+
}
|
|
23
|
+
/** True when `ratio` reaches `minRatio` (within {@link BASELINE_RATIO_EPSILON}). A null ratio never does. */
|
|
24
|
+
export function meetsBaselineRatio(ratio, minRatio) {
|
|
25
|
+
return ratio !== null && ratio + BASELINE_RATIO_EPSILON >= minRatio;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Why two reports are not the same eval, or null when they are. "The same eval" is
|
|
29
|
+
* enforced, not assumed: a ratio of scores from different suites compares nothing.
|
|
30
|
+
*/
|
|
31
|
+
export function sameEvalProblem(candidate, baseline) {
|
|
32
|
+
const count = (c) => (typeof c === 'number' ? c : c.length);
|
|
33
|
+
if (candidate.dataset !== baseline.dataset) {
|
|
34
|
+
return `reports are from different evals ('${candidate.dataset}' vs '${baseline.dataset}')`;
|
|
35
|
+
}
|
|
36
|
+
if (count(candidate.cases) !== count(baseline.cases)) {
|
|
37
|
+
return `reports scored different case counts (${count(candidate.cases)} vs ${count(baseline.cases)})`;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=baseline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../src/eval/baseline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,qFAAqF;AACrF,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,aAAqB;IAC9D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,aAAa,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/G,OAAO,KAAK,GAAG,aAAa,CAAC;AACjC,CAAC;AAED,6GAA6G;AAC7G,MAAM,UAAU,kBAAkB,CAAC,KAAoB,EAAE,QAAgB;IACrE,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,sBAAsB,IAAI,QAAQ,CAAC;AACxE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,SAA4B,EAAE,QAA2B;IACrF,MAAM,KAAK,GAAG,CAAC,CAA6B,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACxF,IAAI,SAAS,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO,EAAE,CAAC;QACzC,OAAO,sCAAsC,SAAS,CAAC,OAAO,SAAS,QAAQ,CAAC,OAAO,IAAI,CAAC;IAChG,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,OAAO,yCAAyC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;IAC1G,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
|