luke0709
Create standalone static benchmark leaderboard
ac7a77a
Raw
History Blame
3.48 kB
export const CANONICAL_DATASETS = [
'일반 상식', '멀티 모달', '수치 정보', '팩트 체크', '소버린 벤치마크',
'K-Prism (Text, Intact)', 'K-Prism (Text, Perturbed)',
'K-Prism (Image, Intact)', 'K-Prism (Image, Perturbed)',
];
const isText = value => typeof value === 'string' && value.trim().length > 0;
// Accept both the original benchmark.json array and a published {models} snapshot.
// Validate before replacing the visible results so failed refreshes keep good data.
export function normalizeBenchmark(payload) {
const source = Array.isArray(payload) ? payload : payload?.models;
if (!Array.isArray(source)) throw new Error('Expected a model array or an object with models.');
const modelKeys = new Set();
const models = source.map((model, index) => {
if (!model || !isText(model.provider) || !isText(model.name)) {
throw new Error(`Model ${index + 1} is missing its provider or name.`);
}
const key = JSON.stringify([model.provider, model.name]);
if (modelKeys.has(key)) throw new Error(`Duplicate model: ${model.provider} / ${model.name}.`);
modelKeys.add(key);
if (!Array.isArray(model.scores)) throw new Error(`Invalid scores for ${model.name}.`);
if (model.is_multimodal != null && typeof model.is_multimodal !== 'boolean') {
throw new Error(`Invalid model type for ${model.name}.`);
}
const scoreNames = new Set();
const scores = model.scores.map(score => {
if (!score || !isText(score.dataset_name) || !Number.isFinite(score.score)) {
throw new Error(`Invalid score for ${model.name}.`);
}
if (scoreNames.has(score.dataset_name)) {
throw new Error(`Duplicate dataset score for ${model.name}: ${score.dataset_name}.`);
}
scoreNames.add(score.dataset_name);
return {
dataset_name: score.dataset_name,
metric_type: score.metric_type === 'llm-as-judge' ? 'llm-as-judge' : 'raw',
score: score.score,
};
});
return {
provider: model.provider,
name: model.name,
repo: typeof model.repo === 'string' ? model.repo : '',
is_multimodal: model.is_multimodal ?? false,
status: typeof model.status === 'string' ? model.status : 'completed',
updated_at: typeof model.updated_at === 'string' ? model.updated_at : '',
scores,
};
});
const publishedDatasets = Array.isArray(payload) ? undefined : payload.datasets;
if (publishedDatasets !== undefined &&
(!Array.isArray(publishedDatasets) || !publishedDatasets.every(isText))) {
throw new Error('Invalid dataset list.');
}
// A published list preserves the curator's selection and order. Legacy arrays
// include the canonical datasets plus any additional scored datasets.
const datasets = [...new Set(publishedDatasets ?? [
...CANONICAL_DATASETS,
...models.flatMap(model => model.scores.map(score => score.dataset_name)),
])];
return { models, datasets };
}
export async function loadBenchmark(url, timeoutMs = 15000) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, {
cache: 'no-store',
credentials: 'omit',
signal: controller.signal,
});
if (!response.ok) throw new Error(`Score data request failed (HTTP ${response.status}).`);
return normalizeBenchmark(await response.json());
} finally {
clearTimeout(timeout);
}
}