Spaces:
Running
Running
File size: 3,993 Bytes
a2c885c 75ee81e a2c885c c418fdb 75ee81e a2c885c 75ee81e a2c885c 75ee81e a2c885c 75ee81e a2c885c 75ee81e a2c885c 75ee81e a2c885c 75ee81e a2c885c 75ee81e a2c885c 75ee81e a2c885c 75ee81e a2c885c 75ee81e a2c885c 75ee81e c418fdb 75ee81e | 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 | import { HF_DATASET_BASE_URL, MAX_DOCS_TO_SCAN, getCorpora, getLinksRepoPath, getDocRepoPath } from '../../../utils/config.js';
export const dynamic = 'force-dynamic';
/**
* GET /api/leaderboard
* Scans ALL corpora and returns annotator rankings.
*/
export async function GET() {
try {
const corpora = getCorpora();
const stats = {}; // annotator -> { verified, correct, incorrect, docs, humanAdded }
for (const corpus of corpora) {
const linksPath = getLinksRepoPath(corpus);
const linksUrl = `${HF_DATASET_BASE_URL}/raw/main/${linksPath}`;
const linksRes = await fetch(linksUrl, {
headers: { 'Authorization': `Bearer ${process.env.HF_TOKEN}` },
cache: 'no-store'
});
if (!linksRes.ok) continue;
const links = await linksRes.json();
const activeLinks = links
.filter(l => l.status === 'success' && l.has_revalidation === true)
.slice(0, MAX_DOCS_TO_SCAN);
await Promise.allSettled(
activeLinks.map(async (link) => {
const docRepoPath = getDocRepoPath(corpus, link.index);
const docUrl = `${HF_DATASET_BASE_URL}/raw/main/${docRepoPath}`;
const docRes = await fetch(docUrl, {
headers: { 'Authorization': `Bearer ${process.env.HF_TOKEN}` },
cache: 'no-store'
});
if (!docRes.ok) return;
const pagesData = await docRes.json();
for (const page of pagesData) {
for (const ds of (page.datasets || [])) {
if (ds.source === 'human' && ds.annotator) {
if (!stats[ds.annotator]) {
stats[ds.annotator] = { verified: 0, correct: 0, incorrect: 0, docs: new Set(), humanAdded: 0 };
}
stats[ds.annotator].humanAdded++;
stats[ds.annotator].docs.add(`${corpus.id}:${link.index}`);
}
for (const v of (ds.validations || [])) {
if (!v.annotator || !v.human_validated) continue;
if (!stats[v.annotator]) {
stats[v.annotator] = { verified: 0, correct: 0, incorrect: 0, docs: new Set(), humanAdded: 0 };
}
stats[v.annotator].verified++;
if (v.human_verdict === true) stats[v.annotator].correct++;
else stats[v.annotator].incorrect++;
stats[v.annotator].docs.add(`${corpus.id}:${link.index}`);
}
}
}
})
);
}
const leaderboard = Object.entries(stats)
.map(([annotator, s]) => ({
annotator,
verified: s.verified,
correct: s.correct,
incorrect: s.incorrect,
humanAdded: s.humanAdded,
docsWorked: s.docs.size,
score: s.verified + s.humanAdded,
}))
.sort((a, b) => b.score - a.score);
return new Response(JSON.stringify({ leaderboard }), {
status: 200,
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache, no-store, must-revalidate'
}
});
} catch (error) {
console.error('Leaderboard API error:', error);
return new Response(
JSON.stringify({ error: 'Failed to compute leaderboard' }),
{ status: 500, headers: { 'Content-Type': 'application/json' } }
);
}
}
|