j-chim Claude Opus 4.7 (1M context) commited on
Commit
154e1d8
Β·
1 Parent(s): db192b0

Restore DuckDB-aware build cache logic

Browse files

The rebase took origin/main wholesale for cache-hf-data.mjs to preserve
the new corpus-aggregates.json fetch. That dropped four pieces of the
DuckDB build path that the production HF Space deploy needs:

- isDuckDBLean mode + ESSENTIAL/JSON_FALLBACK split (skips ~2.7 GB of
JSON snapshots that OOM the Space)
- HF_DATASET_REPO env var override (so the Dockerfile ARG reaches the
cache step instead of being silently ignored)
- duckdb/ in CACHE_DIRECTORIES (else the parquet that lib/duckdb-data.ts
reads is never copied β†’ static prerender fails)
- Binary-safe download via Buffer.from(arrayBuffer()) instead of
response.text() (text-mode would corrupt parquet)
- HF_TOKEN auth header for private/gated dataset access

Re-applies 14c3a2d's intent and adds corpus-aggregates.json to the
essential set (essential because the corpus dashboard depends on it
in both modes; optional because the prod dataset may not have it
populated yet).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files changed (1) hide show
  1. scripts/cache-hf-data.mjs +56 -14
scripts/cache-hf-data.mjs CHANGED
@@ -18,30 +18,60 @@ import { promisify } from "util"
18
  const root = path.resolve(new URL(import.meta.url).pathname, "..", "..")
19
  const cacheDir = path.join(root, ".cache", "hf-data")
20
  const publicDir = path.join(root, "public")
21
- const HF_DATASET_REPO = "https://huggingface.co/datasets/evaleval/card_backend"
 
22
  const HF_RESOLVE_BASE = `${HF_DATASET_REPO}/resolve/main`
23
  const execFileAsync = promisify(execFile)
24
 
25
- const CACHE_ROOT_FILES = [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  "manifest.json",
 
 
 
 
 
 
 
27
  "model-cards.json",
28
  "model-cards-lite.json",
29
  "eval-list.json",
30
  "eval-list-lite.json",
31
  "developers.json",
32
- "benchmark-metadata.json",
33
- "eval-hierarchy.json",
34
- "comparison-index.json",
35
- "corpus-aggregates.json",
36
  ]
37
 
 
 
 
 
38
  const OPTIONAL_CACHE_ROOT_FILES = new Set([
39
  "model-cards-lite.json",
40
  "eval-list-lite.json",
41
  "corpus-aggregates.json",
42
  ])
43
 
44
- const CACHE_DIRECTORIES = ["developers", "evals", "models"]
 
 
 
 
 
45
 
46
  const TOKEN_CASE_MAP = {
47
  ai: "AI",
@@ -89,15 +119,20 @@ function isGitLfsPointer(contents) {
89
  }
90
 
91
  async function writeRemoteFile(relativePath, destinationPath) {
92
- const response = await fetch(`${HF_RESOLVE_BASE}/${relativePath}`)
 
 
 
 
 
93
  if (!response.ok) {
94
  throw new Error(`Failed to download ${relativePath}: ${response.status} ${response.statusText}`)
95
  }
96
 
97
- const body = await response.text()
98
  await fs.mkdir(path.dirname(destinationPath), { recursive: true })
99
- await fs.writeFile(destinationPath, body)
100
- return Buffer.byteLength(body)
101
  }
102
 
103
  async function copySnapshotFile(snapshotRoot, relativePath, destinationPath) {
@@ -339,6 +374,11 @@ async function countFiles(dirPath) {
339
  async function main() {
340
  console.log("Caching HF dataset snapshot for build...\n")
341
 
 
 
 
 
 
342
  await fs.mkdir(cacheDir, { recursive: true })
343
  await fs.mkdir(publicDir, { recursive: true })
344
 
@@ -382,9 +422,11 @@ async function main() {
382
  const peerRanksSuffix = peerRanksResult.source === "remote" ? ", resolved from LFS" : ""
383
  console.log(` βœ“ peer-ranks.json (${(peerRanksResult.size / 1024).toFixed(0)} KB${peerRanksSuffix})`)
384
 
385
- await normalizeCachedModelCardFile(path.join(cacheDir, "model-cards.json"))
386
- await normalizeCachedModelCardFile(path.join(cacheDir, "model-cards-lite.json"))
387
- console.log(" βœ“ normalized model card artifacts")
 
 
388
 
389
  // ── Phase 3: Detail directories ─────────────────────────────────────
390
  console.log("\nPhase 3: Copy detail directories")
 
18
  const root = path.resolve(new URL(import.meta.url).pathname, "..", "..")
19
  const cacheDir = path.join(root, ".cache", "hf-data")
20
  const publicDir = path.join(root, "public")
21
+ const HF_DATASET_REPO = process.env.HF_DATASET_REPO?.trim()
22
+ || "https://huggingface.co/datasets/evaleval/card_backend"
23
  const HF_RESOLVE_BASE = `${HF_DATASET_REPO}/resolve/main`
24
  const execFileAsync = promisify(execFile)
25
 
26
+ // Lean DuckDB mode: when DATA_BACKEND=duckdb, the runtime reads model/eval/
27
+ // developer/summary data exclusively from `duckdb/v1/*.parquet` (see
28
+ // lib/duckdb-data.ts:48,82). The legacy JSON-fallback artifacts
29
+ // (model-cards*, eval-list*, developers*, plus the per-slug detail
30
+ // directories developers/, evals/, models/) become dead weight β€” skipping
31
+ // them avoids OOMing the HF Space on a 2.8 GB JSON snapshot.
32
+ //
33
+ // Always keep:
34
+ // - manifest.json (lib/data-backend.ts:96 β†’ /api/backend-manifest)
35
+ // - eval-hierarchy.json (lib/data-backend.ts:98 β†’ /api/eval-hierarchy)
36
+ // - benchmark-metadata.json (lib/benchmark-metadata.ts:5 β†’ /api/benchmark-metadata)
37
+ // - comparison-index.json (app/api/comparison-index/route.ts:7 β†’ app/models/[id]/page.tsx:157)
38
+ // - corpus-aggregates.json (app/corpus/page.tsx via lib/hf-data:fetchCorpusAggregates)
39
+ // - duckdb/v1/*.parquet (lib/duckdb-data.ts read path)
40
+ // - public/peer-ranks.json (always written outside cacheDir; component fetches HF directly)
41
+ const isDuckDBLean = process.env.DATA_BACKEND?.trim().toLowerCase() === "duckdb"
42
+
43
+ const ESSENTIAL_CACHE_ROOT_FILES = [
44
  "manifest.json",
45
+ "benchmark-metadata.json",
46
+ "eval-hierarchy.json",
47
+ "comparison-index.json",
48
+ "corpus-aggregates.json",
49
+ ]
50
+
51
+ const JSON_FALLBACK_CACHE_ROOT_FILES = [
52
  "model-cards.json",
53
  "model-cards-lite.json",
54
  "eval-list.json",
55
  "eval-list-lite.json",
56
  "developers.json",
 
 
 
 
57
  ]
58
 
59
+ const CACHE_ROOT_FILES = isDuckDBLean
60
+ ? ESSENTIAL_CACHE_ROOT_FILES
61
+ : [...ESSENTIAL_CACHE_ROOT_FILES, ...JSON_FALLBACK_CACHE_ROOT_FILES]
62
+
63
  const OPTIONAL_CACHE_ROOT_FILES = new Set([
64
  "model-cards-lite.json",
65
  "eval-list-lite.json",
66
  "corpus-aggregates.json",
67
  ])
68
 
69
+ const ESSENTIAL_CACHE_DIRECTORIES = ["duckdb"]
70
+ const JSON_FALLBACK_CACHE_DIRECTORIES = ["developers", "evals", "models"]
71
+
72
+ const CACHE_DIRECTORIES = isDuckDBLean
73
+ ? ESSENTIAL_CACHE_DIRECTORIES
74
+ : [...JSON_FALLBACK_CACHE_DIRECTORIES, ...ESSENTIAL_CACHE_DIRECTORIES]
75
 
76
  const TOKEN_CASE_MAP = {
77
  ai: "AI",
 
119
  }
120
 
121
  async function writeRemoteFile(relativePath, destinationPath) {
122
+ const headers = {}
123
+ const hfToken = process.env.HF_TOKEN?.trim()
124
+ if (hfToken) {
125
+ headers.Authorization = `Bearer ${hfToken}`
126
+ }
127
+ const response = await fetch(`${HF_RESOLVE_BASE}/${relativePath}`, { headers })
128
  if (!response.ok) {
129
  throw new Error(`Failed to download ${relativePath}: ${response.status} ${response.statusText}`)
130
  }
131
 
132
+ const buffer = Buffer.from(await response.arrayBuffer())
133
  await fs.mkdir(path.dirname(destinationPath), { recursive: true })
134
+ await fs.writeFile(destinationPath, buffer)
135
+ return buffer.length
136
  }
137
 
138
  async function copySnapshotFile(snapshotRoot, relativePath, destinationPath) {
 
374
  async function main() {
375
  console.log("Caching HF dataset snapshot for build...\n")
376
 
377
+ if (isDuckDBLean) {
378
+ console.log("Lean DuckDB cache mode: skipping JSON-fallback artifacts (model-cards*, eval-list*, developers*, developers/, evals/, models/)")
379
+ console.log("")
380
+ }
381
+
382
  await fs.mkdir(cacheDir, { recursive: true })
383
  await fs.mkdir(publicDir, { recursive: true })
384
 
 
422
  const peerRanksSuffix = peerRanksResult.source === "remote" ? ", resolved from LFS" : ""
423
  console.log(` βœ“ peer-ranks.json (${(peerRanksResult.size / 1024).toFixed(0)} KB${peerRanksSuffix})`)
424
 
425
+ if (!isDuckDBLean) {
426
+ await normalizeCachedModelCardFile(path.join(cacheDir, "model-cards.json"))
427
+ await normalizeCachedModelCardFile(path.join(cacheDir, "model-cards-lite.json"))
428
+ console.log(" βœ“ normalized model card artifacts")
429
+ }
430
 
431
  // ── Phase 3: Detail directories ─────────────────────────────────────
432
  console.log("\nPhase 3: Copy detail directories")