omp-llm-role 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -11
- package/agents/designer.md +4 -3
- package/docs/dev/README.md +44 -7
- package/docs/dev/agent-authoring.md +59 -1
- package/docs/dev/architecture.md +84 -27
- package/docs/dev/ci.md +152 -0
- package/docs/dev/current-state.md +327 -24
- package/docs/dev/data-sources.md +202 -38
- package/docs/dev/explorer.md +157 -46
- package/docs/dev/quirks.md +45 -4
- package/docs/dev/releasing.md +129 -17
- package/docs/dev/scoring.md +789 -28
- package/docs/dev/testing.md +206 -0
- package/docs/dev/writes-and-state.md +176 -28
- package/docs/llm-role-rankings.md +141 -140
- package/package.json +754 -80
- package/skills/omp-llm-role-create-agent/SKILL.md +7 -1
- package/src/agent-architect.ts +148 -19
- package/src/agent-create.ts +800 -40
- package/src/agent-file.ts +2 -5
- package/src/architect-provenance.ts +16 -0
- package/src/availability.ts +104 -6
- package/src/benchmark-author.ts +9 -4
- package/src/benchmark-sources.ts +283 -18
- package/src/cli/create-role.ts +29 -1
- package/src/cli/llm-role-rank.ts +40 -1
- package/src/config-edit.ts +207 -80
- package/src/engine.ts +409 -46
- package/src/error-report.ts +562 -0
- package/src/explorer/boot.ts +36 -24
- package/src/explorer/explain.ts +110 -13
- package/src/explorer/scopes.ts +110 -0
- package/src/explorer/server.ts +112 -32
- package/src/extension.ts +407 -34
- package/src/features.ts +103 -0
- package/src/project-registry.ts +65 -0
- package/src/project-setup.ts +382 -0
- package/src/prompts/agent-creation-architect.md +2 -0
- package/src/prompts/project-profile-architect.md +33 -0
- package/src/prompts/project-profile-user.md +8 -0
- package/src/role-archetypes.ts +12 -2
- package/src/role-settings.ts +22 -0
- package/src/settings.ts +205 -24
- package/src/state.ts +1 -1
- package/src/updater.ts +150 -31
- package/web/app.js +411 -12
- package/web/index.html +1 -0
- package/web/style.css +44 -1
- package/docs/dev/spec.md +0 -633
package/docs/dev/data-sources.md
CHANGED
|
@@ -5,7 +5,6 @@ llm-stats id, and where it is cached. All fetching lives in `src/engine.ts`
|
|
|
5
5
|
(plus `src/availability.ts` for the key/catalog/probe surfaces).
|
|
6
6
|
|
|
7
7
|
- Module map and pipeline: [`architecture.md`](architecture.md).
|
|
8
|
-
- Normative behavior contract: [`spec.md`](spec.md).
|
|
9
8
|
|
|
10
9
|
## llm-stats.com — quality
|
|
11
10
|
|
|
@@ -22,12 +21,27 @@ payload; there is no public JSON API.
|
|
|
22
21
|
`context`, `release_date`, `multimodal`, `license`, `input_price`/`output_price`
|
|
23
22
|
(unused), `throughput`/`latency` (unused), the `index_*` scores (0–100:
|
|
24
23
|
general, reasoning, math, code, agents, search, vision, tool_calling,
|
|
25
|
-
long_context) and the benchmark
|
|
26
|
-
`
|
|
27
|
-
`mrcr_v2_score`, `terminal_bench_score`,
|
|
24
|
+
long_context, communication, finance, healthcare, legal) and the benchmark
|
|
25
|
+
scores (0–1: `gpqa_score`, `aime_2025_score`, `swe_bench_verified_score`,
|
|
26
|
+
`arc_agi_v2_score`, `mrcr_v2_score`, `terminal_bench_score`,
|
|
27
|
+
`tau_bench_retail_score`, plus `hle_score`, `simpleqa_score`, `mmmu_score`,
|
|
28
|
+
`mmmu_pro_score`, `mmmlu_score`, `browsecomp_score`, `swe_bench_pro_score`,
|
|
29
|
+
`mcp_atlas_score`, `apex_agents_score`, `osworld_score`, `scicode_score`,
|
|
30
|
+
`screenspot_pro_score`, `charxiv_r_score`, `frontiermath_score`,
|
|
31
|
+
`toolathlon_score`, `coding_arena_score`). `buildModels` maps the nine
|
|
32
|
+
short-key indices plus the four new `index_*` fields (communication, finance,
|
|
33
|
+
healthcare, legal) and the seven short-key benchmark scores plus the fifteen
|
|
34
|
+
new `*_score` benchmarks — 13 indices and 22 benchmarks in all. The new
|
|
35
|
+
metrics keep the **raw leaderboard field name as the metric key**
|
|
36
|
+
(`index_communication`, `simpleqa_score`, …), unlike the original nine/seven
|
|
37
|
+
short keys. `coding_arena_score`, `latency` and `context` are fetched but
|
|
38
|
+
discarded (see the research note on the agentic-engineering benchmarks for the
|
|
39
|
+
coverage/collinearity of the unmapped ones).
|
|
28
40
|
- **Build**: `buildModels(rows)` maps each row to a `Model`; `metrics` carries
|
|
29
41
|
the index/benchmark values, with `price`/`throughput`/`website`/`writing`
|
|
30
|
-
left `null` for later enrichment.
|
|
42
|
+
left `null` for later enrichment. The row's `release_date` is carried onto
|
|
43
|
+
`Model.releaseDate` (null when absent) and used by the focus-metric freshness
|
|
44
|
+
axis (scoring.md, the nine-axis gate).
|
|
31
45
|
- **Cache**: `cache/llm-stats-fetched-rankings.json` —
|
|
32
46
|
`{ fetchedAt, source, modelCount, rankings[] }` (pretty-printed; each row
|
|
33
47
|
gains a `rank` = array position). Fresh while `fetchedAt` is the current UTC
|
|
@@ -48,14 +62,16 @@ Two payloads, both joined to llm-stats by slug suffix: the llm-stats `model_id`
|
|
|
48
62
|
- **Shape**: `data.endpoint_perf[endpointId]` → `{ p50_throughput (output tok/s),
|
|
49
63
|
p50_latency (ms) }` over the last **30 minutes** of routed traffic;
|
|
50
64
|
`data.models[]` rows link a slug to one endpoint id — the route currently
|
|
51
|
-
getting the traffic — each carrying `pricing.prompt`/`pricing.completion`
|
|
52
|
-
(USD/token strings, discounts already applied). The
|
|
53
|
-
`analytics`, `benchmarks`, `benchmark_ranges`, `categories`,
|
|
65
|
+
getting the traffic — each carrying `pricing.prompt`/`pricing.completion` and
|
|
66
|
+
`pricing.input_cache_read` (USD/token strings, discounts already applied). The
|
|
67
|
+
payload also carries `analytics`, `benchmarks`, `benchmark_ranges`, `categories`,
|
|
54
68
|
`modality_counts`.
|
|
55
69
|
- **Parse**: `parseFindData(v)` narrows `find` (models, `endpoint_perf`,
|
|
56
|
-
`endpoint_price` blended to $/M at 3:1 in:out
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
`endpoint_price` blended to $/M at 3:1 in:out, the parallel
|
|
71
|
+
`endpoint_weight_price` input-only $/M map — the router's sort key — and the
|
|
72
|
+
`endpoint_cache_read_price` cache-read input-only $/M map; see "The
|
|
73
|
+
1/price² blend") and keeps the full `data` object verbatim for the cache; it
|
|
74
|
+
also extracts the Design Arena mirror (`extractDesignElo`, see below).
|
|
59
75
|
- **Cache**: `cache/openrouter-fetched-data.json` —
|
|
60
76
|
`{ fetchedAt, source, modelCount, data }` where `data` is the verbatim
|
|
61
77
|
`find?fmt=cards` response data (sorted keys). Throughput/price maps are
|
|
@@ -65,35 +81,75 @@ Two payloads, both joined to llm-stats by slug suffix: the llm-stats `model_id`
|
|
|
65
81
|
|
|
66
82
|
- **URL**: `https://openrouter.ai/<slug>` (RSC flight payload), fetched only for
|
|
67
83
|
slugs that match a leaderboard model (~150 of ~540).
|
|
68
|
-
- **Shape**: every provider route of a model — pricing, service tier, status
|
|
69
|
-
routed-traffic p50 stats
|
|
70
|
-
one copy without stats; records merge by
|
|
71
|
-
winning). `parseModelPage(html)` narrows
|
|
72
|
-
`OpenRouterEndpointRecord` (`id`, `providerSlug`, `serviceTier`,
|
|
73
|
-
`free`, `variant`, `price`, `
|
|
84
|
+
- **Shape**: every provider route of a model — pricing, service tier, status,
|
|
85
|
+
routed-traffic p50 stats and the per-endpoint capability ceilings — dehydrated
|
|
86
|
+
as React-Query state (sometimes twice, one copy without stats; records merge by
|
|
87
|
+
endpoint id, the stats-carrying copy winning). `parseModelPage(html)` narrows
|
|
88
|
+
each row to `OpenRouterEndpointRecord` (`id`, `providerSlug`, `serviceTier`,
|
|
89
|
+
`status`, `free`, `variant`, `price`, `weightPrice`, `cacheReadPrice`
|
|
90
|
+
(endpoint `pricing.input_cache_read`; `null` when absent), `tput`, `latency`,
|
|
91
|
+
`contextLength` (endpoint `context_length`), `maxCompletionTokens` (endpoint
|
|
92
|
+
`max_completion_tokens`) and `supportsTools` (`supported_parameters` contains
|
|
93
|
+
`tools`)). The three capability fields are `null` when the field is absent —
|
|
94
|
+
the role endpoint filters keep a `null` (missing data is not a capability
|
|
95
|
+
failure).
|
|
74
96
|
- **Fetch**: `fetchEndpointPages(slugs)` with an 8-worker pool
|
|
75
97
|
(`OPENROUTER_PAGE_CONCURRENCY`), one retry per page, permanent 404/410 gives
|
|
76
98
|
up. A page that fails is absent and that model keeps the single-route
|
|
77
99
|
fallback.
|
|
78
100
|
- **Cache**: `cache/openrouter-endpoints-fetched-data.json` —
|
|
79
101
|
`{ fetchedAt, source, slugCount, slugs }` where `slugs` maps each fetched
|
|
80
|
-
model slug to its narrowed per-provider route records.
|
|
102
|
+
model slug to its narrowed per-provider route records. `readEndpointsCache`
|
|
103
|
+
rejects a cache whose records lack `weightPrice` (the pre-#21 shape),
|
|
104
|
+
`contextLength` (the pre-#18 shape) **or** `cacheReadPrice` (the pre-#30
|
|
105
|
+
shape) and refetches, rather than silently dropping every route from the
|
|
106
|
+
blend, treating every ceiling as unstated, or leaving a role's `cacheHitRate`
|
|
107
|
+
inert (a missing cache-read price reads as the full input price).
|
|
108
|
+
- **Per-model routes**: `buildOpenRouterEnrichment` carries the eligible
|
|
109
|
+
standard-tier pool on `OrEnrichment.routes`, and `applyOpenRouterData` sets it
|
|
110
|
+
on `Model.routes` — the pool the role endpoint filters gate. The
|
|
111
|
+
find-route fallback carries the same field (its capability fields are `null`,
|
|
112
|
+
since the find payload has no ceilings).
|
|
81
113
|
|
|
82
114
|
### The 1/price² blend
|
|
83
115
|
|
|
84
116
|
`buildOpenRouterEnrichment(data, pages)` computes the expected price/throughput
|
|
85
117
|
of one request under OpenRouter's default price-based load balancing (a request
|
|
86
118
|
goes to ONE provider, picked among the stable standard-tier routes with
|
|
87
|
-
probability proportional to `1/price²`)
|
|
119
|
+
probability proportional to `1/price²`). The weight basis is the **input
|
|
120
|
+
(prompt) price** — the router's sort key — while the reported price is the
|
|
121
|
+
**billed 3:1 in:out blend** under that distribution.
|
|
88
122
|
|
|
89
123
|
- **Pool**: the page's per-provider routes, plus any find-row endpoint the page
|
|
90
124
|
does not list (the page is normally a superset).
|
|
91
125
|
- **Eligible**: standard tier (`serviceTier === null`), `status === 0`, not
|
|
92
|
-
`:free`, `price > 0`, not `:batch`. flex/priority tiers are
|
|
93
|
-
`:floor`/`:nitro` variants make them eligible); degraded
|
|
94
|
-
are fallbacks and drop out.
|
|
95
|
-
- **
|
|
96
|
-
|
|
126
|
+
`:free`, `price > 0`, `weightPrice > 0`, not `:batch`. flex/priority tiers are
|
|
127
|
+
excluded (only the `:floor`/`:nitro` variants make them eligible); degraded
|
|
128
|
+
routes (`status ≠ 0`) are fallbacks and drop out.
|
|
129
|
+
- **Weight basis**: the input-only $/M (`pricing.prompt * 1e6`, carried as
|
|
130
|
+
`weightPrice` on each route and `endpoint_weight_price` in the find payload).
|
|
131
|
+
OpenRouter's docs say only "weighted by inverse square of the price" and never
|
|
132
|
+
define the basis; the input price is the measured one. Tarun Chitra (Robot
|
|
133
|
+
Ventures), *Caching Cheaters on OpenRouter* (2026-08-14,
|
|
134
|
+
https://robvc.com/research/caching-cheaters): 64/64 informative provider
|
|
135
|
+
splits picked the cheapest-**input** provider (including menus where that
|
|
136
|
+
provider quoted the most expensive output price), output price carries ≲6
|
|
137
|
+
cents per dollar of input, and the inverse-square exponent recovered from
|
|
138
|
+
1,648 choices is r = 1.968 (95% CI [1.856, 2.098]); cached-token price adds no
|
|
139
|
+
measurable predictive power. The authors' caveat: behaviour-measured, not
|
|
140
|
+
source-read.
|
|
141
|
+
- **Blend**: `price = Σ(1/p_in²)·p_billed / Σ(1/p_in²)` — the w-weighted mean of
|
|
142
|
+
the billed 3:1 blend (what a caller pays), weighted by the input price;
|
|
143
|
+
`throughput = Σ(1/p_in²)·t / Σ(1/p_in²)` renormalized over the routes that
|
|
144
|
+
have p50 data; latency likewise. A route with no input price drops from the
|
|
145
|
+
pool (`1/p²` blows up at 0, and the router cannot score a route without one).
|
|
146
|
+
- **Cache-read pricing**: a role may declare `cacheHitRate` (0–1, opt-in), and
|
|
147
|
+
`blendRoutePool(routes, cacheHitRate)` then blends each route's
|
|
148
|
+
`cacheReadPrice` (the endpoint's `pricing.input_cache_read`) into its billed
|
|
149
|
+
price, `billed = price + 3·(h·cacheRead + (1−h)·input − input)/4`, **without**
|
|
150
|
+
changing the `1/p_in²` weight basis (the router still sorts on the listed input
|
|
151
|
+
price). A route with no cache-read price keeps its full input price; `h = 0`
|
|
152
|
+
is byte-identical to the uncached blend. See scoring.md, *Cache-read pricing*.
|
|
97
153
|
- **Fallback** (no eligible route carries throughput): throughput = highest-p50
|
|
98
154
|
variant (`:free` included — it rescues otherwise-unranked models), price =
|
|
99
155
|
cheapest billed route (a $0 free tier never sets the price).
|
|
@@ -101,6 +157,51 @@ probability proportional to `1/price²`):
|
|
|
101
157
|
`m.throughput`, `m.metrics.price`/`throughput`, and `m.thinking`
|
|
102
158
|
(`supports_reasoning`).
|
|
103
159
|
|
|
160
|
+
A role with a `providerPin` does **not** use this blend: it prices the
|
|
161
|
+
model's matching route directly — the route's billed 3:1 price and its p50
|
|
162
|
+
throughput (scoring.md, *Route-aware pricing*). The blend is the unpinned
|
|
163
|
+
default.
|
|
164
|
+
|
|
165
|
+
## OpenRouter — key metadata (tier gate)
|
|
166
|
+
|
|
167
|
+
Bearer-authenticated GETs with the omp-resolved key decide which variant tier the
|
|
168
|
+
run may use:
|
|
169
|
+
|
|
170
|
+
- `GET https://openrouter.ai/api/v1/key` → `is_free_tier`, `limit_remaining`,
|
|
171
|
+
`limit`, `free_model_daily_requests.remaining`.
|
|
172
|
+
- `GET https://openrouter.ai/api/v1/credits` → `total_credits`, `total_usage`.
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
billedUsable = !is_free_tier && limit_remaining > 0 && (total_credits - total_usage) > 0
|
|
176
|
+
freeUsable = free_model_daily_requests.remaining > 0
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
`tierGate` (`src/availability.ts`) maps these to `"billed" | "free" | "none"`:
|
|
180
|
+
billed → billed variants only (exclude `:free`, `:batch`); else free → `:free`
|
|
181
|
+
variants only (exclude `:batch`); else `"none"` aborts the run. The key endpoint
|
|
182
|
+
carries **no** model/provider restriction field — the account's allowed-providers
|
|
183
|
+
whitelist is invisible to it (see the keyed catalog below and the probe in
|
|
184
|
+
[`architecture.md`](architecture.md)).
|
|
185
|
+
|
|
186
|
+
## OpenRouter — keyed catalog (availability)
|
|
187
|
+
|
|
188
|
+
The account setting **"Filter the model catalog for API keys"** (openrouter.ai/settings)
|
|
189
|
+
makes the Bearer-authenticated catalog a per-key allowlist.
|
|
190
|
+
|
|
191
|
+
- **URLs**: `GET https://openrouter.ai/api/v1/models` twice — once unauthenticated
|
|
192
|
+
(the public catalog) and once with `Authorization: Bearer <key>` (the keyed catalog).
|
|
193
|
+
`fetchKeyAvailability` (`src/availability.ts`) issues both in parallel.
|
|
194
|
+
- **Signal**: set membership only — the response carries no per-model access flag. Both
|
|
195
|
+
id lists are normalized with `rankingIdOf` (suffix after the last `/`, minus `:free`,
|
|
196
|
+
minus a trailing `-latest`), the same identity space as the engine's `Model.id`, so
|
|
197
|
+
aliases never produce a false "blocked". The keyed list being a non-empty **proper
|
|
198
|
+
subset** of the public one means the setting is on (`active`); equality is `no-filter`;
|
|
199
|
+
an empty list or any transport/status/shape failure is `unavailable`.
|
|
200
|
+
- **Consumers**: the updater fetches it **once per run** and shares it across roles; the
|
|
201
|
+
explorer fetches it on boot and on `POST /api/refresh`. It is **not cached to disk** —
|
|
202
|
+
every consumer re-fetches, and `fetchKeyAvailability` **never throws** (a failure
|
|
203
|
+
degrades to `unavailable` with empty sets, so the probe walk / `unknown` marks stand).
|
|
204
|
+
|
|
104
205
|
## Design Arena — design quality
|
|
105
206
|
|
|
106
207
|
Two routes, never averaged (same Elo family; mean diff −1.0 website … −5.1 svg,
|
|
@@ -191,25 +292,88 @@ mapping to a `KNOWN_METRICS` key. A source whose data the engine already fetches
|
|
|
191
292
|
### The generic llm-stats benchmark
|
|
192
293
|
|
|
193
294
|
`GET https://api.zeroeval.com/leaderboard/benchmarks/<id>` returns
|
|
194
|
-
`{ benchmark_id, benchmark_name, max_score, entries[] }`; each
|
|
195
|
-
`model_id` (the bare llm-stats id, so the join is **direct**) and
|
|
295
|
+
`{ benchmark_id, benchmark_name, max_score, total_models, entries[] }`; each
|
|
296
|
+
entry carries `model_id` (the bare llm-stats id, so the join is **direct**) and
|
|
196
297
|
`normalized_score` (0-1). Any `llm-stats.com/benchmarks/<id>` link (or a bare
|
|
197
298
|
benchmark id) resolves to a source whose metric is `bench:<normalized-id>`, cache
|
|
198
299
|
file `bench-<normalized-id>-fetched-data.json`, transform `identity`, and a
|
|
199
300
|
capability fill of 0.195. The raw id is preserved for the fetch URL (the real id
|
|
200
301
|
`alpacaeval-2.0` normalizes to the metric `bench:alpacaeval-2_0`), so the source
|
|
201
302
|
is persisted as a declaration (below) — the metric key alone cannot reconstruct
|
|
202
|
-
the raw id.
|
|
303
|
+
the raw id. `catalogBenchmarkDeclaration` builds that declaration for a dotted
|
|
304
|
+
catalog id at discovery/authoring time, carrying the raw id in `fetch.url`.
|
|
305
|
+
|
|
306
|
+
Each entry also carries the trust flags `self_reported` and `verified` (both
|
|
307
|
+
booleans), the `multimodal` flag, the org fields `organization_id`/
|
|
308
|
+
`provider_id`, and a **second, independent** set of the price/throughput/context
|
|
309
|
+
quantities: `input_cost_per_million`, `output_cost_per_million`, `speed_rps`
|
|
310
|
+
(requests/s) and `context_window` (tokens). `parseBenchmarkPayloadMeta(payload)`
|
|
311
|
+
reads them independently of `source.parse` (a declared/writing source reads no
|
|
312
|
+
entry flags) and returns
|
|
313
|
+
`{ trust: { selfReported, verified, covered }, modality: { multimodal, covered },
|
|
314
|
+
provenance: { dominantOrg, dominantShare, orgs, covered }, crossSource }` — the
|
|
315
|
+
trust
|
|
316
|
+
`covered` is the count of entries carrying a boolean `self_reported` (the share
|
|
317
|
+
denominator), `selfReported` the count of those whose `self_reported` is `true`,
|
|
318
|
+
and `verified` the count of those whose `verified` is `true`; the modality
|
|
319
|
+
`covered` is the count of entries carrying a boolean `multimodal` and `multimodal`
|
|
320
|
+
the count of those that are `true`; the provenance `covered` is the count of
|
|
321
|
+
entries carrying a non-empty org string (each row's `organization_id`, falling
|
|
322
|
+
back to `provider_id`), `orgs` the distinct org count, and `dominantOrg`/
|
|
323
|
+
`dominantShare` the most frequent org and its count / `covered`; `crossSource` is
|
|
324
|
+
a map keyed by the entry's `model_id` of `{ input, output, speed, context }`
|
|
325
|
+
(each a finite number, else `null`), `null` when no entry carried any of the four
|
|
326
|
+
(the four summaries have independent denominators)
|
|
327
|
+
(measured 2026-10-07: `verified` is uniformly `false`; `self_reported` varies —
|
|
328
|
+
gpqa 19/20, deepswe-1.1 14/20, terminal-bench-4.0 10/20, automationbench-aa 0/1).
|
|
329
|
+
`trust`/`modality`/`provenance`/`crossSource` are each `null` when no entry
|
|
330
|
+
carried the respective field, and the whole meta is `null` when the payload has
|
|
331
|
+
no llm-stats entries shape.
|
|
332
|
+
`BenchmarkPayload` carries it as `meta`, `BenchmarkScores` as `meta`, and the
|
|
333
|
+
scores cache persists it. The scores-cache reader carries the same shape guard as
|
|
334
|
+
the catalog reader: a cache lacking the `meta` key (written before the
|
|
335
|
+
payload-meta fields landed) is rejected and refetched, so the four
|
|
336
|
+
payload-derived focus axes never go silently inert; `meta: null` (a
|
|
337
|
+
declared/writing payload) is still accepted. The
|
|
338
|
+
focus-metric trust, modality, provenance and cross-source axes (scoring.md)
|
|
339
|
+
consume it via `cachedSourceInfo`.
|
|
340
|
+
|
|
341
|
+
The endpoint caps `entries` at `BENCHMARK_ENTRY_CAP` (20) regardless of
|
|
342
|
+
`limit`/`offset`/`page`/`per_page`, so a generic metric can never load more and
|
|
343
|
+
no pagination loop helps. `total_models` still reports the full set, so
|
|
344
|
+
`loadBenchmarkScores` returns `loaded` (the entries actually read) alongside
|
|
345
|
+
`total`; `loaded < total` marks a capped load (annotated to stderr) and the
|
|
346
|
+
post-fetch coverage count is the loadable `loaded`, never the catalog's
|
|
347
|
+
`model_count`.
|
|
203
348
|
|
|
204
349
|
### The benchmark catalog (discovery)
|
|
205
350
|
|
|
206
351
|
`GET https://api.zeroeval.com/leaderboard/benchmarks` (the same backend, no
|
|
207
352
|
`/<id>`) returns the full catalog as a top-level JSON array of ~745 rows:
|
|
208
353
|
`{ benchmark_id, name, description, categories[], modality, max_score, verified,
|
|
209
|
-
model_count, is_community
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
`
|
|
354
|
+
model_count, is_community, updated_at, version_count, latest_version_row_count,
|
|
355
|
+
star_count, dataset_id, dataset_org_id, dataset_slug }`. `parseBenchmarkCatalog`
|
|
356
|
+
narrows it to
|
|
357
|
+
`{ id, name, description, categories, modelCount, isCommunity, modality,
|
|
358
|
+
updatedAt, versionCount, latestVersionRowCount, starCount, datasetId,
|
|
359
|
+
datasetOrgId, datasetSlug }` (the
|
|
360
|
+
row's `is_community`, defaulting `false` when absent/non-boolean — consumed by
|
|
361
|
+
the trust axis as `community`, 20/745 true — the row's `modality` as an open
|
|
362
|
+
string, `null` when absent/non-string, so an unknown value survives, the
|
|
363
|
+
maintenance fields `updated_at`/`version_count`/`latest_version_row_count`/
|
|
364
|
+
`star_count`, each `null` when absent, non-string (for `updated_at`) or
|
|
365
|
+
non-finite (for the three counts), and the provenance fields `dataset_id`/
|
|
366
|
+
`dataset_org_id`/`dataset_slug`, each `null` when absent, non-string or empty —
|
|
367
|
+
`dataset_org_id` is the benchmark's owning organisation, the provenance axis's
|
|
368
|
+
owner, with `dataset_slug` as its fallback);
|
|
369
|
+
`loadBenchmarkCatalog` follows the same
|
|
370
|
+
daily cache chain (cache file `benchmark-catalog-fetched-data.json`). The catalog
|
|
371
|
+
cache reader carries a shape guard mirroring `readEndpointsCache`: a cache whose
|
|
372
|
+
sampled entry lacks `isCommunity`, `modality`, any of the four maintenance
|
|
373
|
+
fields or any of the three provenance fields (written before the field landed) is
|
|
374
|
+
rejected and refetched, so a stale
|
|
375
|
+
cache never reports `undefined`; an empty
|
|
376
|
+
catalog is still `null`. `/create-agent` uses it to discover the
|
|
213
377
|
benchmarks relevant to a purpose: `discoverBenchmarks` filters by coverage
|
|
214
378
|
(`modelCount >= 3`), ranks the survivors by IDF-weighted lexical overlap with the
|
|
215
379
|
purpose (a category that names the purpose's skill is the strongest signal), caps
|
|
@@ -282,10 +446,10 @@ fresh checkout needs no setup.
|
|
|
282
446
|
| `cache/openrouter-fetched-data.json` | `{ fetchedAt, source, modelCount, data }` | non-fatal (affected models unranked) |
|
|
283
447
|
| `cache/openrouter-endpoints-fetched-data.json` | `{ fetchedAt, source, slugCount, slugs }` | non-fatal (single-route fallback) |
|
|
284
448
|
| `cache/designarena-fetched-data.json` | `{ fetchedAt, source, categories }` | non-fatal (OR mirror alone) |
|
|
285
|
-
| `cache/writing-fetched-data.json` | `{ fetchedAt, source, scores }` | non-fatal (`writing` unfilled) |
|
|
286
|
-
| `cache/bench-<id>-fetched-data.json` | `{ fetchedAt, source, scores }` | non-fatal (the external metric is unfilled) |
|
|
287
|
-
| `cache/benchmark-catalog-fetched-data.json` | `{ fetchedAt, source, entries }` | non-fatal (discovery skipped) |
|
|
288
|
-
| `cache/<declared-id>-fetched-data.json` | `{ fetchedAt, source, scores }` | non-fatal (the external metric is unfilled) |
|
|
449
|
+
| `cache/writing-fetched-data.json` | `{ fetchedAt, source, scores, total, meta }` | non-fatal (`writing` unfilled) |
|
|
450
|
+
| `cache/bench-<id>-fetched-data.json` | `{ fetchedAt, source, scores, total, meta }` | non-fatal (the external metric is unfilled) |
|
|
451
|
+
| `cache/benchmark-catalog-fetched-data.json` | `{ fetchedAt, source, entries }` (each entry carries `isCommunity`, `modality`, the maintenance fields `updatedAt`/`versionCount`/`latestVersionRowCount`/`starCount` and the provenance fields `datasetId`/`datasetOrgId`/`datasetSlug`) | non-fatal (discovery skipped) |
|
|
452
|
+
| `cache/<declared-id>-fetched-data.json` | `{ fetchedAt, source, scores, total, meta }` | non-fatal (the external metric is unfilled) |
|
|
289
453
|
|
|
290
454
|
The last two are the registry's generic scores cache (`loadBenchmarkScores`),
|
|
291
455
|
shared by the generic llm-stats benchmark and every declared source.
|
|
@@ -324,9 +488,9 @@ the source does not cover.
|
|
|
324
488
|
the routes that have p50 data, so a stable route with no recent requests
|
|
325
489
|
contributes price weight but no throughput. A degraded cheapest route
|
|
326
490
|
(`status ≠ 0`) drops out entirely until it recovers, and the price can jump.
|
|
327
|
-
The blend weights by the
|
|
328
|
-
request counts (which aggregate ALL
|
|
329
|
-
`sort` users included).
|
|
491
|
+
The blend weights by the `1/p_in²` formula (input price, see "The 1/price²
|
|
492
|
+
blend"), not by the page's observed request counts (which aggregate ALL
|
|
493
|
+
OpenRouter traffic, `:nitro`/`:floor` and `sort` users included).
|
|
330
494
|
- **The find route and the page record for the same endpoint id can disagree**
|
|
331
495
|
by a few percent (price revisions, status flips, p50 windows); the page copy
|
|
332
496
|
wins the pool merge, the find row joins only when the page does not list its
|