Spaces:
Running
Running
| import fs from 'fs' | |
| import path from 'path' | |
| import type { ModelData, BenchmarkStats, MetricThresholds } from './types' | |
| function pct(val: string): number | null { | |
| const s = val?.trim() | |
| if (!s) return null | |
| const n = parseFloat(s.replace('%', '')) | |
| return isNaN(n) ? null : n / 100 | |
| } | |
| function num(val: string): number | null { | |
| const s = val?.trim() | |
| if (!s) return null | |
| const n = parseFloat(s) | |
| return isNaN(n) ? null : n | |
| } | |
| export function loadData(): ModelData[] { | |
| const filePath = path.join(process.cwd(), 'public', 'data.csv') | |
| const text = fs.readFileSync(filePath, 'utf-8') | |
| const lines = text.split('\n').filter(l => l.trim()).slice(2) | |
| return lines | |
| .map(line => { | |
| const cols = line.split(',') | |
| return { | |
| rank: parseInt(cols[0]) || 0, | |
| creator: cols[1]?.trim() || '', | |
| model: cols[2]?.trim() || '', | |
| luc: { | |
| general: pct(cols[3]), | |
| physics: pct(cols[4]), | |
| career: pct(cols[5]), | |
| jd: pct(cols[6]), | |
| avg: pct(cols[7]), | |
| }, | |
| rag: { | |
| lcAbs: pct(cols[8]), | |
| lcFact: pct(cols[9]), | |
| hyAbs: pct(cols[10]), | |
| hyFact: pct(cols[11]), | |
| avg: pct(cols[12]), | |
| }, | |
| fairness: { | |
| style: num(cols[13]), | |
| con: num(cols[14]), | |
| avg: num(cols[15]), | |
| }, | |
| archived: cols[16]?.trim() === 'true', | |
| } | |
| }) | |
| .filter(m => m.creator && m.model) | |
| } | |
| export function computeStats(models: ModelData[]): BenchmarkStats { | |
| const active = models.filter(m => !m.archived) | |
| const creators = new Set(models.map(m => m.creator)) | |
| const lucScores = active.map(m => m.luc.avg).filter((v): v is number => v !== null) | |
| const ragScores = active.map(m => m.rag.avg).filter((v): v is number => v !== null) | |
| const avgLUC = lucScores.reduce((a, b) => a + b, 0) / lucScores.length | |
| const avgRAG = ragScores.reduce((a, b) => a + b, 0) / ragScores.length | |
| const topModel = active | |
| .filter(m => m.luc.avg !== null) | |
| .sort((a, b) => (b.luc.avg ?? 0) - (a.luc.avg ?? 0))[0]?.model ?? '' | |
| return { | |
| totalModels: models.length, | |
| totalCreators: creators.size, | |
| avgLUC, | |
| avgRAG, | |
| topModel, | |
| lastUpdated: new Date().toLocaleDateString('en-SG', { month: 'short', year: 'numeric' }), | |
| } | |
| } | |
| export function getMaxFairnessAvg(models: ModelData[]): number { | |
| const vals = models.map(m => m.fairness.avg).filter((v): v is number => v !== null) | |
| return Math.max(...vals) | |
| } | |
| function empiricalPercentile(vals: number[], p: number): number { | |
| const sorted = [...vals].sort((a, b) => a - b) | |
| const idx = (p / 100) * (sorted.length - 1) | |
| const lo = Math.floor(idx) | |
| const hi = Math.ceil(idx) | |
| return sorted[lo] + (idx - lo) * (sorted[hi] - sorted[lo]) | |
| } | |
| export function computeThresholds(models: ModelData[]): MetricThresholds { | |
| const active = models.filter(m => !m.archived) | |
| const luc = active.map(m => m.luc.avg).filter((v): v is number => v !== null) | |
| const rag = active.map(m => m.rag.avg).filter((v): v is number => v !== null) | |
| const fair = active.map(m => m.fairness.avg).filter((v): v is number => v !== null) | |
| return { | |
| luc: { p33: empiricalPercentile(luc, 33), p67: empiricalPercentile(luc, 67) }, | |
| rag: { p33: empiricalPercentile(rag, 33), p67: empiricalPercentile(rag, 67) }, | |
| fairness: { p33: empiricalPercentile(fair, 33), p67: empiricalPercentile(fair, 67) }, | |
| } | |
| } | |