forked from apache/maka
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexperiment.ts
More file actions
101 lines (95 loc) · 3.52 KB
/
Copy pathexperiment.ts
File metadata and controls
101 lines (95 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export type JsonPrimitive = string | number | boolean | null;
export type JsonValue =
| JsonPrimitive
| readonly JsonValue[]
| { readonly [key: string]: JsonValue };
export type JsonObject = { readonly [key: string]: JsonValue };
export function decodeJsonObject(value: unknown, where: string): JsonObject {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
throw new Error(`${where} must be an object`);
}
return Object.fromEntries(
Object.entries(value).map(([key, child]) => [key, decodeJsonValue(child, `${where}.${key}`)]),
);
}
function decodeJsonValue(value: unknown, where: string): JsonValue {
if (value === null || typeof value === 'string' || typeof value === 'boolean') return value;
if (typeof value === 'number' && Number.isFinite(value)) return value;
if (Array.isArray(value)) {
return value.map((child, index) => decodeJsonValue(child, `${where}[${index}]`));
}
if (value && typeof value === 'object') return decodeJsonObject(value, where);
throw new Error(`${where} must be JSON`);
}
export interface ExperimentSpec {
readonly schemaVersion: 'maka.eval.v1';
readonly id: string;
readonly benchmark: {
readonly id: string;
readonly version: string;
readonly config: JsonObject;
};
readonly executor: { readonly kind: string; readonly config: JsonObject };
readonly execution: { readonly maxConcurrentTaskGroups: number };
readonly subjects: readonly {
readonly id: string;
readonly kind: 'maka' | 'external';
readonly credentials: readonly string[];
readonly config: JsonObject;
}[];
readonly tasks: readonly {
readonly id: string;
readonly input: string;
readonly config: JsonObject;
}[];
readonly repetitions: number;
readonly budget: JsonObject;
readonly verifier: JsonObject;
}
export interface ExperimentCell {
readonly id: string;
readonly experimentId: string;
readonly benchmark: ExperimentSpec['benchmark'];
readonly executor: ExperimentSpec['executor'];
readonly subject: ExperimentSpec['subjects'][number];
readonly task: ExperimentSpec['tasks'][number];
readonly repetition: number;
readonly budget: JsonObject;
readonly verifier: JsonObject;
}
export function expandExperiment(spec: ExperimentSpec): ExperimentCell[] {
return spec.tasks.flatMap((task) =>
Array.from({ length: spec.repetitions }, (_, repetition) => repetition + 1).flatMap(
(repetition) =>
spec.subjects.map((subject) => ({
id: `${task.id}::${repetition}::${subject.id}`,
experimentId: spec.id,
benchmark: spec.benchmark,
executor: spec.executor,
subject,
task,
repetition,
budget: spec.budget,
verifier: spec.verifier,
})),
),
);
}