mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-28 07:32:52 +00:00
64 lines
3.6 KiB
JavaScript
64 lines
3.6 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Kai's results, as the research API holds them.
|
|
*
|
|
* node scripts/kai.mjs [api base URL]
|
|
*
|
|
* Saves the runs of `GET /v1/research/runs?org=hanzo` whose system the pages
|
|
* compare (lib/kai.ts WHO) as lib/data/benchmarks-kai.json: the snapshot the
|
|
* pages render before their own fetch of the same address returns, and merge
|
|
* with it after. `bench post` in hanzo-inc/kai writes those runs, one per
|
|
* system, revision and benchmark. The base defaults to api.hanzo.ai. The read
|
|
* is anonymous, as the browser's is, so the snapshot holds only public runs.
|
|
*
|
|
* Part of `prebuild`, so every build ships the latest validated runs: canonical,
|
|
* public, and not flagged inconsistent by the API. The committed snapshot is the
|
|
* frozen fallback. It is kept, and the build goes on, when the API cannot be
|
|
* reached, answers with an error, answers with fewer runs of Kai or Jev than
|
|
* the snapshot already holds — a read that loses runs is a broken read, not news
|
|
* — or answers with a revision whose release gate against Jev does not pass
|
|
* (`derive`'s `sota`): such a snapshot is not one the pages and their gates can
|
|
* read, so the build goes on with the committed file, byte for byte
|
|
* (e2e/unit/snapshot.spec.ts).
|
|
*/
|
|
import { readFileSync, writeFileSync } from 'node:fs'
|
|
|
|
const FILE = new URL('../lib/data/benchmarks-kai.json', import.meta.url)
|
|
const keep = (why) => {
|
|
console.log(`kai: kept the frozen snapshot (${why})`)
|
|
process.exit(0)
|
|
}
|
|
|
|
try {
|
|
const { RUNS, WHO, derive } = await import('../lib/kai.ts')
|
|
const base = process.argv[2]?.replace(/\/$/, '')
|
|
const url = base ? RUNS.replace(new URL(RUNS).origin, base) : RUNS
|
|
const res = await fetch(url, { signal: AbortSignal.timeout(20_000) })
|
|
if (!res.ok) keep(`${url}: ${res.status}`)
|
|
const body = await res.json()
|
|
const kai = derive(body.data ?? [])
|
|
if (!kai) keep(`${url}: no Kai run on the harness`)
|
|
if (!kai.sota) keep(`${url}: ${kai.run}: gate does not pass`)
|
|
|
|
// The answer as the API gave it, one run a line, so a diff names the runs a post changed.
|
|
// Only what the pages compare: the snapshot ships to the browser, which merges it with the live
|
|
// answer, so a run of another system, or one whose benchmark or metric names one, stays out.
|
|
const { data: all, ...rest } = body
|
|
// A gate (`gate.<system>`) and a tally (`beats.<system>`) name the system they compare with, so they name it
|
|
// whether or not the answer still lists that system's own runs.
|
|
const others = new Set(all.map((r) => r.system).filter((s) => !WHO.includes(s)))
|
|
const against = (part, i, parts) => i > 0 && ['gate', 'beats'].includes(parts[i - 1]) && !WHO.includes(part)
|
|
const names = (key) => key.split('.').some((part, i, parts) => others.has(part) || against(part, i, parts))
|
|
const valid = (r) => r.canonical !== false && (r.visibility ?? 'public') === 'public' && r.completion !== 'inconsistent'
|
|
const data = all.filter((r) => WHO.includes(r.system) && valid(r) && !names(r.benchmark) && !(r.measures ?? []).some((m) => names(m.metric)))
|
|
|
|
const held = JSON.parse(readFileSync(FILE, 'utf8')).data ?? []
|
|
if (data.length < held.length) keep(`${url}: ${data.length} runs against the snapshot's ${held.length}`)
|
|
|
|
const tail = Object.entries(rest).map(([k, v]) => `${JSON.stringify(k)}: ${JSON.stringify(v)}`)
|
|
writeFileSync(FILE, `{\n"data": [\n${data.map((r) => JSON.stringify(r)).join(',\n')}\n],\n${tail.join(',\n')}\n}\n`)
|
|
console.log(`kai: ${kai.run}: ${data.length} runs (${data.length - held.length >= 0 ? '+' : ''}${data.length - held.length}), ${kai.claims.length} claims; gate passes`)
|
|
} catch (e) {
|
|
keep(e instanceof Error ? e.message : String(e))
|
|
}
|