@pfoundation/ocadvisor 26.9.1 → 26.9.2
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/README.md +388 -46
- package/dist/artificialAnalysis.d.ts +4 -0
- package/dist/artificialAnalysis.d.ts.map +1 -0
- package/dist/artificialAnalysis.js +77 -0
- package/dist/artificialAnalysis.js.map +1 -0
- package/dist/benchmarkConfig.d.ts +19 -0
- package/dist/benchmarkConfig.d.ts.map +1 -0
- package/dist/benchmarkConfig.js +58 -0
- package/dist/benchmarkConfig.js.map +1 -0
- package/dist/benchmarkEvidence.d.ts +37 -0
- package/dist/benchmarkEvidence.d.ts.map +1 -0
- package/dist/benchmarkEvidence.js +81 -0
- package/dist/benchmarkEvidence.js.map +1 -0
- package/dist/benchmarkMatch.d.ts +57 -0
- package/dist/benchmarkMatch.d.ts.map +1 -0
- package/dist/benchmarkMatch.js +236 -0
- package/dist/benchmarkMatch.js.map +1 -0
- package/dist/benchmarkStore.d.ts +44 -0
- package/dist/benchmarkStore.d.ts.map +1 -0
- package/dist/benchmarkStore.js +308 -0
- package/dist/benchmarkStore.js.map +1 -0
- package/dist/benchmarkTypes.d.ts +48 -0
- package/dist/benchmarkTypes.d.ts.map +1 -0
- package/dist/benchmarkTypes.js +298 -0
- package/dist/benchmarkTypes.js.map +1 -0
- package/dist/benchmarkUpdate.d.ts +33 -0
- package/dist/benchmarkUpdate.d.ts.map +1 -0
- package/dist/benchmarkUpdate.js +327 -0
- package/dist/benchmarkUpdate.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +377 -0
- package/dist/cli.js.map +1 -0
- package/dist/data/artificialAnalysis.mappings.json +197 -0
- package/dist/data/artificialAnalysis.snapshot.json +17684 -0
- package/dist/modelProfiles.d.ts +45 -0
- package/dist/modelProfiles.d.ts.map +1 -0
- package/dist/modelProfiles.js +141 -0
- package/dist/modelProfiles.js.map +1 -0
- package/dist/ocAdvisor.d.ts +105 -5
- package/dist/ocAdvisor.d.ts.map +1 -1
- package/dist/ocAdvisor.js +502 -44
- package/dist/ocAdvisor.js.map +1 -1
- package/dist/typesafeGate.d.ts +89 -0
- package/dist/typesafeGate.d.ts.map +1 -0
- package/dist/typesafeGate.js +463 -0
- package/dist/typesafeGate.js.map +1 -0
- package/dist/typesafeState.d.ts +94 -0
- package/dist/typesafeState.d.ts.map +1 -0
- package/dist/typesafeState.js +301 -0
- package/dist/typesafeState.js.map +1 -0
- package/package.json +8 -2
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
// Local benchmark reader with hot reload: one store per plugin setup
|
|
2
|
+
// watches the user snapshot and mappings files, serves a consistent
|
|
3
|
+
// immutable view per consultation, and falls back through last-good data
|
|
4
|
+
// to the bundled seed. Reload detection keys on file identity
|
|
5
|
+
// (device/inode/size/mtime), so atomic replacements are observed even
|
|
6
|
+
// when size and mtime are unchanged. The read path performs no network
|
|
7
|
+
// I/O and never throws for missing or invalid data.
|
|
8
|
+
import { open, stat as nodeStat } from "node:fs/promises";
|
|
9
|
+
import { dirname, join } from "node:path";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
import { createBenchmarkMatcher, parseModelMappings, } from "./benchmarkMatch.js";
|
|
12
|
+
import { parseBenchmarkSnapshot, verifySnapshotHash, } from "./benchmarkTypes.js";
|
|
13
|
+
export const BENCHMARK_READ_MAX_BYTES = 16 * 1024 * 1024;
|
|
14
|
+
export const BENCHMARK_FILE_TOO_LARGE = "BENCHMARK_FILE_TOO_LARGE";
|
|
15
|
+
const READ_ATTEMPTS = 3;
|
|
16
|
+
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
export const DEFAULT_SEED_SNAPSHOT_PATH = join(MODULE_DIR, "data", "artificialAnalysis.snapshot.json");
|
|
18
|
+
export const DEFAULT_SEED_MAPPINGS_PATH = join(MODULE_DIR, "data", "artificialAnalysis.mappings.json");
|
|
19
|
+
function defaultFileSystem(maxBytes) {
|
|
20
|
+
return {
|
|
21
|
+
async stat(path) {
|
|
22
|
+
try {
|
|
23
|
+
const stats = await nodeStat(path);
|
|
24
|
+
return {
|
|
25
|
+
dev: stats.dev,
|
|
26
|
+
ino: stats.ino,
|
|
27
|
+
size: stats.size,
|
|
28
|
+
mtimeMs: stats.mtimeMs,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (error?.code === "ENOENT")
|
|
33
|
+
return null;
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
async read(path) {
|
|
38
|
+
const handle = await open(path, "r");
|
|
39
|
+
try {
|
|
40
|
+
const buffer = Buffer.alloc(maxBytes + 1);
|
|
41
|
+
const { bytesRead } = await handle.read(buffer, 0, maxBytes + 1, 0);
|
|
42
|
+
if (bytesRead > maxBytes) {
|
|
43
|
+
const error = new Error(`benchmark file exceeds ${maxBytes} bytes`);
|
|
44
|
+
error.code = BENCHMARK_FILE_TOO_LARGE;
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
return buffer.subarray(0, bytesRead).toString("utf8");
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
await handle.close();
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function sameIdentity(a, b) {
|
|
56
|
+
return (a.dev === b.dev &&
|
|
57
|
+
a.ino === b.ino &&
|
|
58
|
+
a.size === b.size &&
|
|
59
|
+
a.mtimeMs === b.mtimeMs);
|
|
60
|
+
}
|
|
61
|
+
function signature(identity) {
|
|
62
|
+
return `${identity.dev}:${identity.ino}:${identity.size}:${identity.mtimeMs}`;
|
|
63
|
+
}
|
|
64
|
+
function errorCode(error) {
|
|
65
|
+
const code = error?.code;
|
|
66
|
+
return typeof code === "string" && code ? code : null;
|
|
67
|
+
}
|
|
68
|
+
// Reads a file only when two surrounding stats agree, so the bytes are
|
|
69
|
+
// never cached under the wrong file identity. Atomic renames always yield
|
|
70
|
+
// complete files; the loop only resolves which version was read.
|
|
71
|
+
async function readStableFile(fs, path, maxBytes) {
|
|
72
|
+
for (let attempt = 0; attempt < READ_ATTEMPTS; attempt++) {
|
|
73
|
+
let before;
|
|
74
|
+
try {
|
|
75
|
+
before = await fs.stat(path);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
return {
|
|
79
|
+
kind: "unreadable",
|
|
80
|
+
reason: errorCode(error) ?? "unknown error",
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (before === null)
|
|
84
|
+
return { kind: "missing" };
|
|
85
|
+
if (before.size > maxBytes)
|
|
86
|
+
return { kind: "too_large" };
|
|
87
|
+
let text;
|
|
88
|
+
try {
|
|
89
|
+
text = await fs.read(path);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
const code = errorCode(error);
|
|
93
|
+
if (code === "ENOENT")
|
|
94
|
+
continue;
|
|
95
|
+
if (code === BENCHMARK_FILE_TOO_LARGE)
|
|
96
|
+
return { kind: "too_large" };
|
|
97
|
+
return { kind: "unreadable", reason: code ?? "unknown error" };
|
|
98
|
+
}
|
|
99
|
+
let after;
|
|
100
|
+
try {
|
|
101
|
+
after = await fs.stat(path);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
return {
|
|
105
|
+
kind: "unreadable",
|
|
106
|
+
reason: errorCode(error) ?? "unknown error",
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (after !== null && sameIdentity(before, after)) {
|
|
110
|
+
return { kind: "ok", identity: before, text };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return { kind: "unstable" };
|
|
114
|
+
}
|
|
115
|
+
function isValidationError(value) {
|
|
116
|
+
return typeof value === "object" && value !== null && "error" in value;
|
|
117
|
+
}
|
|
118
|
+
function freshTrackedFile() {
|
|
119
|
+
return { cached: null, rejected: null };
|
|
120
|
+
}
|
|
121
|
+
// Refreshes one watched user file. Unchanged and already-rejected
|
|
122
|
+
// identities skip parsing; anything unusable retains the last good value
|
|
123
|
+
// (or falls through to the seed leg) with an explicit diagnostic.
|
|
124
|
+
async function refreshUserFile(args) {
|
|
125
|
+
const { fs, path, label, maxBytes, state, parse } = args;
|
|
126
|
+
const read = await readStableFile(fs, path, maxBytes);
|
|
127
|
+
if (read.kind === "missing") {
|
|
128
|
+
if (state.cached) {
|
|
129
|
+
return {
|
|
130
|
+
value: state.cached.value,
|
|
131
|
+
note: `${label} file was removed; retained last loaded data`,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return { value: null, note: null };
|
|
135
|
+
}
|
|
136
|
+
if (read.kind === "unstable") {
|
|
137
|
+
const note = `${label} file changed during read and never settled`;
|
|
138
|
+
if (state.cached)
|
|
139
|
+
return { value: state.cached.value, note };
|
|
140
|
+
return { value: null, note };
|
|
141
|
+
}
|
|
142
|
+
if (read.kind === "unreadable") {
|
|
143
|
+
const note = `${label} file is unreadable (${read.reason})`;
|
|
144
|
+
if (state.cached)
|
|
145
|
+
return { value: state.cached.value, note };
|
|
146
|
+
return { value: null, note };
|
|
147
|
+
}
|
|
148
|
+
if (read.kind === "too_large") {
|
|
149
|
+
const note = `${label} file exceeds the ${maxBytes} byte limit`;
|
|
150
|
+
if (state.cached)
|
|
151
|
+
return { value: state.cached.value, note };
|
|
152
|
+
return { value: null, note };
|
|
153
|
+
}
|
|
154
|
+
const sig = signature(read.identity);
|
|
155
|
+
if (state.cached && state.cached.signature === sig) {
|
|
156
|
+
return { value: state.cached.value, note: null };
|
|
157
|
+
}
|
|
158
|
+
if (state.rejected && state.rejected.signature === sig) {
|
|
159
|
+
if (state.cached) {
|
|
160
|
+
return { value: state.cached.value, note: state.rejected.reason };
|
|
161
|
+
}
|
|
162
|
+
return { value: null, note: state.rejected.reason };
|
|
163
|
+
}
|
|
164
|
+
let parsed;
|
|
165
|
+
try {
|
|
166
|
+
parsed = JSON.parse(read.text);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
const reason = `${label} file is not valid JSON`;
|
|
170
|
+
state.rejected = { signature: sig, reason };
|
|
171
|
+
if (state.cached)
|
|
172
|
+
return { value: state.cached.value, note: reason };
|
|
173
|
+
return { value: null, note: reason };
|
|
174
|
+
}
|
|
175
|
+
const validated = parse(parsed);
|
|
176
|
+
if (isValidationError(validated)) {
|
|
177
|
+
const reason = `${label} file rejected: ${validated.error}`;
|
|
178
|
+
state.rejected = { signature: sig, reason };
|
|
179
|
+
if (state.cached)
|
|
180
|
+
return { value: state.cached.value, note: reason };
|
|
181
|
+
return { value: null, note: reason };
|
|
182
|
+
}
|
|
183
|
+
state.cached = { signature: sig, value: validated };
|
|
184
|
+
state.rejected = null;
|
|
185
|
+
return { value: validated, note: null };
|
|
186
|
+
}
|
|
187
|
+
async function loadSeedSnapshot(fs, path, maxBytes) {
|
|
188
|
+
const read = await readStableFile(fs, path, maxBytes);
|
|
189
|
+
// A missing seed is quiet: presence is a packaging assertion, and the
|
|
190
|
+
// store must work identically with user data or unavailable data.
|
|
191
|
+
if (read.kind === "missing" || read.kind === "unstable") {
|
|
192
|
+
return { value: null, note: null };
|
|
193
|
+
}
|
|
194
|
+
if (read.kind === "too_large") {
|
|
195
|
+
return {
|
|
196
|
+
value: null,
|
|
197
|
+
note: `seed snapshot exceeds the ${maxBytes} byte limit`,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
if (read.kind === "unreadable") {
|
|
201
|
+
return {
|
|
202
|
+
value: null,
|
|
203
|
+
note: `seed snapshot is unreadable (${read.reason})`,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
let parsed;
|
|
207
|
+
try {
|
|
208
|
+
parsed = JSON.parse(read.text);
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return { value: null, note: "seed snapshot is not valid JSON" };
|
|
212
|
+
}
|
|
213
|
+
const validated = parseBenchmarkSnapshot(parsed);
|
|
214
|
+
if (isValidationError(validated)) {
|
|
215
|
+
return { value: null, note: `seed snapshot rejected: ${validated.error}` };
|
|
216
|
+
}
|
|
217
|
+
if (!verifySnapshotHash(validated)) {
|
|
218
|
+
return { value: validated, note: "seed snapshot hash mismatch" };
|
|
219
|
+
}
|
|
220
|
+
return { value: validated, note: null };
|
|
221
|
+
}
|
|
222
|
+
async function loadSeedMappings(fs, path, maxBytes) {
|
|
223
|
+
const empty = { schemaVersion: 1, bindings: [] };
|
|
224
|
+
const read = await readStableFile(fs, path, maxBytes);
|
|
225
|
+
if (read.kind === "missing" || read.kind === "unstable") {
|
|
226
|
+
return { value: empty, note: null };
|
|
227
|
+
}
|
|
228
|
+
if (read.kind === "too_large") {
|
|
229
|
+
return {
|
|
230
|
+
value: empty,
|
|
231
|
+
note: `seed mappings exceed the ${maxBytes} byte limit`,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
if (read.kind === "unreadable") {
|
|
235
|
+
return {
|
|
236
|
+
value: empty,
|
|
237
|
+
note: `seed mappings are unreadable (${read.reason})`,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
let parsed;
|
|
241
|
+
try {
|
|
242
|
+
parsed = JSON.parse(read.text);
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
return { value: empty, note: "seed mappings are not valid JSON" };
|
|
246
|
+
}
|
|
247
|
+
const validated = parseModelMappings(parsed);
|
|
248
|
+
if (isValidationError(validated)) {
|
|
249
|
+
return { value: empty, note: `seed mappings rejected: ${validated.error}` };
|
|
250
|
+
}
|
|
251
|
+
return { value: validated, note: null };
|
|
252
|
+
}
|
|
253
|
+
export async function createBenchmarkStore(options) {
|
|
254
|
+
const maxBytes = options.maxBytes ?? BENCHMARK_READ_MAX_BYTES;
|
|
255
|
+
const fs = options.fs ?? defaultFileSystem(maxBytes);
|
|
256
|
+
const seedSnapshotPath = options.seedSnapshotPath ?? DEFAULT_SEED_SNAPSHOT_PATH;
|
|
257
|
+
const seedMappingsPath = options.seedMappingsPath ?? DEFAULT_SEED_MAPPINGS_PATH;
|
|
258
|
+
const seedSnapshot = await loadSeedSnapshot(fs, seedSnapshotPath, maxBytes);
|
|
259
|
+
const seedMappings = await loadSeedMappings(fs, seedMappingsPath, maxBytes);
|
|
260
|
+
const snapshotState = freshTrackedFile();
|
|
261
|
+
const mappingsState = freshTrackedFile();
|
|
262
|
+
return {
|
|
263
|
+
snapshotPath: options.snapshotPath,
|
|
264
|
+
mappingsPath: options.mappingsPath,
|
|
265
|
+
async view() {
|
|
266
|
+
const snapshotLeg = await refreshUserFile({
|
|
267
|
+
fs,
|
|
268
|
+
path: options.snapshotPath,
|
|
269
|
+
label: "benchmark snapshot",
|
|
270
|
+
maxBytes,
|
|
271
|
+
state: snapshotState,
|
|
272
|
+
parse: parseBenchmarkSnapshot,
|
|
273
|
+
});
|
|
274
|
+
const mappingsLeg = await refreshUserFile({
|
|
275
|
+
fs,
|
|
276
|
+
path: options.mappingsPath,
|
|
277
|
+
label: "model mappings",
|
|
278
|
+
maxBytes,
|
|
279
|
+
state: mappingsState,
|
|
280
|
+
parse: parseModelMappings,
|
|
281
|
+
});
|
|
282
|
+
const snapshot = snapshotLeg.value ?? seedSnapshot.value;
|
|
283
|
+
const snapshotSource = snapshotLeg.value
|
|
284
|
+
? "user"
|
|
285
|
+
: seedSnapshot.value
|
|
286
|
+
? "seed"
|
|
287
|
+
: "unavailable";
|
|
288
|
+
const snapshotNote = snapshotLeg.note ?? (snapshot ? null : seedSnapshot.note);
|
|
289
|
+
return {
|
|
290
|
+
snapshot,
|
|
291
|
+
snapshotSource,
|
|
292
|
+
snapshotPath: snapshotLeg.value ? options.snapshotPath : null,
|
|
293
|
+
snapshotNote,
|
|
294
|
+
snapshotHashVerified: snapshot ? verifySnapshotHash(snapshot) : false,
|
|
295
|
+
localMappings: mappingsLeg.value,
|
|
296
|
+
localMappingsNote: mappingsLeg.note,
|
|
297
|
+
bundledMappings: seedMappings.value,
|
|
298
|
+
bundledMappingsNote: seedMappings.note,
|
|
299
|
+
matcher: createBenchmarkMatcher({
|
|
300
|
+
snapshot,
|
|
301
|
+
bundled: seedMappings.value,
|
|
302
|
+
local: mappingsLeg.value,
|
|
303
|
+
}),
|
|
304
|
+
};
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=benchmarkStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmarkStore.js","sourceRoot":"","sources":["../src/benchmarkStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export declare const BENCHMARK_SCHEMA_VERSION = 1;
|
|
2
|
+
export declare const BENCHMARK_SOURCE = "artificial-analysis";
|
|
3
|
+
export declare const BENCHMARK_SOURCE_URL = "https://artificialanalysis.ai/";
|
|
4
|
+
export type MetricCategory = "coding" | "general" | "reasoning" | "math";
|
|
5
|
+
export type MetricUnit = "index_points" | "fraction";
|
|
6
|
+
export interface MetricDefinition {
|
|
7
|
+
key: string;
|
|
8
|
+
label: string;
|
|
9
|
+
category: MetricCategory;
|
|
10
|
+
unit: MetricUnit;
|
|
11
|
+
higherIsBetter: boolean;
|
|
12
|
+
benchmarkVersion: string | null;
|
|
13
|
+
}
|
|
14
|
+
export interface BenchmarkModel {
|
|
15
|
+
id: string;
|
|
16
|
+
creatorID: string;
|
|
17
|
+
name: string;
|
|
18
|
+
slug: string;
|
|
19
|
+
evaluatedEffort: string | null;
|
|
20
|
+
evaluatedAt: string | null;
|
|
21
|
+
evaluations: Record<string, number | null>;
|
|
22
|
+
}
|
|
23
|
+
export interface BenchmarkSnapshot {
|
|
24
|
+
schemaVersion: 1;
|
|
25
|
+
source: "artificial-analysis";
|
|
26
|
+
sourceURL: string;
|
|
27
|
+
endpoint: string;
|
|
28
|
+
fetchedAt: string;
|
|
29
|
+
contentHash: string;
|
|
30
|
+
methodologyVersion: string | null;
|
|
31
|
+
metricDefinitions: MetricDefinition[];
|
|
32
|
+
models: BenchmarkModel[];
|
|
33
|
+
}
|
|
34
|
+
export declare const RECOGNIZED_METRICS: readonly MetricDefinition[];
|
|
35
|
+
export declare const GATE_METRIC_ORDER: readonly string[];
|
|
36
|
+
export type BenchmarkValidationError = {
|
|
37
|
+
error: string;
|
|
38
|
+
};
|
|
39
|
+
export declare function parseBenchmarkModel(value: unknown, label: string): BenchmarkModel | BenchmarkValidationError;
|
|
40
|
+
export declare function parseBenchmarkSnapshot(value: unknown): BenchmarkSnapshot | BenchmarkValidationError;
|
|
41
|
+
export declare function computeSnapshotHash(input: {
|
|
42
|
+
source: string;
|
|
43
|
+
endpoint: string;
|
|
44
|
+
methodologyVersion: string | null;
|
|
45
|
+
models: BenchmarkModel[];
|
|
46
|
+
}): string;
|
|
47
|
+
export declare function verifySnapshotHash(snapshot: BenchmarkSnapshot): boolean;
|
|
48
|
+
//# sourceMappingURL=benchmarkTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmarkTypes.d.ts","sourceRoot":"","sources":["../src/benchmarkTypes.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,gBAAgB,wBAAwB,CAAC;AACtD,eAAO,MAAM,oBAAoB,mCAAmC,CAAC;AAErE,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;AACzE,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,UAAU,CAAC;AAErD,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,CAAC,CAAC;IACjB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IAEjB,SAAS,EAAE,MAAM,CAAC;IAGlB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B;AAMD,eAAO,MAAM,kBAAkB,EAAE,SAAS,gBAAgB,EAyCzD,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAE9C,CAAC;AAYF,MAAM,MAAM,wBAAwB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AA+DzD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACZ,cAAc,GAAG,wBAAwB,CAwC3C;AA8DD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,iBAAiB,GAAG,wBAAwB,CAmE9C;AAkBD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B,GAAG,MAAM,CAYT;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CASvE"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
// Versioned Artificial Analysis benchmark snapshot: shared schema,
|
|
2
|
+
// validation, and content hashing for the updater, reader, CLI, and gate.
|
|
3
|
+
//
|
|
4
|
+
// One validation path serves downloads, the bundled seed, user snapshots,
|
|
5
|
+
// and mapping-adjacent reads so every consumer agrees on what is usable.
|
|
6
|
+
// Unknown additive fields are ignored or preserved (never invented), and
|
|
7
|
+
// undocumented metadata stays null instead of guessed.
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
export const BENCHMARK_SCHEMA_VERSION = 1;
|
|
10
|
+
export const BENCHMARK_SOURCE = "artificial-analysis";
|
|
11
|
+
export const BENCHMARK_SOURCE_URL = "https://artificialanalysis.ai/";
|
|
12
|
+
// Recognized metrics in deterministic gate-selection order: the two
|
|
13
|
+
// Artificial Analysis indexes first, then reasoning/math evidence. Scores
|
|
14
|
+
// keep their published labels and units; index points and fractions are
|
|
15
|
+
// never mixed into one aggregate.
|
|
16
|
+
export const RECOGNIZED_METRICS = [
|
|
17
|
+
{
|
|
18
|
+
key: "artificial_analysis_coding_index",
|
|
19
|
+
label: "Artificial Analysis Coding Index",
|
|
20
|
+
category: "coding",
|
|
21
|
+
unit: "index_points",
|
|
22
|
+
higherIsBetter: true,
|
|
23
|
+
benchmarkVersion: null,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
key: "artificial_analysis_intelligence_index",
|
|
27
|
+
label: "Artificial Analysis Intelligence Index",
|
|
28
|
+
category: "general",
|
|
29
|
+
unit: "index_points",
|
|
30
|
+
higherIsBetter: true,
|
|
31
|
+
benchmarkVersion: null,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: "hle",
|
|
35
|
+
label: "HLE (Humanity's Last Exam)",
|
|
36
|
+
category: "reasoning",
|
|
37
|
+
unit: "fraction",
|
|
38
|
+
higherIsBetter: true,
|
|
39
|
+
benchmarkVersion: null,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
key: "gpqa",
|
|
43
|
+
label: "GPQA",
|
|
44
|
+
category: "reasoning",
|
|
45
|
+
unit: "fraction",
|
|
46
|
+
higherIsBetter: true,
|
|
47
|
+
benchmarkVersion: null,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
key: "artificial_analysis_math_index",
|
|
51
|
+
label: "Artificial Analysis Math Index",
|
|
52
|
+
category: "math",
|
|
53
|
+
unit: "index_points",
|
|
54
|
+
higherIsBetter: true,
|
|
55
|
+
benchmarkVersion: null,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
export const GATE_METRIC_ORDER = RECOGNIZED_METRICS.map((metric) => metric.key);
|
|
59
|
+
const RECOGNIZED_KEYS = new Set(GATE_METRIC_ORDER);
|
|
60
|
+
const HASH_FORMAT = /^[0-9a-f]{64}$/;
|
|
61
|
+
const CATEGORIES = [
|
|
62
|
+
"coding",
|
|
63
|
+
"general",
|
|
64
|
+
"reasoning",
|
|
65
|
+
"math",
|
|
66
|
+
];
|
|
67
|
+
const UNITS = ["index_points", "fraction"];
|
|
68
|
+
function isRecord(value) {
|
|
69
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
70
|
+
}
|
|
71
|
+
function isValidDateTime(value) {
|
|
72
|
+
return Number.isFinite(Date.parse(value));
|
|
73
|
+
}
|
|
74
|
+
function isValidationError(value) {
|
|
75
|
+
return typeof value === "object" && value !== null;
|
|
76
|
+
}
|
|
77
|
+
// `in` narrowing cannot discriminate an index-signature Record from the
|
|
78
|
+
// error shape, so evaluations results use this predicate instead.
|
|
79
|
+
function isParseError(value) {
|
|
80
|
+
return typeof value === "object" && value !== null && "error" in value;
|
|
81
|
+
}
|
|
82
|
+
function parseNullableString(value, field) {
|
|
83
|
+
if (value === null || value === undefined)
|
|
84
|
+
return null;
|
|
85
|
+
if (typeof value !== "string")
|
|
86
|
+
return { error: `${field} must be a string or null` };
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
// Recognized scores must be finite numbers or explicit nulls (zero is a
|
|
90
|
+
// real score). Unknown keys keep finite numbers and nulls for forward
|
|
91
|
+
// compatibility; anything else is ignored rather than rejected so additive
|
|
92
|
+
// upstream changes cannot break previously valid snapshots.
|
|
93
|
+
function parseEvaluations(value, label) {
|
|
94
|
+
if (value === null || value === undefined)
|
|
95
|
+
return {};
|
|
96
|
+
if (!isRecord(value)) {
|
|
97
|
+
return { error: `${label} evaluations must be an object` };
|
|
98
|
+
}
|
|
99
|
+
const evaluations = {};
|
|
100
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
101
|
+
if (entry === null) {
|
|
102
|
+
evaluations[key] = null;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (typeof entry !== "number" || !Number.isFinite(entry)) {
|
|
106
|
+
if (RECOGNIZED_KEYS.has(key)) {
|
|
107
|
+
return { error: `${label} has an invalid ${key} score` };
|
|
108
|
+
}
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
evaluations[key] = entry;
|
|
112
|
+
}
|
|
113
|
+
return evaluations;
|
|
114
|
+
}
|
|
115
|
+
export function parseBenchmarkModel(value, label) {
|
|
116
|
+
if (!isRecord(value)) {
|
|
117
|
+
return { error: `${label} must be an object` };
|
|
118
|
+
}
|
|
119
|
+
const id = typeof value.id === "string" ? value.id.trim() : "";
|
|
120
|
+
if (!id)
|
|
121
|
+
return { error: `${label} is missing a stable model id` };
|
|
122
|
+
const creatorID = typeof value.creatorID === "string" ? value.creatorID.trim() : "";
|
|
123
|
+
if (!creatorID)
|
|
124
|
+
return { error: `${label} is missing a creator id` };
|
|
125
|
+
if (typeof value.name !== "string" || typeof value.slug !== "string") {
|
|
126
|
+
return { error: `${label} is missing its name or slug` };
|
|
127
|
+
}
|
|
128
|
+
const evaluatedEffort = parseNullableString(value.evaluatedEffort, `${label} evaluatedEffort`);
|
|
129
|
+
if (isValidationError(evaluatedEffort))
|
|
130
|
+
return evaluatedEffort;
|
|
131
|
+
const evaluatedAt = parseNullableString(value.evaluatedAt, `${label} evaluatedAt`);
|
|
132
|
+
if (isValidationError(evaluatedAt))
|
|
133
|
+
return evaluatedAt;
|
|
134
|
+
if (typeof evaluatedAt === "string" &&
|
|
135
|
+
evaluatedAt.trim() &&
|
|
136
|
+
!isValidDateTime(evaluatedAt)) {
|
|
137
|
+
return { error: `${label} has an invalid evaluatedAt date` };
|
|
138
|
+
}
|
|
139
|
+
const evaluations = parseEvaluations(value.evaluations, label);
|
|
140
|
+
if (isParseError(evaluations))
|
|
141
|
+
return evaluations;
|
|
142
|
+
return {
|
|
143
|
+
id,
|
|
144
|
+
creatorID,
|
|
145
|
+
name: value.name,
|
|
146
|
+
slug: value.slug,
|
|
147
|
+
evaluatedEffort: evaluatedEffort,
|
|
148
|
+
evaluatedAt: evaluatedAt,
|
|
149
|
+
evaluations,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function parseMetricDefinitions(value) {
|
|
153
|
+
if (!Array.isArray(value)) {
|
|
154
|
+
return { error: "metricDefinitions must be an array" };
|
|
155
|
+
}
|
|
156
|
+
const seen = new Set();
|
|
157
|
+
const definitions = [];
|
|
158
|
+
for (let index = 0; index < value.length; index++) {
|
|
159
|
+
const entry = value[index];
|
|
160
|
+
const label = `metric definition ${index}`;
|
|
161
|
+
if (!isRecord(entry))
|
|
162
|
+
return { error: `${label} must be an object` };
|
|
163
|
+
const key = typeof entry.key === "string" ? entry.key.trim() : "";
|
|
164
|
+
if (!key)
|
|
165
|
+
return { error: `${label} is missing its key` };
|
|
166
|
+
if (seen.has(key)) {
|
|
167
|
+
return { error: `duplicate metric definition for ${key}` };
|
|
168
|
+
}
|
|
169
|
+
seen.add(key);
|
|
170
|
+
if (typeof entry.label !== "string") {
|
|
171
|
+
return { error: `${label} is missing its label` };
|
|
172
|
+
}
|
|
173
|
+
if (typeof entry.category !== "string" ||
|
|
174
|
+
!CATEGORIES.includes(entry.category)) {
|
|
175
|
+
return { error: `${label} has an unknown category` };
|
|
176
|
+
}
|
|
177
|
+
if (typeof entry.unit !== "string" || !UNITS.includes(entry.unit)) {
|
|
178
|
+
return { error: `${label} has an unknown unit` };
|
|
179
|
+
}
|
|
180
|
+
if (typeof entry.higherIsBetter !== "boolean") {
|
|
181
|
+
return { error: `${label} is missing higherIsBetter` };
|
|
182
|
+
}
|
|
183
|
+
const benchmarkVersion = parseNullableString(entry.benchmarkVersion, `${label} benchmarkVersion`);
|
|
184
|
+
if (isValidationError(benchmarkVersion))
|
|
185
|
+
return benchmarkVersion;
|
|
186
|
+
definitions.push({
|
|
187
|
+
key,
|
|
188
|
+
label: entry.label,
|
|
189
|
+
category: entry.category,
|
|
190
|
+
unit: entry.unit,
|
|
191
|
+
higherIsBetter: entry.higherIsBetter,
|
|
192
|
+
benchmarkVersion: benchmarkVersion,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
return definitions;
|
|
196
|
+
}
|
|
197
|
+
function hasUsableScore(models) {
|
|
198
|
+
return models.some((model) => GATE_METRIC_ORDER.some((key) => typeof model.evaluations[key] === "number" &&
|
|
199
|
+
Number.isFinite(model.evaluations[key])));
|
|
200
|
+
}
|
|
201
|
+
export function parseBenchmarkSnapshot(value) {
|
|
202
|
+
if (!isRecord(value)) {
|
|
203
|
+
return { error: "benchmark snapshot must be an object" };
|
|
204
|
+
}
|
|
205
|
+
if (value.schemaVersion !== BENCHMARK_SCHEMA_VERSION) {
|
|
206
|
+
return {
|
|
207
|
+
error: `unsupported benchmark snapshot schema version ${String(value.schemaVersion)} (expected ${BENCHMARK_SCHEMA_VERSION})`,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
if (value.source !== BENCHMARK_SOURCE) {
|
|
211
|
+
return {
|
|
212
|
+
error: `benchmark snapshot source must be ${BENCHMARK_SOURCE}`,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
if (typeof value.sourceURL !== "string" || !value.sourceURL.trim()) {
|
|
216
|
+
return { error: "benchmark snapshot is missing its sourceURL" };
|
|
217
|
+
}
|
|
218
|
+
if (typeof value.endpoint !== "string" || !value.endpoint.trim()) {
|
|
219
|
+
return { error: "benchmark snapshot is missing its endpoint" };
|
|
220
|
+
}
|
|
221
|
+
if (typeof value.fetchedAt !== "string" ||
|
|
222
|
+
!isValidDateTime(value.fetchedAt)) {
|
|
223
|
+
return { error: "benchmark snapshot has an invalid fetchedAt timestamp" };
|
|
224
|
+
}
|
|
225
|
+
if (typeof value.contentHash !== "string" ||
|
|
226
|
+
!HASH_FORMAT.test(value.contentHash)) {
|
|
227
|
+
return { error: "benchmark snapshot has an invalid contentHash" };
|
|
228
|
+
}
|
|
229
|
+
const methodologyVersion = parseNullableString(value.methodologyVersion, "methodologyVersion");
|
|
230
|
+
if (isValidationError(methodologyVersion))
|
|
231
|
+
return methodologyVersion;
|
|
232
|
+
const metricDefinitions = parseMetricDefinitions(value.metricDefinitions);
|
|
233
|
+
if ("error" in metricDefinitions)
|
|
234
|
+
return metricDefinitions;
|
|
235
|
+
if (!Array.isArray(value.models) || value.models.length === 0) {
|
|
236
|
+
return { error: "benchmark snapshot has an empty model dataset" };
|
|
237
|
+
}
|
|
238
|
+
const seen = new Set();
|
|
239
|
+
const models = [];
|
|
240
|
+
for (let index = 0; index < value.models.length; index++) {
|
|
241
|
+
const parsed = parseBenchmarkModel(value.models[index], `model ${index}`);
|
|
242
|
+
if ("error" in parsed)
|
|
243
|
+
return parsed;
|
|
244
|
+
if (seen.has(parsed.id)) {
|
|
245
|
+
return { error: `duplicate benchmark model id ${parsed.id}` };
|
|
246
|
+
}
|
|
247
|
+
seen.add(parsed.id);
|
|
248
|
+
models.push(parsed);
|
|
249
|
+
}
|
|
250
|
+
if (!hasUsableScore(models)) {
|
|
251
|
+
return { error: "benchmark snapshot has no usable benchmark scores" };
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
schemaVersion: BENCHMARK_SCHEMA_VERSION,
|
|
255
|
+
source: BENCHMARK_SOURCE,
|
|
256
|
+
sourceURL: value.sourceURL,
|
|
257
|
+
endpoint: value.endpoint,
|
|
258
|
+
fetchedAt: value.fetchedAt,
|
|
259
|
+
contentHash: value.contentHash,
|
|
260
|
+
methodologyVersion: methodologyVersion,
|
|
261
|
+
metricDefinitions,
|
|
262
|
+
models,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// Canonical JSON: object keys sorted recursively, arrays in order. Used only
|
|
266
|
+
// for hashing, never for display.
|
|
267
|
+
function stableStringify(value) {
|
|
268
|
+
if (Array.isArray(value)) {
|
|
269
|
+
return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
|
|
270
|
+
}
|
|
271
|
+
if (isRecord(value)) {
|
|
272
|
+
const body = Object.keys(value)
|
|
273
|
+
.sort()
|
|
274
|
+
.map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`)
|
|
275
|
+
.join(",");
|
|
276
|
+
return `{${body}}`;
|
|
277
|
+
}
|
|
278
|
+
return JSON.stringify(value) ?? "null";
|
|
279
|
+
}
|
|
280
|
+
export function computeSnapshotHash(input) {
|
|
281
|
+
return createHash("sha256")
|
|
282
|
+
.update(stableStringify({
|
|
283
|
+
source: input.source,
|
|
284
|
+
endpoint: input.endpoint,
|
|
285
|
+
methodologyVersion: input.methodologyVersion,
|
|
286
|
+
models: input.models,
|
|
287
|
+
}), "utf8")
|
|
288
|
+
.digest("hex");
|
|
289
|
+
}
|
|
290
|
+
export function verifySnapshotHash(snapshot) {
|
|
291
|
+
return (computeSnapshotHash({
|
|
292
|
+
source: snapshot.source,
|
|
293
|
+
endpoint: snapshot.endpoint,
|
|
294
|
+
methodologyVersion: snapshot.methodologyVersion,
|
|
295
|
+
models: snapshot.models,
|
|
296
|
+
}) === snapshot.contentHash);
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=benchmarkTypes.js.map
|