@valerypopoff/rivet2-evaluations 2.17.0 → 2.19.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.
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/serialization.ts
|
|
31
|
+
var serialization_exports = {};
|
|
32
|
+
__export(serialization_exports, {
|
|
33
|
+
createEmptyEvaluationProjectData: () => createEmptyEvaluationProjectData,
|
|
34
|
+
deserializeEvaluationProjectData: () => deserializeEvaluationProjectData,
|
|
35
|
+
deserializeEvaluationProjectDataFromString: () => deserializeEvaluationProjectDataFromString,
|
|
36
|
+
serializeEvaluationProjectData: () => serializeEvaluationProjectData,
|
|
37
|
+
serializeEvaluationProjectDataToString: () => serializeEvaluationProjectDataToString
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(serialization_exports);
|
|
40
|
+
var yaml = __toESM(require("yaml"), 1);
|
|
41
|
+
|
|
42
|
+
// src/canonical.ts
|
|
43
|
+
function assertPortableJson(value, path = "$", stack = /* @__PURE__ */ new Set()) {
|
|
44
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return;
|
|
45
|
+
if (typeof value === "number") {
|
|
46
|
+
if (!Number.isFinite(value)) throw new Error(`${path} must not contain a non-finite number.`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (typeof value !== "object") throw new Error(`${path} must be portable JSON.`);
|
|
50
|
+
if (stack.has(value)) throw new Error(`${path} must not contain a cycle.`);
|
|
51
|
+
if (Array.isArray(value)) {
|
|
52
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
53
|
+
throw new Error(`${path} must not contain symbol-keyed array properties.`);
|
|
54
|
+
}
|
|
55
|
+
stack.add(value);
|
|
56
|
+
try {
|
|
57
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
58
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, index);
|
|
59
|
+
if (!descriptor) throw new Error(`${path}[${index}] must not be a sparse array entry.`);
|
|
60
|
+
if (!descriptor.enumerable || descriptor.get || descriptor.set) {
|
|
61
|
+
throw new Error(`${path}[${index}] must be an enumerable data property.`);
|
|
62
|
+
}
|
|
63
|
+
assertPortableJson(descriptor.value, `${path}[${index}]`, stack);
|
|
64
|
+
}
|
|
65
|
+
if (Object.getOwnPropertyNames(value).length !== value.length + 1) {
|
|
66
|
+
throw new Error(`${path} must not contain hidden or extra array properties.`);
|
|
67
|
+
}
|
|
68
|
+
} finally {
|
|
69
|
+
stack.delete(value);
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
|
|
74
|
+
throw new Error(`${path} must be a plain object.`);
|
|
75
|
+
}
|
|
76
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
77
|
+
throw new Error(`${path} must not contain symbol-keyed object properties.`);
|
|
78
|
+
}
|
|
79
|
+
const ownPropertyNames = Object.getOwnPropertyNames(value);
|
|
80
|
+
const keys = Object.keys(value);
|
|
81
|
+
if (ownPropertyNames.length !== keys.length) {
|
|
82
|
+
throw new Error(`${path} must not contain non-enumerable object properties.`);
|
|
83
|
+
}
|
|
84
|
+
stack.add(value);
|
|
85
|
+
try {
|
|
86
|
+
for (const key of keys) {
|
|
87
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
88
|
+
if (!descriptor || descriptor.get || descriptor.set) {
|
|
89
|
+
throw new Error(`${path}.${key} must be an enumerable data property.`);
|
|
90
|
+
}
|
|
91
|
+
assertPortableJson(descriptor.value, `${path}.${key}`, stack);
|
|
92
|
+
}
|
|
93
|
+
} finally {
|
|
94
|
+
stack.delete(value);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/normalization.ts
|
|
99
|
+
function isRecord(value) {
|
|
100
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
101
|
+
}
|
|
102
|
+
function isQualityStatus(value) {
|
|
103
|
+
return ["passed", "failed", "scored", "not-evaluated", "unable-to-evaluate"].includes(String(value));
|
|
104
|
+
}
|
|
105
|
+
function isEvaluationMode(value) {
|
|
106
|
+
return value === "pass-fail" || value === "scoring";
|
|
107
|
+
}
|
|
108
|
+
function isQualityStatusForMode(status, evaluationMode) {
|
|
109
|
+
return evaluationMode === "scoring" ? status !== "passed" && status !== "failed" : status !== "scored";
|
|
110
|
+
}
|
|
111
|
+
function isPurpose(value) {
|
|
112
|
+
return value === "evaluation" || value === "execution-benchmark";
|
|
113
|
+
}
|
|
114
|
+
function isAccountingStatus(value) {
|
|
115
|
+
return value === "complete" || value === "partial";
|
|
116
|
+
}
|
|
117
|
+
function isNormalizedScore(value) {
|
|
118
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1;
|
|
119
|
+
}
|
|
120
|
+
function reasonForQualityStatus(status, executionStatus) {
|
|
121
|
+
if (executionStatus === "canceled") return { code: "canceled", message: "The execution was canceled." };
|
|
122
|
+
if (executionStatus === "error" && status === "failed") {
|
|
123
|
+
return { code: "target-error", message: "The target graph failed before it could produce a valid result." };
|
|
124
|
+
}
|
|
125
|
+
switch (status) {
|
|
126
|
+
case "passed":
|
|
127
|
+
return { code: "checks-passed", message: "All required quality criteria passed." };
|
|
128
|
+
case "failed":
|
|
129
|
+
return { code: "checks-failed", message: "One or more required quality criteria failed." };
|
|
130
|
+
case "scored":
|
|
131
|
+
return { code: "scores-complete", message: "Every requested trial produced a score." };
|
|
132
|
+
case "not-evaluated":
|
|
133
|
+
return { code: "no-trial-quality-checks", message: "No per-trial quality check evaluated this result." };
|
|
134
|
+
case "unable-to-evaluate":
|
|
135
|
+
return { code: "required-check-error", message: "A required quality criterion could not be evaluated." };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function reasonForQualityStatusInMode(status, evaluationMode, executionStatus) {
|
|
139
|
+
if (evaluationMode === "scoring" && status === "unable-to-evaluate") {
|
|
140
|
+
return { code: "scores-incomplete", message: "One or more requested trials did not produce a usable score." };
|
|
141
|
+
}
|
|
142
|
+
return reasonForQualityStatus(status, executionStatus);
|
|
143
|
+
}
|
|
144
|
+
function isQualityReasonCompatible(reason, status, purpose, executionStatus) {
|
|
145
|
+
if (purpose === "execution-benchmark") {
|
|
146
|
+
return executionStatus === "canceled" ? reason.code === "canceled" : reason.code === "benchmark";
|
|
147
|
+
}
|
|
148
|
+
if (executionStatus === "queued" || executionStatus === "running") return reason.code === "in-progress";
|
|
149
|
+
if (executionStatus === "canceled") return reason.code === "canceled";
|
|
150
|
+
switch (status) {
|
|
151
|
+
case "passed":
|
|
152
|
+
return reason.code === "checks-passed" || reason.code === "thresholds-passed";
|
|
153
|
+
case "failed":
|
|
154
|
+
return reason.code === "checks-failed" || reason.code === "thresholds-failed" || reason.code === "target-error";
|
|
155
|
+
case "scored":
|
|
156
|
+
return reason.code === "scores-complete";
|
|
157
|
+
case "not-evaluated":
|
|
158
|
+
return reason.code === "no-trial-quality-checks" || reason.code === "no-completed-trials";
|
|
159
|
+
case "unable-to-evaluate":
|
|
160
|
+
return reason.code === "required-check-error" || reason.code === "required-metric-unavailable" || reason.code === "scores-incomplete";
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function normalizeQualityReason(value, fallback, status, purpose, executionStatus) {
|
|
164
|
+
if (!isRecord(value) || typeof value.code !== "string" || typeof value.message !== "string") return fallback;
|
|
165
|
+
const reason = value;
|
|
166
|
+
return isQualityReasonCompatible(reason, status, purpose, executionStatus) ? reason : fallback;
|
|
167
|
+
}
|
|
168
|
+
function normalizeEvaluationAggregate(value, trials) {
|
|
169
|
+
if (!isRecord(value)) throw new Error("Evaluation aggregate must be an object.");
|
|
170
|
+
const normalized = structuredClone(value);
|
|
171
|
+
if (!isNormalizedScore(normalized.meanScore)) delete normalized.meanScore;
|
|
172
|
+
if (!isNormalizedScore(normalized.medianScore)) delete normalized.medianScore;
|
|
173
|
+
if (!isNormalizedScore(normalized.p95Score)) delete normalized.p95Score;
|
|
174
|
+
if (typeof normalized.medianLatencyMs !== "number" || !Number.isFinite(normalized.medianLatencyMs) || normalized.medianLatencyMs < 0) {
|
|
175
|
+
delete normalized.medianLatencyMs;
|
|
176
|
+
}
|
|
177
|
+
if (trials) {
|
|
178
|
+
const completed = trials.filter((trial) => trial.executionStatus === "completed");
|
|
179
|
+
const evaluated2 = completed.filter((trial) => trial.qualityStatus === "passed" || trial.qualityStatus === "failed");
|
|
180
|
+
const passed2 = evaluated2.filter((trial) => trial.qualityStatus === "passed");
|
|
181
|
+
const failed2 = evaluated2.filter((trial) => trial.qualityStatus === "failed");
|
|
182
|
+
const notEvaluated2 = completed.filter((trial) => trial.qualityStatus === "not-evaluated");
|
|
183
|
+
const unable2 = completed.filter((trial) => trial.qualityStatus === "unable-to-evaluate");
|
|
184
|
+
const scored = completed.filter((trial) => trial.qualityStatus === "scored");
|
|
185
|
+
return {
|
|
186
|
+
...normalized,
|
|
187
|
+
trialCount: trials.length,
|
|
188
|
+
evaluatedTrialCount: evaluated2.length,
|
|
189
|
+
notEvaluatedTrialCount: notEvaluated2.length,
|
|
190
|
+
unableToEvaluateTrialCount: unable2.length,
|
|
191
|
+
passedTrialCount: passed2.length,
|
|
192
|
+
failedTrialCount: failed2.length,
|
|
193
|
+
erroredTrialCount: trials.filter((trial) => trial.executionStatus === "error").length,
|
|
194
|
+
canceledTrialCount: trials.filter((trial) => trial.executionStatus === "canceled").length,
|
|
195
|
+
...scored.length > 0 || normalized.scoredTrialCount !== void 0 ? { scoredTrialCount: scored.length, missingScoreTrialCount: trials.length - scored.length } : {},
|
|
196
|
+
passRate: evaluated2.length === 0 ? 0 : passed2.length / evaluated2.length
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const trialCount = Number(value.trialCount ?? 0);
|
|
200
|
+
const passed = Number(value.passedTrialCount ?? 0);
|
|
201
|
+
const failed = Number(value.failedTrialCount ?? 0);
|
|
202
|
+
const errored = Number(value.erroredTrialCount ?? 0);
|
|
203
|
+
const canceled = Number(value.canceledTrialCount ?? 0);
|
|
204
|
+
const evaluated = Number(value.evaluatedTrialCount ?? passed + failed);
|
|
205
|
+
const unable = Number(value.unableToEvaluateTrialCount ?? 0);
|
|
206
|
+
const notEvaluated = Number(
|
|
207
|
+
value.notEvaluatedTrialCount ?? Math.max(0, trialCount - evaluated - unable - errored - canceled)
|
|
208
|
+
);
|
|
209
|
+
return {
|
|
210
|
+
...normalized,
|
|
211
|
+
evaluatedTrialCount: evaluated,
|
|
212
|
+
notEvaluatedTrialCount: notEvaluated,
|
|
213
|
+
unableToEvaluateTrialCount: unable,
|
|
214
|
+
passRate: evaluated === 0 ? 0 : passed / evaluated
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function withoutAuthoritativeCost(aggregate) {
|
|
218
|
+
const normalized = { ...aggregate };
|
|
219
|
+
delete normalized.totalCostUsd;
|
|
220
|
+
delete normalized.averageCostUsd;
|
|
221
|
+
return normalized;
|
|
222
|
+
}
|
|
223
|
+
function normalizeEvaluationBaselineSnapshot(value) {
|
|
224
|
+
if (!isRecord(value)) throw new Error("Evaluation baseline snapshot must be an object.");
|
|
225
|
+
const accountingStatus = isAccountingStatus(value.accountingStatus) ? value.accountingStatus : isRecord(value.provenance) && value.provenance.accountingComplete === false ? "partial" : "complete";
|
|
226
|
+
const aggregate = normalizeEvaluationAggregate(value.aggregate);
|
|
227
|
+
const purpose = isPurpose(value.purpose) ? value.purpose : "evaluation";
|
|
228
|
+
const evaluationMode = isEvaluationMode(value.evaluationMode) ? value.evaluationMode : "pass-fail";
|
|
229
|
+
const hasCompleteScoringAggregate = aggregate.trialCount > 0 && aggregate.scoredTrialCount === aggregate.trialCount && aggregate.missingScoreTrialCount === 0 && aggregate.meanScore !== void 0;
|
|
230
|
+
const qualityStatus = purpose === "execution-benchmark" ? "not-evaluated" : evaluationMode === "scoring" ? hasCompleteScoringAggregate ? "scored" : "unable-to-evaluate" : isQualityStatus(value.qualityStatus) && isQualityStatusForMode(value.qualityStatus, evaluationMode) ? value.qualityStatus : aggregate.failedTrialCount > 0 || aggregate.erroredTrialCount > 0 ? "failed" : aggregate.evaluatedTrialCount > 0 ? "passed" : "not-evaluated";
|
|
231
|
+
const qualityReasonFallback = purpose === "execution-benchmark" ? { code: "benchmark", message: "This run measured execution without evaluating output quality." } : reasonForQualityStatusInMode(qualityStatus, evaluationMode);
|
|
232
|
+
return {
|
|
233
|
+
...structuredClone(value),
|
|
234
|
+
purpose,
|
|
235
|
+
evaluationMode,
|
|
236
|
+
qualityStatus,
|
|
237
|
+
qualityReason: normalizeQualityReason(value.qualityReason, qualityReasonFallback, qualityStatus, purpose),
|
|
238
|
+
accountingStatus,
|
|
239
|
+
aggregate: accountingStatus === "partial" ? withoutAuthoritativeCost(aggregate) : aggregate
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/serialization.ts
|
|
244
|
+
function isRecord2(value) {
|
|
245
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
246
|
+
}
|
|
247
|
+
function requireRecord(value, path) {
|
|
248
|
+
if (!isRecord2(value)) throw new Error(`${path} must be an object.`);
|
|
249
|
+
return value;
|
|
250
|
+
}
|
|
251
|
+
function requireString(value, path) {
|
|
252
|
+
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${path} must be a non-empty string.`);
|
|
253
|
+
}
|
|
254
|
+
function requireText(value, path) {
|
|
255
|
+
if (typeof value !== "string") throw new Error(`${path} must be a string.`);
|
|
256
|
+
}
|
|
257
|
+
function requireBoolean(value, path) {
|
|
258
|
+
if (typeof value !== "boolean") throw new Error(`${path} must be a boolean.`);
|
|
259
|
+
}
|
|
260
|
+
function requireFiniteNumber(value, path) {
|
|
261
|
+
if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${path} must be a finite number.`);
|
|
262
|
+
}
|
|
263
|
+
function requireArray(value, path) {
|
|
264
|
+
if (!Array.isArray(value)) throw new Error(`${path} must be an array.`);
|
|
265
|
+
return value;
|
|
266
|
+
}
|
|
267
|
+
function stripLegacyEditorSelections(data) {
|
|
268
|
+
const { selectedSuiteId: _selectedSuiteId, selectedDatasetId: _selectedDatasetId, ...projectData } = data;
|
|
269
|
+
return projectData;
|
|
270
|
+
}
|
|
271
|
+
function validateOptionalPrimitive(record, key, type, path) {
|
|
272
|
+
const value = record[key];
|
|
273
|
+
if (value === void 0) return;
|
|
274
|
+
if (type === "number") requireFiniteNumber(value, `${path}.${key}`);
|
|
275
|
+
else if (typeof value !== type) throw new Error(`${path}.${key} must be a ${type}.`);
|
|
276
|
+
}
|
|
277
|
+
var ASSERTION_OPERATORS = /* @__PURE__ */ new Set([
|
|
278
|
+
"equals",
|
|
279
|
+
"not-equals",
|
|
280
|
+
"contains",
|
|
281
|
+
"matches-regex",
|
|
282
|
+
"type-is",
|
|
283
|
+
"json-schema",
|
|
284
|
+
"number-at-least",
|
|
285
|
+
"number-at-most",
|
|
286
|
+
"number-between",
|
|
287
|
+
"array-includes",
|
|
288
|
+
"set-overlaps",
|
|
289
|
+
"contains-any",
|
|
290
|
+
"contains-all"
|
|
291
|
+
]);
|
|
292
|
+
var EVALUATOR_CONTEXT_INPUTS = /* @__PURE__ */ new Set(["case", "inputs", "expected", "outputs", "run"]);
|
|
293
|
+
function validateSuiteShape(value, index) {
|
|
294
|
+
const path = `evaluations.suites[${index}]`;
|
|
295
|
+
const suite = requireRecord(value, path);
|
|
296
|
+
for (const key of ["id", "targetGraphId", "datasetId"]) requireString(suite[key], `${path}.${key}`);
|
|
297
|
+
requireText(suite.name, `${path}.name`);
|
|
298
|
+
if (suite.evaluationMode !== void 0 && suite.evaluationMode !== "pass-fail" && suite.evaluationMode !== "scoring") {
|
|
299
|
+
throw new Error(`${path}.evaluationMode must be "pass-fail" or "scoring".`);
|
|
300
|
+
}
|
|
301
|
+
for (const [bindingIndex, bindingValue] of requireArray(suite.inputBindings, `${path}.inputBindings`).entries()) {
|
|
302
|
+
const binding = requireRecord(bindingValue, `${path}.inputBindings[${bindingIndex}]`);
|
|
303
|
+
requireString(binding.graphInputId, `${path}.inputBindings[${bindingIndex}].graphInputId`);
|
|
304
|
+
requireString(binding.datasetFieldId, `${path}.inputBindings[${bindingIndex}].datasetFieldId`);
|
|
305
|
+
}
|
|
306
|
+
for (const [assertionIndex, assertionValue] of requireArray(suite.assertions, `${path}.assertions`).entries()) {
|
|
307
|
+
const assertionPath = `${path}.assertions[${assertionIndex}]`;
|
|
308
|
+
const assertion = requireRecord(assertionValue, assertionPath);
|
|
309
|
+
for (const key of ["id", "outputPath"]) requireString(assertion[key], `${assertionPath}.${key}`);
|
|
310
|
+
requireText(assertion.name, `${assertionPath}.name`);
|
|
311
|
+
if (typeof assertion.operator !== "string" || !ASSERTION_OPERATORS.has(assertion.operator)) {
|
|
312
|
+
throw new Error(`${assertionPath}.operator is not supported.`);
|
|
313
|
+
}
|
|
314
|
+
validateOptionalPrimitive(assertion, "required", "boolean", assertionPath);
|
|
315
|
+
const expected = requireRecord(assertion.expected, `${assertionPath}.expected`);
|
|
316
|
+
if (expected.kind === "literal") {
|
|
317
|
+
if (!Object.hasOwn(expected, "value")) throw new Error(`${assertionPath}.expected.value is required.`);
|
|
318
|
+
} else if (expected.kind === "dataset-field") {
|
|
319
|
+
requireString(expected.fieldId, `${assertionPath}.expected.fieldId`);
|
|
320
|
+
} else {
|
|
321
|
+
throw new Error(`${assertionPath}.expected.kind must be "literal" or "dataset-field".`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
for (const [evaluatorIndex, evaluatorValue] of requireArray(suite.evaluators, `${path}.evaluators`).entries()) {
|
|
325
|
+
const evaluatorPath = `${path}.evaluators[${evaluatorIndex}]`;
|
|
326
|
+
const evaluator = requireRecord(evaluatorValue, evaluatorPath);
|
|
327
|
+
for (const key of ["id", "graphId"]) requireString(evaluator[key], `${evaluatorPath}.${key}`);
|
|
328
|
+
requireText(evaluator.name, `${evaluatorPath}.name`);
|
|
329
|
+
validateOptionalPrimitive(evaluator, "required", "boolean", evaluatorPath);
|
|
330
|
+
validateOptionalPrimitive(evaluator, "runOnTargetError", "boolean", evaluatorPath);
|
|
331
|
+
validateOptionalPrimitive(evaluator, "scoreWeight", "number", evaluatorPath);
|
|
332
|
+
if (evaluator.inputBindings !== void 0) {
|
|
333
|
+
for (const [bindingIndex, bindingValue] of requireArray(
|
|
334
|
+
evaluator.inputBindings,
|
|
335
|
+
`${evaluatorPath}.inputBindings`
|
|
336
|
+
).entries()) {
|
|
337
|
+
const bindingPath = `${evaluatorPath}.inputBindings[${bindingIndex}]`;
|
|
338
|
+
const binding = requireRecord(bindingValue, bindingPath);
|
|
339
|
+
requireString(binding.graphInputId, `${bindingPath}.graphInputId`);
|
|
340
|
+
const source = requireRecord(binding.source, `${bindingPath}.source`);
|
|
341
|
+
if (source.kind === "dataset-field") requireString(source.fieldId, `${bindingPath}.source.fieldId`);
|
|
342
|
+
else if (source.kind === "target-output") requireString(source.outputId, `${bindingPath}.source.outputId`);
|
|
343
|
+
else if (source.kind === "context") {
|
|
344
|
+
if (typeof source.context !== "string" || !EVALUATOR_CONTEXT_INPUTS.has(source.context)) {
|
|
345
|
+
throw new Error(`${bindingPath}.source.context is not supported.`);
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
throw new Error(`${bindingPath}.source.kind is not supported.`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
if (suite.thresholds !== void 0) {
|
|
354
|
+
for (const [thresholdIndex, thresholdValue] of requireArray(suite.thresholds, `${path}.thresholds`).entries()) {
|
|
355
|
+
const thresholdPath = `${path}.thresholds[${thresholdIndex}]`;
|
|
356
|
+
const threshold = requireRecord(thresholdValue, thresholdPath);
|
|
357
|
+
for (const key of ["id", "metric", "operator"]) requireString(threshold[key], `${thresholdPath}.${key}`);
|
|
358
|
+
requireFiniteNumber(threshold.value, `${thresholdPath}.value`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (suite.configuration !== void 0) {
|
|
362
|
+
const configuration = requireRecord(suite.configuration, `${path}.configuration`);
|
|
363
|
+
for (const key of ["trialCount", "concurrency", "timeoutMs", "seed"]) {
|
|
364
|
+
validateOptionalPrimitive(configuration, key, "number", `${path}.configuration`);
|
|
365
|
+
}
|
|
366
|
+
validateOptionalPrimitive(configuration, "seedGraphInputId", "string", `${path}.configuration`);
|
|
367
|
+
validateOptionalPrimitive(configuration, "recordingRetention", "string", `${path}.configuration`);
|
|
368
|
+
}
|
|
369
|
+
validateOptionalPrimitive(suite, "description", "string", path);
|
|
370
|
+
if (suite.tags !== void 0) {
|
|
371
|
+
for (const [tagIndex, tag] of requireArray(suite.tags, `${path}.tags`).entries()) {
|
|
372
|
+
requireString(tag, `${path}.tags[${tagIndex}]`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function validateNumericRecord(value, path) {
|
|
377
|
+
const record = requireRecord(value, path);
|
|
378
|
+
for (const [key, entry] of Object.entries(record)) requireFiniteNumber(entry, `${path}.${key}`);
|
|
379
|
+
}
|
|
380
|
+
function validateBaselineShape(value, index) {
|
|
381
|
+
const path = `evaluations.baselines[${index}]`;
|
|
382
|
+
const baseline = requireRecord(value, path);
|
|
383
|
+
for (const key of ["id", "suiteId", "createdAt"]) requireString(baseline[key], `${path}.${key}`);
|
|
384
|
+
validateOptionalPrimitive(baseline, "sourceRunId", "string", path);
|
|
385
|
+
if (baseline.evaluationMode !== void 0 && baseline.evaluationMode !== "pass-fail" && baseline.evaluationMode !== "scoring") {
|
|
386
|
+
throw new Error(`${path}.evaluationMode must be "pass-fail" or "scoring".`);
|
|
387
|
+
}
|
|
388
|
+
const provenance = requireRecord(baseline.provenance, `${path}.provenance`);
|
|
389
|
+
for (const key of [
|
|
390
|
+
"projectFingerprint",
|
|
391
|
+
"suiteFingerprint",
|
|
392
|
+
"datasetFingerprint",
|
|
393
|
+
"targetFingerprint",
|
|
394
|
+
"executionMode"
|
|
395
|
+
]) {
|
|
396
|
+
requireString(provenance[key], `${path}.provenance.${key}`);
|
|
397
|
+
}
|
|
398
|
+
const evaluatorFingerprints = requireRecord(
|
|
399
|
+
provenance.evaluatorFingerprints,
|
|
400
|
+
`${path}.provenance.evaluatorFingerprints`
|
|
401
|
+
);
|
|
402
|
+
for (const [key, fingerprint] of Object.entries(evaluatorFingerprints)) {
|
|
403
|
+
requireString(fingerprint, `${path}.provenance.evaluatorFingerprints.${key}`);
|
|
404
|
+
}
|
|
405
|
+
requireBoolean(provenance.accountingComplete, `${path}.provenance.accountingComplete`);
|
|
406
|
+
const aggregate = requireRecord(baseline.aggregate, `${path}.aggregate`);
|
|
407
|
+
for (const key of [
|
|
408
|
+
"trialCount",
|
|
409
|
+
"passedTrialCount",
|
|
410
|
+
"failedTrialCount",
|
|
411
|
+
"erroredTrialCount",
|
|
412
|
+
"canceledTrialCount",
|
|
413
|
+
"passRate",
|
|
414
|
+
"averageLatencyMs",
|
|
415
|
+
"p95LatencyMs",
|
|
416
|
+
"targetErrorRate",
|
|
417
|
+
"evaluatorErrorRate",
|
|
418
|
+
"toolFailureRate"
|
|
419
|
+
]) {
|
|
420
|
+
requireFiniteNumber(aggregate[key], `${path}.aggregate.${key}`);
|
|
421
|
+
}
|
|
422
|
+
for (const key of [
|
|
423
|
+
"evaluatedTrialCount",
|
|
424
|
+
"notEvaluatedTrialCount",
|
|
425
|
+
"unableToEvaluateTrialCount",
|
|
426
|
+
"meanScore",
|
|
427
|
+
"medianScore",
|
|
428
|
+
"p95Score",
|
|
429
|
+
"medianLatencyMs",
|
|
430
|
+
"totalCostUsd",
|
|
431
|
+
"averageCostUsd",
|
|
432
|
+
"scoredTrialCount",
|
|
433
|
+
"missingScoreTrialCount"
|
|
434
|
+
]) {
|
|
435
|
+
validateOptionalPrimitive(aggregate, key, "number", `${path}.aggregate`);
|
|
436
|
+
}
|
|
437
|
+
validateNumericRecord(aggregate.metrics, `${path}.aggregate.metrics`);
|
|
438
|
+
for (const [caseIndex, caseValue] of requireArray(baseline.cases, `${path}.cases`).entries()) {
|
|
439
|
+
const casePath = `${path}.cases[${caseIndex}]`;
|
|
440
|
+
const caseAggregate = requireRecord(caseValue, casePath);
|
|
441
|
+
requireString(caseAggregate.caseId, `${casePath}.caseId`);
|
|
442
|
+
requireString(caseAggregate.caseName, `${casePath}.caseName`);
|
|
443
|
+
validateNumericRecord(caseAggregate.metrics, `${casePath}.metrics`);
|
|
444
|
+
for (const key of [
|
|
445
|
+
"passRate",
|
|
446
|
+
"meanScore",
|
|
447
|
+
"evaluatedTrialCount",
|
|
448
|
+
"passedTrialCount",
|
|
449
|
+
"failedTrialCount",
|
|
450
|
+
"notEvaluatedTrialCount",
|
|
451
|
+
"unableToEvaluateTrialCount",
|
|
452
|
+
"erroredTrialCount",
|
|
453
|
+
"canceledTrialCount",
|
|
454
|
+
"scoredTrialCount",
|
|
455
|
+
"missingScoreTrialCount"
|
|
456
|
+
]) {
|
|
457
|
+
validateOptionalPrimitive(caseAggregate, key, "number", casePath);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
function createEmptyEvaluationProjectData() {
|
|
462
|
+
return { version: 1, suites: [], baselines: [] };
|
|
463
|
+
}
|
|
464
|
+
function serializeEvaluationProjectData(data) {
|
|
465
|
+
if (data.version !== 1) throw new Error(`Unsupported evaluation data version: ${data.version}`);
|
|
466
|
+
const persistentData = stripLegacyEditorSelections(data);
|
|
467
|
+
assertPortableJson(persistentData);
|
|
468
|
+
return {
|
|
469
|
+
...structuredClone(persistentData),
|
|
470
|
+
baselines: persistentData.baselines.map(normalizeEvaluationBaselineSnapshot)
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
function deserializeEvaluationProjectData(data) {
|
|
474
|
+
if (data === null || typeof data !== "object" || Array.isArray(data))
|
|
475
|
+
throw new Error("Evaluation project data must be an object.");
|
|
476
|
+
const candidate = data;
|
|
477
|
+
if (candidate.version !== 1 || !Array.isArray(candidate.suites) || !Array.isArray(candidate.baselines)) {
|
|
478
|
+
throw new Error("Unsupported or invalid evaluation project data.");
|
|
479
|
+
}
|
|
480
|
+
const persistentData = stripLegacyEditorSelections(candidate);
|
|
481
|
+
assertPortableJson(persistentData);
|
|
482
|
+
persistentData.suites.forEach(validateSuiteShape);
|
|
483
|
+
persistentData.baselines.forEach(validateBaselineShape);
|
|
484
|
+
return {
|
|
485
|
+
...structuredClone(persistentData),
|
|
486
|
+
baselines: persistentData.baselines.map(normalizeEvaluationBaselineSnapshot)
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
function serializeEvaluationProjectDataToString(data) {
|
|
490
|
+
return yaml.stringify(serializeEvaluationProjectData(data), null, 2);
|
|
491
|
+
}
|
|
492
|
+
function deserializeEvaluationProjectDataFromString(data) {
|
|
493
|
+
return deserializeEvaluationProjectData(yaml.parse(data));
|
|
494
|
+
}
|
|
495
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
496
|
+
0 && (module.exports = {
|
|
497
|
+
createEmptyEvaluationProjectData,
|
|
498
|
+
deserializeEvaluationProjectData,
|
|
499
|
+
deserializeEvaluationProjectDataFromString,
|
|
500
|
+
serializeEvaluationProjectData,
|
|
501
|
+
serializeEvaluationProjectDataToString
|
|
502
|
+
});
|
|
503
|
+
//# sourceMappingURL=serialization.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/serialization.ts", "../../src/canonical.ts", "../../src/normalization.ts"],
|
|
4
|
+
"sourcesContent": ["import * as yaml from 'yaml';\nimport { assertPortableJson } from './canonical.js';\nimport { normalizeEvaluationBaselineSnapshot } from './normalization.js';\nimport type { EvaluationProjectData, EvaluationSuite } from './types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction requireRecord(value: unknown, path: string): Record<string, unknown> {\n if (!isRecord(value)) throw new Error(`${path} must be an object.`);\n return value;\n}\n\nfunction requireString(value: unknown, path: string): void {\n if (typeof value !== 'string' || value.trim().length === 0) throw new Error(`${path} must be a non-empty string.`);\n}\n\nfunction requireText(value: unknown, path: string): void {\n if (typeof value !== 'string') throw new Error(`${path} must be a string.`);\n}\n\nfunction requireBoolean(value: unknown, path: string): void {\n if (typeof value !== 'boolean') throw new Error(`${path} must be a boolean.`);\n}\n\nfunction requireFiniteNumber(value: unknown, path: string): void {\n if (typeof value !== 'number' || !Number.isFinite(value)) throw new Error(`${path} must be a finite number.`);\n}\n\nfunction requireArray(value: unknown, path: string): readonly unknown[] {\n if (!Array.isArray(value)) throw new Error(`${path} must be an array.`);\n return value;\n}\n\ntype LegacyEvaluationProjectData = EvaluationProjectData & {\n selectedSuiteId?: unknown;\n selectedDatasetId?: unknown;\n};\n\n/**\n * Selection is editor workspace state, not executable project data. Older\n * project attachments can contain these fields, and previous editors could\n * put an explicit `undefined` here, which is not portable JSON. They have no\n * effect on project behavior, so discard both fields before validation.\n */\nfunction stripLegacyEditorSelections(data: LegacyEvaluationProjectData): EvaluationProjectData {\n const { selectedSuiteId: _selectedSuiteId, selectedDatasetId: _selectedDatasetId, ...projectData } = data;\n return projectData;\n}\n\nfunction validateOptionalPrimitive(\n record: Record<string, unknown>,\n key: string,\n type: 'string' | 'boolean' | 'number',\n path: string,\n): void {\n const value = record[key];\n if (value === undefined) return;\n if (type === 'number') requireFiniteNumber(value, `${path}.${key}`);\n else if (typeof value !== type) throw new Error(`${path}.${key} must be a ${type}.`);\n}\n\nconst ASSERTION_OPERATORS = new Set([\n 'equals',\n 'not-equals',\n 'contains',\n 'matches-regex',\n 'type-is',\n 'json-schema',\n 'number-at-least',\n 'number-at-most',\n 'number-between',\n 'array-includes',\n 'set-overlaps',\n 'contains-any',\n 'contains-all',\n]);\nconst EVALUATOR_CONTEXT_INPUTS = new Set(['case', 'inputs', 'expected', 'outputs', 'run']);\n\nfunction validateSuiteShape(value: unknown, index: number): asserts value is EvaluationSuite {\n const path = `evaluations.suites[${index}]`;\n const suite = requireRecord(value, path);\n for (const key of ['id', 'targetGraphId', 'datasetId']) requireString(suite[key], `${path}.${key}`);\n requireText(suite.name, `${path}.name`);\n if (\n suite.evaluationMode !== undefined &&\n suite.evaluationMode !== 'pass-fail' &&\n suite.evaluationMode !== 'scoring'\n ) {\n throw new Error(`${path}.evaluationMode must be \"pass-fail\" or \"scoring\".`);\n }\n for (const [bindingIndex, bindingValue] of requireArray(suite.inputBindings, `${path}.inputBindings`).entries()) {\n const binding = requireRecord(bindingValue, `${path}.inputBindings[${bindingIndex}]`);\n requireString(binding.graphInputId, `${path}.inputBindings[${bindingIndex}].graphInputId`);\n requireString(binding.datasetFieldId, `${path}.inputBindings[${bindingIndex}].datasetFieldId`);\n }\n for (const [assertionIndex, assertionValue] of requireArray(suite.assertions, `${path}.assertions`).entries()) {\n const assertionPath = `${path}.assertions[${assertionIndex}]`;\n const assertion = requireRecord(assertionValue, assertionPath);\n for (const key of ['id', 'outputPath']) requireString(assertion[key], `${assertionPath}.${key}`);\n requireText(assertion.name, `${assertionPath}.name`);\n if (typeof assertion.operator !== 'string' || !ASSERTION_OPERATORS.has(assertion.operator)) {\n throw new Error(`${assertionPath}.operator is not supported.`);\n }\n validateOptionalPrimitive(assertion, 'required', 'boolean', assertionPath);\n const expected = requireRecord(assertion.expected, `${assertionPath}.expected`);\n if (expected.kind === 'literal') {\n if (!Object.hasOwn(expected, 'value')) throw new Error(`${assertionPath}.expected.value is required.`);\n } else if (expected.kind === 'dataset-field') {\n requireString(expected.fieldId, `${assertionPath}.expected.fieldId`);\n } else {\n throw new Error(`${assertionPath}.expected.kind must be \"literal\" or \"dataset-field\".`);\n }\n }\n for (const [evaluatorIndex, evaluatorValue] of requireArray(suite.evaluators, `${path}.evaluators`).entries()) {\n const evaluatorPath = `${path}.evaluators[${evaluatorIndex}]`;\n const evaluator = requireRecord(evaluatorValue, evaluatorPath);\n for (const key of ['id', 'graphId']) requireString(evaluator[key], `${evaluatorPath}.${key}`);\n requireText(evaluator.name, `${evaluatorPath}.name`);\n validateOptionalPrimitive(evaluator, 'required', 'boolean', evaluatorPath);\n validateOptionalPrimitive(evaluator, 'runOnTargetError', 'boolean', evaluatorPath);\n validateOptionalPrimitive(evaluator, 'scoreWeight', 'number', evaluatorPath);\n if (evaluator.inputBindings !== undefined) {\n for (const [bindingIndex, bindingValue] of requireArray(\n evaluator.inputBindings,\n `${evaluatorPath}.inputBindings`,\n ).entries()) {\n const bindingPath = `${evaluatorPath}.inputBindings[${bindingIndex}]`;\n const binding = requireRecord(bindingValue, bindingPath);\n requireString(binding.graphInputId, `${bindingPath}.graphInputId`);\n const source = requireRecord(binding.source, `${bindingPath}.source`);\n if (source.kind === 'dataset-field') requireString(source.fieldId, `${bindingPath}.source.fieldId`);\n else if (source.kind === 'target-output') requireString(source.outputId, `${bindingPath}.source.outputId`);\n else if (source.kind === 'context') {\n if (typeof source.context !== 'string' || !EVALUATOR_CONTEXT_INPUTS.has(source.context)) {\n throw new Error(`${bindingPath}.source.context is not supported.`);\n }\n } else {\n throw new Error(`${bindingPath}.source.kind is not supported.`);\n }\n }\n }\n }\n if (suite.thresholds !== undefined) {\n for (const [thresholdIndex, thresholdValue] of requireArray(suite.thresholds, `${path}.thresholds`).entries()) {\n const thresholdPath = `${path}.thresholds[${thresholdIndex}]`;\n const threshold = requireRecord(thresholdValue, thresholdPath);\n for (const key of ['id', 'metric', 'operator']) requireString(threshold[key], `${thresholdPath}.${key}`);\n requireFiniteNumber(threshold.value, `${thresholdPath}.value`);\n }\n }\n if (suite.configuration !== undefined) {\n const configuration = requireRecord(suite.configuration, `${path}.configuration`);\n for (const key of ['trialCount', 'concurrency', 'timeoutMs', 'seed']) {\n validateOptionalPrimitive(configuration, key, 'number', `${path}.configuration`);\n }\n validateOptionalPrimitive(configuration, 'seedGraphInputId', 'string', `${path}.configuration`);\n validateOptionalPrimitive(configuration, 'recordingRetention', 'string', `${path}.configuration`);\n }\n validateOptionalPrimitive(suite, 'description', 'string', path);\n if (suite.tags !== undefined) {\n for (const [tagIndex, tag] of requireArray(suite.tags, `${path}.tags`).entries()) {\n requireString(tag, `${path}.tags[${tagIndex}]`);\n }\n }\n}\n\nfunction validateNumericRecord(value: unknown, path: string): void {\n const record = requireRecord(value, path);\n for (const [key, entry] of Object.entries(record)) requireFiniteNumber(entry, `${path}.${key}`);\n}\n\nfunction validateBaselineShape(value: unknown, index: number): void {\n const path = `evaluations.baselines[${index}]`;\n const baseline = requireRecord(value, path);\n for (const key of ['id', 'suiteId', 'createdAt']) requireString(baseline[key], `${path}.${key}`);\n validateOptionalPrimitive(baseline, 'sourceRunId', 'string', path);\n if (\n baseline.evaluationMode !== undefined &&\n baseline.evaluationMode !== 'pass-fail' &&\n baseline.evaluationMode !== 'scoring'\n ) {\n throw new Error(`${path}.evaluationMode must be \"pass-fail\" or \"scoring\".`);\n }\n const provenance = requireRecord(baseline.provenance, `${path}.provenance`);\n for (const key of [\n 'projectFingerprint',\n 'suiteFingerprint',\n 'datasetFingerprint',\n 'targetFingerprint',\n 'executionMode',\n ]) {\n requireString(provenance[key], `${path}.provenance.${key}`);\n }\n const evaluatorFingerprints = requireRecord(\n provenance.evaluatorFingerprints,\n `${path}.provenance.evaluatorFingerprints`,\n );\n for (const [key, fingerprint] of Object.entries(evaluatorFingerprints)) {\n requireString(fingerprint, `${path}.provenance.evaluatorFingerprints.${key}`);\n }\n requireBoolean(provenance.accountingComplete, `${path}.provenance.accountingComplete`);\n const aggregate = requireRecord(baseline.aggregate, `${path}.aggregate`);\n for (const key of [\n 'trialCount',\n 'passedTrialCount',\n 'failedTrialCount',\n 'erroredTrialCount',\n 'canceledTrialCount',\n 'passRate',\n 'averageLatencyMs',\n 'p95LatencyMs',\n 'targetErrorRate',\n 'evaluatorErrorRate',\n 'toolFailureRate',\n ]) {\n requireFiniteNumber(aggregate[key], `${path}.aggregate.${key}`);\n }\n for (const key of [\n 'evaluatedTrialCount',\n 'notEvaluatedTrialCount',\n 'unableToEvaluateTrialCount',\n 'meanScore',\n 'medianScore',\n 'p95Score',\n 'medianLatencyMs',\n 'totalCostUsd',\n 'averageCostUsd',\n 'scoredTrialCount',\n 'missingScoreTrialCount',\n ]) {\n validateOptionalPrimitive(aggregate, key, 'number', `${path}.aggregate`);\n }\n validateNumericRecord(aggregate.metrics, `${path}.aggregate.metrics`);\n for (const [caseIndex, caseValue] of requireArray(baseline.cases, `${path}.cases`).entries()) {\n const casePath = `${path}.cases[${caseIndex}]`;\n const caseAggregate = requireRecord(caseValue, casePath);\n requireString(caseAggregate.caseId, `${casePath}.caseId`);\n requireString(caseAggregate.caseName, `${casePath}.caseName`);\n validateNumericRecord(caseAggregate.metrics, `${casePath}.metrics`);\n for (const key of [\n 'passRate',\n 'meanScore',\n 'evaluatedTrialCount',\n 'passedTrialCount',\n 'failedTrialCount',\n 'notEvaluatedTrialCount',\n 'unableToEvaluateTrialCount',\n 'erroredTrialCount',\n 'canceledTrialCount',\n 'scoredTrialCount',\n 'missingScoreTrialCount',\n ]) {\n validateOptionalPrimitive(caseAggregate, key, 'number', casePath);\n }\n }\n}\n\nexport function createEmptyEvaluationProjectData(): EvaluationProjectData {\n return { version: 1, suites: [], baselines: [] };\n}\n\nexport function serializeEvaluationProjectData(data: EvaluationProjectData): EvaluationProjectData {\n if (data.version !== 1) throw new Error(`Unsupported evaluation data version: ${data.version}`);\n const persistentData = stripLegacyEditorSelections(data as LegacyEvaluationProjectData);\n assertPortableJson(persistentData);\n return {\n ...structuredClone(persistentData),\n baselines: persistentData.baselines.map(normalizeEvaluationBaselineSnapshot),\n };\n}\n\nexport function deserializeEvaluationProjectData(data: unknown): EvaluationProjectData {\n if (data === null || typeof data !== 'object' || Array.isArray(data))\n throw new Error('Evaluation project data must be an object.');\n const candidate = data as Partial<LegacyEvaluationProjectData>;\n if (candidate.version !== 1 || !Array.isArray(candidate.suites) || !Array.isArray(candidate.baselines)) {\n throw new Error('Unsupported or invalid evaluation project data.');\n }\n const persistentData = stripLegacyEditorSelections(candidate as LegacyEvaluationProjectData);\n assertPortableJson(persistentData);\n persistentData.suites.forEach(validateSuiteShape);\n persistentData.baselines.forEach(validateBaselineShape);\n return {\n ...structuredClone(persistentData),\n baselines: persistentData.baselines.map(normalizeEvaluationBaselineSnapshot),\n };\n}\n\nexport function serializeEvaluationProjectDataToString(data: EvaluationProjectData): string {\n return yaml.stringify(serializeEvaluationProjectData(data), null, 2);\n}\n\nexport function deserializeEvaluationProjectDataFromString(data: string): EvaluationProjectData {\n return deserializeEvaluationProjectData(yaml.parse(data));\n}\n", "import type { EvaluationDatasetSnapshot, EvaluationRecordingArtifact, PortableJson } from './types.js';\n\nexport function assertPortableJson(\n value: unknown,\n path = '$',\n stack = new Set<object>(),\n): asserts value is PortableJson {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return;\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) throw new Error(`${path} must not contain a non-finite number.`);\n return;\n }\n if (typeof value !== 'object') throw new Error(`${path} must be portable JSON.`);\n if (stack.has(value)) throw new Error(`${path} must not contain a cycle.`);\n if (Array.isArray(value)) {\n if (Object.getOwnPropertySymbols(value).length > 0) {\n throw new Error(`${path} must not contain symbol-keyed array properties.`);\n }\n stack.add(value);\n try {\n for (let index = 0; index < value.length; index += 1) {\n const descriptor = Object.getOwnPropertyDescriptor(value, index);\n if (!descriptor) throw new Error(`${path}[${index}] must not be a sparse array entry.`);\n if (!descriptor.enumerable || descriptor.get || descriptor.set) {\n throw new Error(`${path}[${index}] must be an enumerable data property.`);\n }\n assertPortableJson(descriptor.value, `${path}[${index}]`, stack);\n }\n if (Object.getOwnPropertyNames(value).length !== value.length + 1) {\n throw new Error(`${path} must not contain hidden or extra array properties.`);\n }\n } finally {\n stack.delete(value);\n }\n return;\n }\n if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {\n throw new Error(`${path} must be a plain object.`);\n }\n if (Object.getOwnPropertySymbols(value).length > 0) {\n throw new Error(`${path} must not contain symbol-keyed object properties.`);\n }\n const ownPropertyNames = Object.getOwnPropertyNames(value);\n const keys = Object.keys(value);\n if (ownPropertyNames.length !== keys.length) {\n throw new Error(`${path} must not contain non-enumerable object properties.`);\n }\n stack.add(value);\n try {\n for (const key of keys) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (!descriptor || descriptor.get || descriptor.set) {\n throw new Error(`${path}.${key} must be an enumerable data property.`);\n }\n assertPortableJson(descriptor.value, `${path}.${key}`, stack);\n }\n } finally {\n stack.delete(value);\n }\n}\n\nexport function canonicalizePortableJson(value: unknown): PortableJson {\n assertPortableJson(value);\n if (value === null || typeof value !== 'object') return value;\n if (Array.isArray(value)) return value.map(canonicalizePortableJson);\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, canonicalizePortableJson(value[key])]),\n );\n}\n\n/**\n * Evaluation inputs and observations cross concurrent graph-run boundaries.\n * Clone them before handing them to an adapter so a Code or evaluator graph\n * cannot mutate a dataset case, another trial, or the persisted run model.\n */\nexport function clonePortableJson<T extends PortableJson>(value: T): T {\n assertPortableJson(value);\n return structuredClone(value);\n}\n\nexport function canonicalStringify(value: unknown): string {\n return JSON.stringify(canonicalizePortableJson(value));\n}\n\n/** Stable, synchronously available content fingerprint for project-local identities. */\nexport function fingerprint(value: unknown): string {\n const source = canonicalStringify(value);\n let hash = 0xcbf29ce484222325n;\n for (let index = 0; index < source.length; index += 1) {\n hash ^= BigInt(source.charCodeAt(index));\n hash = BigInt.asUintN(64, hash * 0x100000001b3n);\n }\n return `fnv1a64:${hash.toString(16).padStart(16, '0')}`;\n}\n\nexport function fingerprintEvaluationDataset(value: { id: unknown; fields: unknown; cases: unknown }): string {\n return fingerprint({ datasetId: value.id, fields: value.fields, cases: value.cases });\n}\n\n/**\n * A dataset fingerprint is the link between a compact run summary and its\n * historical input cases. Stores must reject a mismatched key rather than\n * accepting a snapshot that can no longer prove which cases were run.\n */\nexport function assertEvaluationDatasetSnapshot(snapshot: EvaluationDatasetSnapshot): void {\n if (\n typeof snapshot.projectId !== 'string' ||\n snapshot.projectId.length === 0 ||\n typeof snapshot.fingerprint !== 'string' ||\n snapshot.fingerprint.length === 0 ||\n typeof snapshot.createdAt !== 'string' ||\n !Number.isFinite(Date.parse(snapshot.createdAt))\n ) {\n throw new Error('An evaluation dataset snapshot has invalid identity or creation time.');\n }\n if (snapshot.dataset.projectId !== snapshot.projectId) {\n throw new Error('An evaluation dataset snapshot must belong to its project.');\n }\n if (fingerprintEvaluationDataset(snapshot.dataset) !== snapshot.fingerprint) {\n throw new Error('An evaluation dataset snapshot fingerprint must match its dataset ID, fields, and cases.');\n }\n}\n\n/** Rejects malformed replay evidence at both write and durable-read boundaries. */\nexport function assertEvaluationRecordingArtifact(value: unknown): asserts value is EvaluationRecordingArtifact {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error('An evaluation recording artifact must be an object.');\n }\n const artifact = value as Partial<EvaluationRecordingArtifact>;\n if (\n typeof artifact.projectId !== 'string' ||\n artifact.projectId.length === 0 ||\n typeof artifact.runId !== 'string' ||\n artifact.runId.length === 0 ||\n typeof artifact.trialId !== 'string' ||\n artifact.trialId.length === 0 ||\n typeof artifact.serialized !== 'string' ||\n typeof artifact.createdAt !== 'string' ||\n !Number.isFinite(Date.parse(artifact.createdAt))\n ) {\n throw new Error('An evaluation recording artifact has invalid identity, payload, or creation time.');\n }\n const reference = artifact.reference;\n if (\n typeof reference !== 'object' ||\n reference === null ||\n typeof reference.id !== 'string' ||\n reference.id.length === 0 ||\n !['temporary', 'failure', 'baseline', 'retained'].includes(reference.retention ?? '') ||\n (reference.expiresAt !== undefined &&\n (typeof reference.expiresAt !== 'string' || !Number.isFinite(Date.parse(reference.expiresAt))))\n ) {\n throw new Error('An evaluation recording artifact has an invalid retention reference.');\n }\n}\n", "import type {\n EvaluationAccountingStatus,\n EvaluationAggregate,\n EvaluationBaselineSnapshot,\n EvaluationQualityReason,\n EvaluationQualityStatus,\n EvaluationRun,\n EvaluationRunPurpose,\n EvaluationSuiteMode,\n EvaluationTrial,\n EvaluationTrialExecutionStatus,\n} from './types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isQualityStatus(value: unknown): value is EvaluationQualityStatus {\n return ['passed', 'failed', 'scored', 'not-evaluated', 'unable-to-evaluate'].includes(String(value));\n}\n\nfunction isEvaluationMode(value: unknown): value is EvaluationSuiteMode {\n return value === 'pass-fail' || value === 'scoring';\n}\n\nfunction isQualityStatusForMode(status: EvaluationQualityStatus, evaluationMode: EvaluationSuiteMode): boolean {\n return evaluationMode === 'scoring' ? status !== 'passed' && status !== 'failed' : status !== 'scored';\n}\n\nfunction isExecutionStatus(value: unknown): value is EvaluationTrialExecutionStatus {\n return ['completed', 'error', 'canceled'].includes(String(value));\n}\n\nfunction isRunExecutionStatus(value: unknown): value is EvaluationRun['executionStatus'] {\n return ['queued', 'running', 'completed', 'canceled', 'error'].includes(String(value));\n}\n\nfunction isTerminalRunExecutionStatus(status: EvaluationRun['executionStatus']): boolean {\n return status === 'completed' || status === 'canceled' || status === 'error';\n}\n\nfunction reconcileRecordingReference(\n primary: EvaluationTrial['recording'],\n secondary: EvaluationTrial['recording'],\n): EvaluationTrial['recording'] {\n if (!primary) return secondary;\n if (!secondary) return primary;\n const rank = (retention: NonNullable<EvaluationTrial['recording']>['retention']): number =>\n retention === 'temporary' ? 0 : retention === 'failure' ? 1 : 2;\n return rank(secondary.retention) > rank(primary.retention) ? secondary : primary;\n}\n\n/**\n * Orders snapshots for one run without allowing an equal-revision progress\n * update to demote a terminal result. Writers and delayed UI reads share this\n * rule so persistence cannot disagree with what the workspace presents.\n */\nexport function shouldReplaceEvaluationRun(\n existing: Pick<EvaluationRun, 'executionStatus' | 'revision'> | undefined,\n incoming: Pick<EvaluationRun, 'executionStatus' | 'revision'>,\n): boolean {\n if (!existing) return true;\n const existingRevision = existing.revision ?? 0;\n const incomingRevision = incoming.revision ?? 0;\n if (incomingRevision !== existingRevision) return incomingRevision > existingRevision;\n return (\n !isTerminalRunExecutionStatus(existing.executionStatus) || isTerminalRunExecutionStatus(incoming.executionStatus)\n );\n}\n\n/**\n * Execution snapshots never own a user-assigned run name. Preserve it when a\n * runner publishes a newer progress or terminal revision after a rename.\n */\nexport function preserveEvaluationRunName(\n existing: Pick<EvaluationRun, 'name'> | undefined,\n incoming: EvaluationRun,\n): EvaluationRun {\n return existing?.name !== undefined && incoming.name === undefined ? { ...incoming, name: existing.name } : incoming;\n}\n\n/**\n * Reconciles two snapshots of the same run without discarding evidence.\n *\n * Revisions remain authoritative. Within one revision, however, persistence\n * and recording-retention updates can race with a terminal UI snapshot. Keep\n * the snapshot with the fuller trial set, while still allowing a terminal\n * snapshot to complete a progress snapshot and allowing recording references\n * and warnings to enrich already-settled evidence.\n */\nexport function reconcileEvaluationRunSnapshots(\n existing: EvaluationRun | undefined,\n incoming: EvaluationRun,\n): EvaluationRun {\n if (!existing) return incoming;\n\n const existingRevision = existing.revision ?? 0;\n const incomingRevision = incoming.revision ?? 0;\n if (incomingRevision < existingRevision) return existing;\n if (incomingRevision > existingRevision) return preserveEvaluationRunName(existing, incoming);\n if (!shouldReplaceEvaluationRun(existing, incoming)) return existing;\n\n const existingTerminal = isTerminalRunExecutionStatus(existing.executionStatus);\n const incomingTerminal = isTerminalRunExecutionStatus(incoming.executionStatus);\n const existingTrials = existing.trials ?? [];\n const incomingTrials = incoming.trials ?? [];\n const incomingIsPrimary =\n incomingTerminal !== existingTerminal ? incomingTerminal : incomingTrials.length >= existingTrials.length;\n const primary = preserveEvaluationRunName(existing, incomingIsPrimary ? incoming : existing);\n const secondary = incomingIsPrimary ? existing : incoming;\n const primaryTrials = primary.trials ?? [];\n const secondaryTrialList = secondary.trials ?? [];\n const name = existing.name ?? incoming.name;\n const primaryTrialIds = new Set(primaryTrials.map((trial) => trial.id));\n const secondaryTrials = new Map(secondaryTrialList.map((trial) => [trial.id, trial] as const));\n\n return {\n ...primary,\n trials: [\n ...primaryTrials.map((trial) => {\n const other = secondaryTrials.get(trial.id);\n if (!other) return trial;\n const secondaryObservations = new Map(\n (other.observations ?? []).map((observation) => [observation.id, observation] as const),\n );\n const primaryObservationIds = new Set((trial.observations ?? []).map((observation) => observation.id));\n const recording = reconcileRecordingReference(trial.recording, other.recording);\n return {\n ...trial,\n ...(recording === undefined ? {} : { recording }),\n observations: [\n ...(trial.observations ?? []).map((observation) => {\n const otherObservation = secondaryObservations.get(observation.id);\n const observationRecording = reconcileRecordingReference(\n observation.recording,\n otherObservation?.recording,\n );\n return observationRecording === observation.recording\n ? observation\n : {\n ...observation,\n ...(observationRecording === undefined ? {} : { recording: observationRecording }),\n };\n }),\n ...(other.observations ?? []).filter((observation) => !primaryObservationIds.has(observation.id)),\n ],\n };\n }),\n ...secondaryTrialList.filter((trial) => !primaryTrialIds.has(trial.id)),\n ],\n ...(name === undefined ? {} : { name }),\n warnings: [...new Set([...(primary.warnings ?? []), ...(secondary.warnings ?? [])])],\n };\n}\n\nfunction isPurpose(value: unknown): value is EvaluationRunPurpose {\n return value === 'evaluation' || value === 'execution-benchmark';\n}\n\nfunction isAccountingStatus(value: unknown): value is EvaluationAccountingStatus {\n return value === 'complete' || value === 'partial';\n}\n\n/** Run records keep scores normalized even though evaluator graphs use 0..100. */\nfunction isNormalizedScore(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= 1;\n}\n\nfunction reasonForQualityStatus(\n status: EvaluationQualityStatus,\n executionStatus?: EvaluationTrialExecutionStatus,\n): EvaluationQualityReason {\n if (executionStatus === 'canceled') return { code: 'canceled', message: 'The execution was canceled.' };\n if (executionStatus === 'error' && status === 'failed') {\n return { code: 'target-error', message: 'The target graph failed before it could produce a valid result.' };\n }\n switch (status) {\n case 'passed':\n return { code: 'checks-passed', message: 'All required quality criteria passed.' };\n case 'failed':\n return { code: 'checks-failed', message: 'One or more required quality criteria failed.' };\n case 'scored':\n return { code: 'scores-complete', message: 'Every requested trial produced a score.' };\n case 'not-evaluated':\n return { code: 'no-trial-quality-checks', message: 'No per-trial quality check evaluated this result.' };\n case 'unable-to-evaluate':\n return { code: 'required-check-error', message: 'A required quality criterion could not be evaluated.' };\n }\n}\n\nfunction reasonForQualityStatusInMode(\n status: EvaluationQualityStatus,\n evaluationMode: EvaluationSuiteMode,\n executionStatus?: EvaluationTrialExecutionStatus,\n): EvaluationQualityReason {\n if (evaluationMode === 'scoring' && status === 'unable-to-evaluate') {\n return { code: 'scores-incomplete', message: 'One or more requested trials did not produce a usable score.' };\n }\n return reasonForQualityStatus(status, executionStatus);\n}\n\nfunction isTargetExecutionError(value: Record<string, unknown>, observations: readonly unknown[]): boolean {\n if (typeof value.error === 'string' && value.error.length > 0) return true;\n return observations.some(\n (observation) =>\n isRecord(observation) &&\n observation.id === 'target-error' &&\n observation.kind === 'assertion' &&\n observation.status === 'error',\n );\n}\n\nfunction legacyQualityFromObservations(\n observations: readonly unknown[],\n targetExecutionError: boolean,\n): EvaluationQualityStatus {\n if (targetExecutionError) return 'failed';\n const required = observations.filter(\n (observation) => isRecord(observation) && observation.required !== false,\n ) as Array<Record<string, unknown>>;\n if (required.some((observation) => observation.status === 'failed')) return 'failed';\n if (required.some((observation) => observation.status === 'error')) return 'unable-to-evaluate';\n if (required.some((observation) => observation.status === 'passed')) return 'passed';\n return 'not-evaluated';\n}\n\n/**\n * Scoring runs are new enough that they do not need to preserve a legacy\n * pass/fail quality label. Do still recover a useful status when a partial or\n * hand-edited scoring record lacks its derived status, but never let an old\n * `passed`/`failed` value leak into the scoring UI.\n */\nfunction scoringQualityFromObservations(observations: readonly unknown[]): EvaluationQualityStatus {\n const evaluatorObservations = observations.filter(\n (observation): observation is Record<string, unknown> => isRecord(observation) && observation.kind === 'graph',\n );\n const hasCompleteScore =\n evaluatorObservations.length > 0 &&\n evaluatorObservations.every(\n (observation) =>\n observation.status === 'scored' &&\n typeof observation.score === 'number' &&\n Number.isFinite(observation.score) &&\n observation.score >= 0 &&\n observation.score <= 1,\n );\n return hasCompleteScore ? 'scored' : 'unable-to-evaluate';\n}\n\nfunction isQualityReasonCompatible(\n reason: EvaluationQualityReason,\n status: EvaluationQualityStatus,\n purpose: EvaluationRunPurpose,\n executionStatus?: EvaluationTrialExecutionStatus | EvaluationRun['executionStatus'],\n): boolean {\n if (purpose === 'execution-benchmark') {\n return executionStatus === 'canceled' ? reason.code === 'canceled' : reason.code === 'benchmark';\n }\n if (executionStatus === 'queued' || executionStatus === 'running') return reason.code === 'in-progress';\n if (executionStatus === 'canceled') return reason.code === 'canceled';\n switch (status) {\n case 'passed':\n return reason.code === 'checks-passed' || reason.code === 'thresholds-passed';\n case 'failed':\n return reason.code === 'checks-failed' || reason.code === 'thresholds-failed' || reason.code === 'target-error';\n case 'scored':\n return reason.code === 'scores-complete';\n case 'not-evaluated':\n return reason.code === 'no-trial-quality-checks' || reason.code === 'no-completed-trials';\n case 'unable-to-evaluate':\n return (\n reason.code === 'required-check-error' ||\n reason.code === 'required-metric-unavailable' ||\n reason.code === 'scores-incomplete'\n );\n }\n}\n\nfunction normalizeQualityReason(\n value: unknown,\n fallback: EvaluationQualityReason,\n status: EvaluationQualityStatus,\n purpose: EvaluationRunPurpose,\n executionStatus?: EvaluationTrialExecutionStatus | EvaluationRun['executionStatus'],\n): EvaluationQualityReason {\n if (!isRecord(value) || typeof value.code !== 'string' || typeof value.message !== 'string') return fallback;\n const reason = value as unknown as EvaluationQualityReason;\n return isQualityReasonCompatible(reason, status, purpose, executionStatus) ? reason : fallback;\n}\n\nexport function normalizeEvaluationTrial(\n value: EvaluationTrial | unknown,\n purpose: EvaluationRunPurpose = 'evaluation',\n evaluationMode: EvaluationSuiteMode = 'pass-fail',\n): EvaluationTrial {\n if (!isRecord(value)) throw new Error('Evaluation trial must be an object.');\n const legacyStatus = value.status;\n const observations = Array.isArray(value.observations) ? value.observations : [];\n const targetExecutionError = isTargetExecutionError(value, observations);\n const executionStatus = isExecutionStatus(value.executionStatus)\n ? value.executionStatus\n : legacyStatus === 'canceled'\n ? 'canceled'\n : targetExecutionError\n ? 'error'\n : legacyStatus === 'error' &&\n !observations.some(\n (observation) =>\n isRecord(observation) && observation.required !== false && observation.status === 'error',\n )\n ? 'error'\n : 'completed';\n const qualityStatus: EvaluationQualityStatus =\n purpose === 'execution-benchmark' || executionStatus === 'canceled'\n ? 'not-evaluated'\n : executionStatus === 'error'\n ? evaluationMode === 'scoring'\n ? 'unable-to-evaluate'\n : 'failed'\n : evaluationMode === 'scoring'\n ? scoringQualityFromObservations(observations)\n : isQualityStatus(value.qualityStatus) && isQualityStatusForMode(value.qualityStatus, evaluationMode)\n ? value.qualityStatus\n : legacyQualityFromObservations(observations, targetExecutionError);\n const normalized = structuredClone(value) as Record<string, unknown>;\n // Legacy runs stored a single status that conflated execution and quality.\n // Read it above, then remove it so normalized v2 values cannot contradict\n // their authoritative executionStatus/qualityStatus pair.\n delete normalized.status;\n return {\n ...(normalized as unknown as EvaluationTrial),\n executionStatus,\n qualityStatus,\n qualityReason: normalizeQualityReason(\n value.qualityReason,\n executionStatus === 'canceled'\n ? { code: 'canceled', message: 'The execution was canceled.' }\n : purpose === 'execution-benchmark'\n ? { code: 'benchmark', message: 'This run measured execution without evaluating output quality.' }\n : reasonForQualityStatusInMode(qualityStatus, evaluationMode, executionStatus),\n qualityStatus,\n purpose,\n executionStatus,\n ),\n };\n}\n\nexport function normalizeEvaluationAggregate(\n value: EvaluationAggregate | unknown,\n trials?: readonly EvaluationTrial[],\n): EvaluationAggregate {\n if (!isRecord(value)) throw new Error('Evaluation aggregate must be an object.');\n const normalized = structuredClone(value) as unknown as EvaluationAggregate;\n // Never let a graph-facing 0..100 value (or corrupt local data) masquerade\n // as the persisted normalized score and render as an impossible 9900/100.\n if (!isNormalizedScore(normalized.meanScore)) delete normalized.meanScore;\n if (!isNormalizedScore(normalized.medianScore)) delete normalized.medianScore;\n if (!isNormalizedScore(normalized.p95Score)) delete normalized.p95Score;\n if (\n typeof normalized.medianLatencyMs !== 'number' ||\n !Number.isFinite(normalized.medianLatencyMs) ||\n normalized.medianLatencyMs < 0\n ) {\n delete normalized.medianLatencyMs;\n }\n if (trials) {\n const completed = trials.filter((trial) => trial.executionStatus === 'completed');\n const evaluated = completed.filter((trial) => trial.qualityStatus === 'passed' || trial.qualityStatus === 'failed');\n const passed = evaluated.filter((trial) => trial.qualityStatus === 'passed');\n const failed = evaluated.filter((trial) => trial.qualityStatus === 'failed');\n const notEvaluated = completed.filter((trial) => trial.qualityStatus === 'not-evaluated');\n const unable = completed.filter((trial) => trial.qualityStatus === 'unable-to-evaluate');\n const scored = completed.filter((trial) => trial.qualityStatus === 'scored');\n return {\n ...normalized,\n trialCount: trials.length,\n evaluatedTrialCount: evaluated.length,\n notEvaluatedTrialCount: notEvaluated.length,\n unableToEvaluateTrialCount: unable.length,\n passedTrialCount: passed.length,\n failedTrialCount: failed.length,\n erroredTrialCount: trials.filter((trial) => trial.executionStatus === 'error').length,\n canceledTrialCount: trials.filter((trial) => trial.executionStatus === 'canceled').length,\n ...(scored.length > 0 || normalized.scoredTrialCount !== undefined\n ? { scoredTrialCount: scored.length, missingScoreTrialCount: trials.length - scored.length }\n : {}),\n passRate: evaluated.length === 0 ? 0 : passed.length / evaluated.length,\n };\n }\n const trialCount = Number(value.trialCount ?? 0);\n const passed = Number(value.passedTrialCount ?? 0);\n const failed = Number(value.failedTrialCount ?? 0);\n const errored = Number(value.erroredTrialCount ?? 0);\n const canceled = Number(value.canceledTrialCount ?? 0);\n const evaluated = Number(value.evaluatedTrialCount ?? passed + failed);\n const unable = Number(value.unableToEvaluateTrialCount ?? 0);\n const notEvaluated = Number(\n value.notEvaluatedTrialCount ?? Math.max(0, trialCount - evaluated - unable - errored - canceled),\n );\n return {\n ...normalized,\n evaluatedTrialCount: evaluated,\n notEvaluatedTrialCount: notEvaluated,\n unableToEvaluateTrialCount: unable,\n passRate: evaluated === 0 ? 0 : passed / evaluated,\n };\n}\n\nfunction withoutAuthoritativeCost(aggregate: EvaluationAggregate): EvaluationAggregate {\n const normalized = { ...aggregate };\n delete normalized.totalCostUsd;\n delete normalized.averageCostUsd;\n return normalized;\n}\n\nexport function normalizeEvaluationBaselineSnapshot(\n value: EvaluationBaselineSnapshot | unknown,\n): EvaluationBaselineSnapshot {\n if (!isRecord(value)) throw new Error('Evaluation baseline snapshot must be an object.');\n const accountingStatus = isAccountingStatus(value.accountingStatus)\n ? value.accountingStatus\n : isRecord(value.provenance) && value.provenance.accountingComplete === false\n ? 'partial'\n : 'complete';\n const aggregate = normalizeEvaluationAggregate(value.aggregate);\n const purpose = isPurpose(value.purpose) ? value.purpose : 'evaluation';\n const evaluationMode = isEvaluationMode(value.evaluationMode) ? value.evaluationMode : 'pass-fail';\n const hasCompleteScoringAggregate =\n aggregate.trialCount > 0 &&\n aggregate.scoredTrialCount === aggregate.trialCount &&\n aggregate.missingScoreTrialCount === 0 &&\n aggregate.meanScore !== undefined;\n const qualityStatus: EvaluationQualityStatus =\n purpose === 'execution-benchmark'\n ? 'not-evaluated'\n : evaluationMode === 'scoring'\n ? hasCompleteScoringAggregate\n ? 'scored'\n : 'unable-to-evaluate'\n : isQualityStatus(value.qualityStatus) && isQualityStatusForMode(value.qualityStatus, evaluationMode)\n ? value.qualityStatus\n : aggregate.failedTrialCount > 0 || aggregate.erroredTrialCount > 0\n ? 'failed'\n : aggregate.evaluatedTrialCount > 0\n ? 'passed'\n : 'not-evaluated';\n const qualityReasonFallback =\n purpose === 'execution-benchmark'\n ? { code: 'benchmark' as const, message: 'This run measured execution without evaluating output quality.' }\n : reasonForQualityStatusInMode(qualityStatus, evaluationMode);\n return {\n ...(structuredClone(value) as unknown as EvaluationBaselineSnapshot),\n purpose,\n evaluationMode,\n qualityStatus,\n qualityReason: normalizeQualityReason(value.qualityReason, qualityReasonFallback, qualityStatus, purpose),\n accountingStatus,\n aggregate: accountingStatus === 'partial' ? withoutAuthoritativeCost(aggregate) : aggregate,\n };\n}\n\nexport function normalizeEvaluationRun(value: EvaluationRun | unknown): EvaluationRun {\n if (!isRecord(value)) throw new Error('Evaluation run must be an object.');\n const purpose = isPurpose(value.purpose) ? value.purpose : 'evaluation';\n const evaluationMode = isEvaluationMode(value.evaluationMode) ? value.evaluationMode : 'pass-fail';\n const executionStatus = isRunExecutionStatus(value.executionStatus)\n ? value.executionStatus\n : typeof value.completedAt === 'string'\n ? 'completed'\n : 'running';\n const trials = Array.isArray(value.trials)\n ? value.trials.map((trial) => normalizeEvaluationTrial(trial, purpose, evaluationMode))\n : [];\n const accountingStatus = isAccountingStatus(value.accountingStatus)\n ? value.accountingStatus\n : isRecord(value.provenance) && value.provenance.accountingComplete === false\n ? 'partial'\n : 'complete';\n let qualityStatus: EvaluationQualityStatus;\n if (purpose === 'execution-benchmark' || executionStatus === 'canceled') {\n qualityStatus = 'not-evaluated';\n } else if (executionStatus === 'error') {\n qualityStatus = evaluationMode === 'scoring' ? 'unable-to-evaluate' : 'failed';\n } else if (executionStatus === 'queued' || executionStatus === 'running') {\n qualityStatus = 'not-evaluated';\n } else if (evaluationMode === 'scoring') {\n const scored = trials.filter((trial) => trial.qualityStatus === 'scored').length;\n qualityStatus = scored > 0 && scored === trials.length ? 'scored' : 'unable-to-evaluate';\n } else if (isQualityStatus(value.qualityStatus) && isQualityStatusForMode(value.qualityStatus, evaluationMode)) {\n qualityStatus = value.qualityStatus;\n } else if (trials.some((trial) => trial.executionStatus === 'error' || trial.qualityStatus === 'failed')) {\n qualityStatus = 'failed';\n } else if (trials.some((trial) => trial.qualityStatus === 'unable-to-evaluate')) {\n qualityStatus = 'unable-to-evaluate';\n } else if (trials.some((trial) => trial.qualityStatus === 'passed')) {\n qualityStatus = 'passed';\n } else if (value.verdict === 'fail') {\n // Old runs could fail an aggregate threshold without having a per-trial\n // quality observation. Preserve that authoritative failure. Only legacy\n // success-without-evidence is reinterpreted as Not evaluated.\n qualityStatus = 'failed';\n } else {\n // Legacy runs used `pass` for a graph that merely completed. If no stored\n // required check proves quality, reinterpret it as Not evaluated instead\n // of preserving the misleading pass label.\n qualityStatus = 'not-evaluated';\n }\n const qualityReasonFallback =\n executionStatus === 'canceled'\n ? { code: 'canceled' as const, message: 'The evaluation run was canceled.' }\n : executionStatus === 'queued' || executionStatus === 'running'\n ? { code: 'in-progress' as const, message: 'The run is still in progress.' }\n : purpose === 'execution-benchmark'\n ? { code: 'benchmark' as const, message: 'This run measured execution without evaluating output quality.' }\n : (executionStatus === 'error' || trials.some((trial) => trial.executionStatus === 'error')) &&\n qualityStatus === 'failed'\n ? { code: 'target-error' as const, message: 'One or more target graph executions failed.' }\n : reasonForQualityStatusInMode(qualityStatus, evaluationMode);\n const provenance = isRecord(value.provenance)\n ? {\n ...structuredClone(value.provenance),\n accountingComplete: accountingStatus === 'complete',\n }\n : value.provenance;\n const normalized = structuredClone(value) as Record<string, unknown>;\n // As with legacy trial.status, the old verdict is input-only compatibility\n // data. New v2 values expose one unambiguous qualityStatus instead.\n delete normalized.verdict;\n const name = typeof value.name === 'string' && value.name.trim().length > 0 ? value.name.trim() : undefined;\n delete normalized.name;\n const requestedTrialCount =\n typeof value.requestedTrialCount === 'number' &&\n Number.isSafeInteger(value.requestedTrialCount) &&\n value.requestedTrialCount >= 0\n ? value.requestedTrialCount\n : undefined;\n delete normalized.requestedTrialCount;\n const aggregate = value.aggregate === undefined ? undefined : normalizeEvaluationAggregate(value.aggregate, trials);\n return {\n ...(normalized as unknown as EvaluationRun),\n version: 2,\n purpose,\n evaluationMode,\n executionStatus,\n qualityStatus,\n qualityReason: normalizeQualityReason(\n value.qualityReason,\n qualityReasonFallback,\n qualityStatus,\n purpose,\n executionStatus,\n ),\n accountingStatus,\n provenance: provenance as EvaluationRun['provenance'],\n trials,\n thresholdResults: Array.isArray(value.thresholdResults)\n ? (structuredClone(value.thresholdResults) as EvaluationRun['thresholdResults'])\n : [],\n ...(name === undefined ? {} : { name }),\n ...(requestedTrialCount === undefined ? {} : { requestedTrialCount }),\n ...(aggregate === undefined\n ? {}\n : { aggregate: accountingStatus === 'partial' ? withoutAuthoritativeCost(aggregate) : aggregate }),\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["evaluated", "passed", "failed", "notEvaluated", "unable", "isRecord"]
|
|
7
|
+
}
|