Update TriWorldBench web from desktop manager
Browse files- .gitattributes +1 -0
- Dockerfile +1 -1
- deployment-manifest.json +5 -5
- package.json +1 -0
- public/assets_common/photos/Group_Chat.jpg +2 -2
- scripts/sanitize-public-database.mjs +57 -0
- src/app/(site)/page.tsx +0 -2
- src/components/triworldbench/ClientSections.tsx +5 -1
- src/components/triworldbench/Leaderboard.tsx +23 -5
- src/components/triworldbench/metrics.ts +0 -1
- src/lib/data/leaderboard.ts +36 -14
- src/lib/db/schema.ts +0 -8
- src/styles/triworldbench.css +20 -3
.gitattributes
CHANGED
|
@@ -1,2 +1,3 @@
|
|
| 1 |
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 2 |
*.pdf filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 1 |
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 2 |
*.pdf filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
public/assets_common/photos/Group_Chat.jpg filter=lfs diff=lfs merge=lfs -text
|
Dockerfile
CHANGED
|
@@ -16,4 +16,4 @@ ENV TRIWORLDBENCH_VIDEO_ROOT=/tmp/triworldbench/video-cases
|
|
| 16 |
|
| 17 |
EXPOSE 7860
|
| 18 |
|
| 19 |
-
CMD ["sh", "-c", "npm run hf:download-dataset && npm run hf:download-video-cases && npm run hf:restore-space-assets && npx next start -H 0.0.0.0 -p ${PORT:-7860}"]
|
|
|
|
| 16 |
|
| 17 |
EXPOSE 7860
|
| 18 |
|
| 19 |
+
CMD ["sh", "-c", "npm run hf:download-dataset && npm run hf:sanitize-public-dataset && npm run hf:download-video-cases && npm run hf:restore-space-assets && npx next start -H 0.0.0.0 -p ${PORT:-7860}"]
|
deployment-manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
{
|
| 2 |
"schema": 2,
|
| 3 |
-
"generated_at_utc": "2026-08-
|
| 4 |
-
"web_tree_sha256": "
|
| 5 |
-
"source_file_count":
|
| 6 |
"release_contract": {
|
| 7 |
"web_source": "TriWorldBench/web",
|
| 8 |
"local_database": "database/database.sqlite",
|
|
@@ -13,8 +13,8 @@
|
|
| 13 |
},
|
| 14 |
"database_release": {
|
| 15 |
"dataset_file": "database.sqlite",
|
| 16 |
-
"snapshot_sha256": "
|
| 17 |
-
"data_version":
|
| 18 |
"video_count": 24,
|
| 19 |
"video_prefix": "video-cases"
|
| 20 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"schema": 2,
|
| 3 |
+
"generated_at_utc": "2026-08-14T12:00:38.227389+00:00",
|
| 4 |
+
"web_tree_sha256": "8c12cc89b824c4104f5cee92366b440fb716057cce0b1d09b6890b7baff3a818",
|
| 5 |
+
"source_file_count": 90,
|
| 6 |
"release_contract": {
|
| 7 |
"web_source": "TriWorldBench/web",
|
| 8 |
"local_database": "database/database.sqlite",
|
|
|
|
| 13 |
},
|
| 14 |
"database_release": {
|
| 15 |
"dataset_file": "database.sqlite",
|
| 16 |
+
"snapshot_sha256": "afc2a632e2c3df54014b0e2d0ea996b64427a53b31b0ad810e98cee6f0fcaa78",
|
| 17 |
+
"data_version": 275,
|
| 18 |
"video_count": 24,
|
| 19 |
"video_prefix": "video-cases"
|
| 20 |
}
|
package.json
CHANGED
|
@@ -8,6 +8,7 @@
|
|
| 8 |
"build": "next build",
|
| 9 |
"start": "next start",
|
| 10 |
"hf:download-dataset": "node scripts/download-dataset.mjs",
|
|
|
|
| 11 |
"hf:download-video-cases": "node scripts/download-video-cases.mjs",
|
| 12 |
"hf:restore-space-assets": "node scripts/restore-space-assets.mjs"
|
| 13 |
},
|
|
|
|
| 8 |
"build": "next build",
|
| 9 |
"start": "next start",
|
| 10 |
"hf:download-dataset": "node scripts/download-dataset.mjs",
|
| 11 |
+
"hf:sanitize-public-dataset": "node scripts/sanitize-public-database.mjs",
|
| 12 |
"hf:download-video-cases": "node scripts/download-video-cases.mjs",
|
| 13 |
"hf:restore-space-assets": "node scripts/restore-space-assets.mjs"
|
| 14 |
},
|
public/assets_common/photos/Group_Chat.jpg
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
scripts/sanitize-public-database.mjs
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import fs from "node:fs";
|
| 2 |
+
import os from "node:os";
|
| 3 |
+
import path from "node:path";
|
| 4 |
+
import { DatabaseSync } from "node:sqlite";
|
| 5 |
+
|
| 6 |
+
const targetPath = path.resolve(
|
| 7 |
+
process.env.TRIWORLDBENCH_DB_PATH || path.join(os.tmpdir(), "triworldbench", "database.sqlite")
|
| 8 |
+
);
|
| 9 |
+
const temporaryRoot = path.resolve(os.tmpdir());
|
| 10 |
+
|
| 11 |
+
if (process.env.TRIWORLDBENCH_PUBLIC_READONLY !== "1") {
|
| 12 |
+
throw new Error("Refusing to sanitize a database outside public read-only mode.");
|
| 13 |
+
}
|
| 14 |
+
if (targetPath !== temporaryRoot && !targetPath.startsWith(`${temporaryRoot}${path.sep}`)) {
|
| 15 |
+
throw new Error(`Refusing to sanitize a database outside the temporary directory: ${targetPath}`);
|
| 16 |
+
}
|
| 17 |
+
if (!fs.existsSync(targetPath)) {
|
| 18 |
+
throw new Error(`Downloaded public database was not found: ${targetPath}`);
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
const database = new DatabaseSync(targetPath);
|
| 22 |
+
try {
|
| 23 |
+
database.exec(`
|
| 24 |
+
BEGIN IMMEDIATE;
|
| 25 |
+
UPDATE teams
|
| 26 |
+
SET slug = 'public-team-' || id,
|
| 27 |
+
name = 'Private participant',
|
| 28 |
+
participant_email = 'private-' || id || '@invalid.local',
|
| 29 |
+
affiliation = NULL,
|
| 30 |
+
country_region = NULL,
|
| 31 |
+
strengths = NULL,
|
| 32 |
+
updated_at = CURRENT_TIMESTAMP;
|
| 33 |
+
UPDATE models
|
| 34 |
+
SET model_card_url = NULL,
|
| 35 |
+
brief_introduction = NULL;
|
| 36 |
+
UPDATE submissions
|
| 37 |
+
SET artifact_uri = NULL,
|
| 38 |
+
notes = NULL;
|
| 39 |
+
COMMIT;
|
| 40 |
+
PRAGMA wal_checkpoint(TRUNCATE);
|
| 41 |
+
`);
|
| 42 |
+
const integrity = database.prepare("PRAGMA integrity_check").get();
|
| 43 |
+
if (integrity.integrity_check !== "ok") {
|
| 44 |
+
throw new Error(`Public database integrity check failed: ${integrity.integrity_check}`);
|
| 45 |
+
}
|
| 46 |
+
} catch (error) {
|
| 47 |
+
try {
|
| 48 |
+
database.exec("ROLLBACK");
|
| 49 |
+
} catch {
|
| 50 |
+
// No active transaction remains after a successful commit.
|
| 51 |
+
}
|
| 52 |
+
throw error;
|
| 53 |
+
} finally {
|
| 54 |
+
database.close();
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
console.log("Public runtime database identity fields sanitized.");
|
src/app/(site)/page.tsx
CHANGED
|
@@ -216,7 +216,6 @@ function toBoardEntries(entries: LeaderboardEntry[]): TriWorldBoardEntry[] {
|
|
| 216 |
return {
|
| 217 |
rank: entry.rank,
|
| 218 |
modelName: entry.model.name,
|
| 219 |
-
teamName: entry.team.name,
|
| 220 |
score: entry.metrics[TRIWORLD_RANKING_CODE]?.rawValue ?? entry.score.rawValue ?? null,
|
| 221 |
normalizedScore: entry.metrics[TRIWORLD_RANKING_CODE]?.rawValue ?? entry.score.rawValue ?? null,
|
| 222 |
status: entry.statusLabel || entry.submission.status,
|
|
@@ -449,7 +448,6 @@ function LeaderboardTable({
|
|
| 449 |
<tr key={row.modelName}>
|
| 450 |
<td className="twb-model-col twb-sticky-col">
|
| 451 |
<b>{row.modelName}</b>
|
| 452 |
-
<small>{row.teamName}</small>
|
| 453 |
</td>
|
| 454 |
<td className="twb-col-rank twb-sticky-rank">
|
| 455 |
<span className={`twb-rank-badge rank-${Math.min(row.rank, 4)}`}>
|
|
|
|
| 216 |
return {
|
| 217 |
rank: entry.rank,
|
| 218 |
modelName: entry.model.name,
|
|
|
|
| 219 |
score: entry.metrics[TRIWORLD_RANKING_CODE]?.rawValue ?? entry.score.rawValue ?? null,
|
| 220 |
normalizedScore: entry.metrics[TRIWORLD_RANKING_CODE]?.rawValue ?? entry.score.rawValue ?? null,
|
| 221 |
status: entry.statusLabel || entry.submission.status,
|
|
|
|
| 448 |
<tr key={row.modelName}>
|
| 449 |
<td className="twb-model-col twb-sticky-col">
|
| 450 |
<b>{row.modelName}</b>
|
|
|
|
| 451 |
</td>
|
| 452 |
<td className="twb-col-rank twb-sticky-rank">
|
| 453 |
<span className={`twb-rank-badge rank-${Math.min(row.rank, 4)}`}>
|
src/components/triworldbench/ClientSections.tsx
CHANGED
|
@@ -429,7 +429,11 @@ function OverallRadar({
|
|
| 429 |
style={{ "--c": color, "--dash": dashPattern } as React.CSSProperties}
|
| 430 |
>
|
| 431 |
<polygon className="twb-radar-area" points={points} />
|
| 432 |
-
<polyline
|
|
|
|
|
|
|
|
|
|
|
|
|
| 433 |
</g>
|
| 434 |
);
|
| 435 |
})}
|
|
|
|
| 429 |
style={{ "--c": color, "--dash": dashPattern } as React.CSSProperties}
|
| 430 |
>
|
| 431 |
<polygon className="twb-radar-area" points={points} />
|
| 432 |
+
<polyline
|
| 433 |
+
className="twb-radar-line"
|
| 434 |
+
fill="none"
|
| 435 |
+
points={`${points} ${points.split(" ")[0]}`}
|
| 436 |
+
/>
|
| 437 |
</g>
|
| 438 |
);
|
| 439 |
})}
|
src/components/triworldbench/Leaderboard.tsx
CHANGED
|
@@ -94,6 +94,7 @@ export function TriWorldLeaderboard({ rows, metricTexts, descriptionText }: Prop
|
|
| 94 |
const [highlightedName, setHighlightedName] = useState<string | null>(null);
|
| 95 |
const [message, setMessage] = useState("");
|
| 96 |
const rangeMenuRef = useRef<HTMLDetailsElement>(null);
|
|
|
|
| 97 |
const rowRefs = useRef(new Map<string, HTMLTableRowElement>());
|
| 98 |
|
| 99 |
const ranges = useMemo(() => {
|
|
@@ -129,6 +130,24 @@ export function TriWorldLeaderboard({ rows, metricTexts, descriptionText }: Prop
|
|
| 129 |
return ranksByMetric;
|
| 130 |
}, [rows]);
|
| 131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
const locate = useCallback((name = query) => {
|
| 133 |
const normalized = name.trim().toLocaleLowerCase();
|
| 134 |
if (!normalized) {
|
|
@@ -147,9 +166,9 @@ export function TriWorldLeaderboard({ rows, metricTexts, descriptionText }: Prop
|
|
| 147 |
setHighlightedName(matched.modelName);
|
| 148 |
setMessage(`Located ${matched.modelName} at rank ${matched.rank}.`);
|
| 149 |
window.requestAnimationFrame(() => {
|
| 150 |
-
|
| 151 |
});
|
| 152 |
-
}, [query, rows]);
|
| 153 |
|
| 154 |
const jumpToRange = (start: number) => {
|
| 155 |
const row = rows[start];
|
|
@@ -158,7 +177,7 @@ export function TriWorldLeaderboard({ rows, metricTexts, descriptionText }: Prop
|
|
| 158 |
setMessage("");
|
| 159 |
rangeMenuRef.current?.removeAttribute("open");
|
| 160 |
window.requestAnimationFrame(() => {
|
| 161 |
-
|
| 162 |
});
|
| 163 |
};
|
| 164 |
|
|
@@ -204,7 +223,7 @@ export function TriWorldLeaderboard({ rows, metricTexts, descriptionText }: Prop
|
|
| 204 |
</div>
|
| 205 |
{message ? <p className="twb-locator-message" role="status">{message}</p> : null}
|
| 206 |
|
| 207 |
-
<div className="twb-table-wrap" tabIndex={0} aria-label="TriWorldBench leaderboard">
|
| 208 |
<table
|
| 209 |
className="twb-dense-table"
|
| 210 |
style={{ "--twb-score-column-count": TRIWORLD_TABLE_METRICS.length } as React.CSSProperties}
|
|
@@ -246,7 +265,6 @@ export function TriWorldLeaderboard({ rows, metricTexts, descriptionText }: Prop
|
|
| 246 |
>
|
| 247 |
<td className="twb-model-col twb-sticky-col">
|
| 248 |
<b>{row.modelName}</b>
|
| 249 |
-
{row.teamName ? <small>{row.teamName}</small> : null}
|
| 250 |
</td>
|
| 251 |
<td className="twb-col-rank twb-sticky-rank">
|
| 252 |
<span className={`twb-rank-badge rank-${row.rank <= 3 ? row.rank : "other"}`}>
|
|
|
|
| 94 |
const [highlightedName, setHighlightedName] = useState<string | null>(null);
|
| 95 |
const [message, setMessage] = useState("");
|
| 96 |
const rangeMenuRef = useRef<HTMLDetailsElement>(null);
|
| 97 |
+
const tableWrapRef = useRef<HTMLDivElement>(null);
|
| 98 |
const rowRefs = useRef(new Map<string, HTMLTableRowElement>());
|
| 99 |
|
| 100 |
const ranges = useMemo(() => {
|
|
|
|
| 130 |
return ranksByMetric;
|
| 131 |
}, [rows]);
|
| 132 |
|
| 133 |
+
const scrollToRow = useCallback((modelName: string, block: "start" | "center") => {
|
| 134 |
+
const container = tableWrapRef.current;
|
| 135 |
+
const row = rowRefs.current.get(modelName);
|
| 136 |
+
if (!container || !row) return;
|
| 137 |
+
|
| 138 |
+
const containerRect = container.getBoundingClientRect();
|
| 139 |
+
const rowRect = row.getBoundingClientRect();
|
| 140 |
+
const headerHeight = container.querySelector("thead")?.getBoundingClientRect().height ?? 0;
|
| 141 |
+
const targetTop = block === "center"
|
| 142 |
+
? container.scrollTop + rowRect.top - containerRect.top - (container.clientHeight - rowRect.height) / 2
|
| 143 |
+
: container.scrollTop + rowRect.top - containerRect.top - headerHeight;
|
| 144 |
+
|
| 145 |
+
container.scrollTo({
|
| 146 |
+
top: Math.max(0, targetTop),
|
| 147 |
+
behavior: "smooth",
|
| 148 |
+
});
|
| 149 |
+
}, []);
|
| 150 |
+
|
| 151 |
const locate = useCallback((name = query) => {
|
| 152 |
const normalized = name.trim().toLocaleLowerCase();
|
| 153 |
if (!normalized) {
|
|
|
|
| 166 |
setHighlightedName(matched.modelName);
|
| 167 |
setMessage(`Located ${matched.modelName} at rank ${matched.rank}.`);
|
| 168 |
window.requestAnimationFrame(() => {
|
| 169 |
+
scrollToRow(matched.modelName, "center");
|
| 170 |
});
|
| 171 |
+
}, [query, rows, scrollToRow]);
|
| 172 |
|
| 173 |
const jumpToRange = (start: number) => {
|
| 174 |
const row = rows[start];
|
|
|
|
| 177 |
setMessage("");
|
| 178 |
rangeMenuRef.current?.removeAttribute("open");
|
| 179 |
window.requestAnimationFrame(() => {
|
| 180 |
+
scrollToRow(row.modelName, "start");
|
| 181 |
});
|
| 182 |
};
|
| 183 |
|
|
|
|
| 223 |
</div>
|
| 224 |
{message ? <p className="twb-locator-message" role="status">{message}</p> : null}
|
| 225 |
|
| 226 |
+
<div ref={tableWrapRef} className="twb-table-wrap" tabIndex={0} aria-label="TriWorldBench leaderboard">
|
| 227 |
<table
|
| 228 |
className="twb-dense-table"
|
| 229 |
style={{ "--twb-score-column-count": TRIWORLD_TABLE_METRICS.length } as React.CSSProperties}
|
|
|
|
| 265 |
>
|
| 266 |
<td className="twb-model-col twb-sticky-col">
|
| 267 |
<b>{row.modelName}</b>
|
|
|
|
| 268 |
</td>
|
| 269 |
<td className="twb-col-rank twb-sticky-rank">
|
| 270 |
<span className={`twb-rank-badge rank-${row.rank <= 3 ? row.rank : "other"}`}>
|
src/components/triworldbench/metrics.ts
CHANGED
|
@@ -195,7 +195,6 @@ export type TriWorldMetricCode = string;
|
|
| 195 |
export interface TriWorldBoardEntry {
|
| 196 |
rank: number;
|
| 197 |
modelName: string;
|
| 198 |
-
teamName: string;
|
| 199 |
score: number | null;
|
| 200 |
normalizedScore: number | null;
|
| 201 |
status: string;
|
|
|
|
| 195 |
export interface TriWorldBoardEntry {
|
| 196 |
rank: number;
|
| 197 |
modelName: string;
|
|
|
|
| 198 |
score: number | null;
|
| 199 |
normalizedScore: number | null;
|
| 200 |
status: string;
|
src/lib/data/leaderboard.ts
CHANGED
|
@@ -13,18 +13,42 @@ export function latestSnapshot(snapshotParam?: string | null): LeaderboardSnapsh
|
|
| 13 |
const db = getDb();
|
| 14 |
if (snapshotParam && snapshotParam !== "latest") {
|
| 15 |
return (
|
| 16 |
-
dbGet<LeaderboardSnapshot>(
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
);
|
| 19 |
}
|
| 20 |
return dbGet<LeaderboardSnapshot>(
|
| 21 |
-
db.prepare(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
);
|
| 23 |
}
|
| 24 |
|
| 25 |
export function getSnapshotHistory(): LeaderboardSnapshot[] {
|
| 26 |
return all<LeaderboardSnapshot>(
|
| 27 |
-
getDb().prepare(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
);
|
| 29 |
}
|
| 30 |
|
|
@@ -43,14 +67,12 @@ export function getLeaderboard(
|
|
| 43 |
const rawEntries = db
|
| 44 |
.prepare(
|
| 45 |
`SELECT e.rank, e.status_label, e.updated_label, e.submission_id,
|
| 46 |
-
t.id AS team_id, t.slug AS team_slug, t.name AS team_name, t.affiliation, t.strengths,
|
| 47 |
mo.id AS model_id, mo.slug AS model_slug, mo.name AS model_name,
|
| 48 |
s.version_label, s.status AS submission_status, s.dataset_split, s.submitted_at,
|
| 49 |
sr.normalized_value, sr.percentile, sr.raw_value
|
| 50 |
FROM leaderboard_snapshot_entries e
|
| 51 |
JOIN submissions s ON s.id = e.submission_id
|
| 52 |
JOIN models mo ON mo.id = s.model_id
|
| 53 |
-
JOIN teams t ON t.id = mo.team_id
|
| 54 |
JOIN score_records sr ON sr.id = e.score_record_id
|
| 55 |
WHERE e.snapshot_id = ? ORDER BY e.rank LIMIT ?`
|
| 56 |
)
|
|
@@ -63,11 +85,6 @@ export function getLeaderboard(
|
|
| 63 |
rank: entry.rank as number,
|
| 64 |
statusLabel: entry.status_label as string | null,
|
| 65 |
updatedLabel: entry.updated_label as string | null,
|
| 66 |
-
team: {
|
| 67 |
-
id: entry.team_id as number, slug: entry.team_slug as string,
|
| 68 |
-
name: entry.team_name as string, affiliation: entry.affiliation as string | null,
|
| 69 |
-
strengths: entry.strengths as string | null,
|
| 70 |
-
},
|
| 71 |
model: {
|
| 72 |
id: entry.model_id as number, slug: entry.model_slug as string,
|
| 73 |
name: entry.model_name as string,
|
|
@@ -95,7 +112,7 @@ export function getRadarData(
|
|
| 95 |
const codes = metricCodes?.length ? metricCodes : DEFAULT_RADAR_METRICS;
|
| 96 |
const board = getLeaderboard("latest");
|
| 97 |
const entries = board.entries.slice(0, top).map((entry) => ({
|
| 98 |
-
rank: entry.rank, model: entry.model,
|
| 99 |
axes: codes.map((code) => {
|
| 100 |
const metric = entry.metrics[code];
|
| 101 |
return { code, label: metric ? metric.displayName : code, value: metric?.percentile ?? null };
|
|
@@ -129,14 +146,19 @@ export function getModelScores(modelId: string): {
|
|
| 129 |
} {
|
| 130 |
const db = getDb();
|
| 131 |
const model = db.prepare(
|
| 132 |
-
`SELECT mo.
|
|
|
|
|
|
|
| 133 |
).get(modelId, modelId) as Record<string, unknown> | null;
|
| 134 |
|
| 135 |
if (!model) return { model: null, submission: null, scores: [] };
|
| 136 |
|
| 137 |
const modelIdNum = model.id as number;
|
| 138 |
const submission = db.prepare(
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
| 140 |
).get(modelIdNum) as Record<string, unknown> | null;
|
| 141 |
|
| 142 |
if (!submission) return { model, submission: null, scores: [] };
|
|
|
|
| 13 |
const db = getDb();
|
| 14 |
if (snapshotParam && snapshotParam !== "latest") {
|
| 15 |
return (
|
| 16 |
+
dbGet<LeaderboardSnapshot>(
|
| 17 |
+
db.prepare(
|
| 18 |
+
`SELECT id, label, snapshot_time, status, ranking_policy, NULL AS notes,
|
| 19 |
+
is_latest, created_at
|
| 20 |
+
FROM leaderboard_snapshots WHERE id = ?`
|
| 21 |
+
),
|
| 22 |
+
snapshotParam
|
| 23 |
+
) ||
|
| 24 |
+
dbGet<LeaderboardSnapshot>(
|
| 25 |
+
db.prepare(
|
| 26 |
+
`SELECT id, label, snapshot_time, status, ranking_policy, NULL AS notes,
|
| 27 |
+
is_latest, created_at
|
| 28 |
+
FROM leaderboard_snapshots WHERE label = ?`
|
| 29 |
+
),
|
| 30 |
+
snapshotParam
|
| 31 |
+
)
|
| 32 |
);
|
| 33 |
}
|
| 34 |
return dbGet<LeaderboardSnapshot>(
|
| 35 |
+
db.prepare(
|
| 36 |
+
`SELECT id, label, snapshot_time, status, ranking_policy, NULL AS notes,
|
| 37 |
+
is_latest, created_at
|
| 38 |
+
FROM leaderboard_snapshots
|
| 39 |
+
ORDER BY is_latest DESC, snapshot_time DESC, id DESC LIMIT 1`
|
| 40 |
+
)
|
| 41 |
);
|
| 42 |
}
|
| 43 |
|
| 44 |
export function getSnapshotHistory(): LeaderboardSnapshot[] {
|
| 45 |
return all<LeaderboardSnapshot>(
|
| 46 |
+
getDb().prepare(
|
| 47 |
+
`SELECT id, label, snapshot_time, status, ranking_policy, NULL AS notes,
|
| 48 |
+
is_latest, created_at
|
| 49 |
+
FROM leaderboard_snapshots
|
| 50 |
+
ORDER BY snapshot_time DESC, id DESC`
|
| 51 |
+
)
|
| 52 |
);
|
| 53 |
}
|
| 54 |
|
|
|
|
| 67 |
const rawEntries = db
|
| 68 |
.prepare(
|
| 69 |
`SELECT e.rank, e.status_label, e.updated_label, e.submission_id,
|
|
|
|
| 70 |
mo.id AS model_id, mo.slug AS model_slug, mo.name AS model_name,
|
| 71 |
s.version_label, s.status AS submission_status, s.dataset_split, s.submitted_at,
|
| 72 |
sr.normalized_value, sr.percentile, sr.raw_value
|
| 73 |
FROM leaderboard_snapshot_entries e
|
| 74 |
JOIN submissions s ON s.id = e.submission_id
|
| 75 |
JOIN models mo ON mo.id = s.model_id
|
|
|
|
| 76 |
JOIN score_records sr ON sr.id = e.score_record_id
|
| 77 |
WHERE e.snapshot_id = ? ORDER BY e.rank LIMIT ?`
|
| 78 |
)
|
|
|
|
| 85 |
rank: entry.rank as number,
|
| 86 |
statusLabel: entry.status_label as string | null,
|
| 87 |
updatedLabel: entry.updated_label as string | null,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
model: {
|
| 89 |
id: entry.model_id as number, slug: entry.model_slug as string,
|
| 90 |
name: entry.model_name as string,
|
|
|
|
| 112 |
const codes = metricCodes?.length ? metricCodes : DEFAULT_RADAR_METRICS;
|
| 113 |
const board = getLeaderboard("latest");
|
| 114 |
const entries = board.entries.slice(0, top).map((entry) => ({
|
| 115 |
+
rank: entry.rank, model: entry.model, score: entry.score,
|
| 116 |
axes: codes.map((code) => {
|
| 117 |
const metric = entry.metrics[code];
|
| 118 |
return { code, label: metric ? metric.displayName : code, value: metric?.percentile ?? null };
|
|
|
|
| 146 |
} {
|
| 147 |
const db = getDb();
|
| 148 |
const model = db.prepare(
|
| 149 |
+
`SELECT mo.id, mo.slug, mo.name
|
| 150 |
+
FROM models mo
|
| 151 |
+
WHERE mo.id = ? OR mo.slug = ?`
|
| 152 |
).get(modelId, modelId) as Record<string, unknown> | null;
|
| 153 |
|
| 154 |
if (!model) return { model: null, submission: null, scores: [] };
|
| 155 |
|
| 156 |
const modelIdNum = model.id as number;
|
| 157 |
const submission = db.prepare(
|
| 158 |
+
`SELECT id, model_id, version_label, submitted_at, status, dataset_split
|
| 159 |
+
FROM submissions
|
| 160 |
+
WHERE model_id = ?
|
| 161 |
+
ORDER BY submitted_at DESC, id DESC LIMIT 1`
|
| 162 |
).get(modelIdNum) as Record<string, unknown> | null;
|
| 163 |
|
| 164 |
if (!submission) return { model, submission: null, scores: [] };
|
src/lib/db/schema.ts
CHANGED
|
@@ -354,13 +354,6 @@ export interface LeaderboardEntry {
|
|
| 354 |
rank: number;
|
| 355 |
statusLabel: string | null;
|
| 356 |
updatedLabel: string | null;
|
| 357 |
-
team: {
|
| 358 |
-
id: number;
|
| 359 |
-
slug: string;
|
| 360 |
-
name: string;
|
| 361 |
-
affiliation: string | null;
|
| 362 |
-
strengths: string | null;
|
| 363 |
-
};
|
| 364 |
model: {
|
| 365 |
id: number;
|
| 366 |
slug: string;
|
|
@@ -384,7 +377,6 @@ export interface LeaderboardEntry {
|
|
| 384 |
export interface RadarEntry {
|
| 385 |
rank: number;
|
| 386 |
model: { name: string; slug: string };
|
| 387 |
-
team: { name: string };
|
| 388 |
score: { percentile: number | null };
|
| 389 |
axes: Array<{ code: string; label: string; value: number | null }>;
|
| 390 |
}
|
|
|
|
| 354 |
rank: number;
|
| 355 |
statusLabel: string | null;
|
| 356 |
updatedLabel: string | null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 357 |
model: {
|
| 358 |
id: number;
|
| 359 |
slug: string;
|
|
|
|
| 377 |
export interface RadarEntry {
|
| 378 |
rank: number;
|
| 379 |
model: { name: string; slug: string };
|
|
|
|
| 380 |
score: { percentile: number | null };
|
| 381 |
axes: Array<{ code: string; label: string; value: number | null }>;
|
| 382 |
}
|
src/styles/triworldbench.css
CHANGED
|
@@ -2062,8 +2062,8 @@ main,
|
|
| 2062 |
width: 100%;
|
| 2063 |
height: 100%;
|
| 2064 |
object-fit: contain;
|
|
|
|
| 2065 |
padding: 8px;
|
| 2066 |
-
transform: translateY(24px);
|
| 2067 |
}
|
| 2068 |
.coming { border-radius: 4px; }
|
| 2069 |
.citation-code,
|
|
@@ -2650,7 +2650,7 @@ body .twb-doc[data-page="triworldbench"] #contact .contact-card p span {
|
|
| 2650 |
#leaderboard .twb-radar-scale, .visualization .twb-radar-scale { fill: currentColor; font-size: 9px; opacity: .55; }
|
| 2651 |
.visualization .twb-radar-ring, .visualization .twb-radar-axis { fill: none; stroke: currentColor; opacity: .22; vector-effect: non-scaling-stroke; }
|
| 2652 |
.visualization .twb-radar-label { fill: currentColor; font-size: 11px; font-weight: 800; text-anchor: middle; dominant-baseline: middle; }
|
| 2653 |
-
.visualization .twb-radar-area { fill:
|
| 2654 |
.visualization .twb-radar-line { fill: none; stroke: var(--c); stroke-width: 1.8; vector-effect: non-scaling-stroke; }
|
| 2655 |
|
| 2656 |
/* per-metric split: bar list + radar */
|
|
@@ -2711,7 +2711,10 @@ body .twb-doc[data-page="triworldbench"] #contact .contact-card p span {
|
|
| 2711 |
/* radar series highlight / dim states */
|
| 2712 |
.visualization .twb-radar-series.is-dim { opacity: .14; }
|
| 2713 |
.visualization .twb-radar-series.is-hl .twb-radar-line { stroke-width: 3.4; }
|
| 2714 |
-
.visualization .twb-radar-series.is-hl .twb-radar-area {
|
|
|
|
|
|
|
|
|
|
| 2715 |
.visualization .twb-radar-spoke line { stroke: var(--c); stroke-width: 2.2; vector-effect: non-scaling-stroke; }
|
| 2716 |
.visualization .twb-radar-spoke circle { fill: var(--c); }
|
| 2717 |
.visualization .twb-radar-spoke.is-dim { opacity: .16; }
|
|
@@ -5645,6 +5648,20 @@ body .twb-doc[data-page="triworldbench"] #contact .contact-card * {
|
|
| 5645 |
dominant-baseline: middle;
|
| 5646 |
opacity: .68;
|
| 5647 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5648 |
.twb-doc[data-page="triworldbench"] .twb-vis-top .twb-vis-models {
|
| 5649 |
background: #f1f3f5;
|
| 5650 |
border-color: #d5dadd;
|
|
|
|
| 2062 |
width: 100%;
|
| 2063 |
height: 100%;
|
| 2064 |
object-fit: contain;
|
| 2065 |
+
object-position: center;
|
| 2066 |
padding: 8px;
|
|
|
|
| 2067 |
}
|
| 2068 |
.coming { border-radius: 4px; }
|
| 2069 |
.citation-code,
|
|
|
|
| 2650 |
#leaderboard .twb-radar-scale, .visualization .twb-radar-scale { fill: currentColor; font-size: 9px; opacity: .55; }
|
| 2651 |
.visualization .twb-radar-ring, .visualization .twb-radar-axis { fill: none; stroke: currentColor; opacity: .22; vector-effect: non-scaling-stroke; }
|
| 2652 |
.visualization .twb-radar-label { fill: currentColor; font-size: 11px; font-weight: 800; text-anchor: middle; dominant-baseline: middle; }
|
| 2653 |
+
.visualization .twb-radar-area { fill: #6f7880; fill-opacity: .01; stroke: none; }
|
| 2654 |
.visualization .twb-radar-line { fill: none; stroke: var(--c); stroke-width: 1.8; vector-effect: non-scaling-stroke; }
|
| 2655 |
|
| 2656 |
/* per-metric split: bar list + radar */
|
|
|
|
| 2711 |
/* radar series highlight / dim states */
|
| 2712 |
.visualization .twb-radar-series.is-dim { opacity: .14; }
|
| 2713 |
.visualization .twb-radar-series.is-hl .twb-radar-line { stroke-width: 3.4; }
|
| 2714 |
+
.visualization .twb-radar-series.is-hl .twb-radar-area {
|
| 2715 |
+
fill: #69737b;
|
| 2716 |
+
fill-opacity: .10;
|
| 2717 |
+
}
|
| 2718 |
.visualization .twb-radar-spoke line { stroke: var(--c); stroke-width: 2.2; vector-effect: non-scaling-stroke; }
|
| 2719 |
.visualization .twb-radar-spoke circle { fill: var(--c); }
|
| 2720 |
.visualization .twb-radar-spoke.is-dim { opacity: .16; }
|
|
|
|
| 5648 |
dominant-baseline: middle;
|
| 5649 |
opacity: .68;
|
| 5650 |
}
|
| 5651 |
+
.twb-doc[data-page="triworldbench"] .visualization .twb-radar-series .twb-radar-line,
|
| 5652 |
+
.twb-doc[data-page="triworldbench"] .visualization .twb-radar-series.is-hl .twb-radar-line {
|
| 5653 |
+
fill: none !important;
|
| 5654 |
+
fill-opacity: 0 !important;
|
| 5655 |
+
}
|
| 5656 |
+
.twb-doc[data-page="triworldbench"] .visualization .twb-radar-series .twb-radar-area {
|
| 5657 |
+
display: block !important;
|
| 5658 |
+
fill: #6f7880 !important;
|
| 5659 |
+
fill-opacity: .01 !important;
|
| 5660 |
+
}
|
| 5661 |
+
.twb-doc[data-page=triworldbench] .visualization .twb-radar-series.is-hl .twb-radar-area {
|
| 5662 |
+
fill: #69737b !important;
|
| 5663 |
+
fill-opacity: .10 !important;
|
| 5664 |
+
}
|
| 5665 |
.twb-doc[data-page="triworldbench"] .twb-vis-top .twb-vis-models {
|
| 5666 |
background: #f1f3f5;
|
| 5667 |
border-color: #d5dadd;
|