@wendellresearch-ai/benchwarmers 0.1.1 → 0.2.1
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/AGENTS.md +147 -147
- package/BENCHMARKS.md +262 -262
- package/GATEWAY.md +272 -271
- package/NOTICE +28 -28
- package/PRIVACY.md +46 -46
- package/README.md +368 -275
- package/SECURITY.md +83 -83
- package/TERMS.md +22 -22
- package/USAGE.md +170 -155
- package/VERSION +1 -1
- package/bin/benchwarmers.js +16 -72
- package/cli.py +666 -0
- package/examples/config/gateway.json +5 -5
- package/examples/config/model-roles.json +11 -11
- package/gateway.py +755 -712
- package/launcher.py +120 -0
- package/mcp_server.py +266 -0
- package/metrics/alerts.py +116 -116
- package/metrics/aliases.py +41 -41
- package/metrics/bench_collections.py +141 -141
- package/metrics/catalog.py +295 -295
- package/metrics/client.py +394 -373
- package/metrics/cliproxy.py +191 -191
- package/metrics/connect.py +691 -691
- package/metrics/cost.py +152 -152
- package/metrics/decide.py +227 -227
- package/metrics/discover.py +318 -318
- package/metrics/endpoints.py +436 -436
- package/metrics/guard.py +617 -592
- package/metrics/learn.py +221 -221
- package/metrics/litellm_hub.py +206 -206
- package/metrics/model_roles.py +84 -84
- package/metrics/offload.py +166 -166
- package/metrics/owui.py +205 -205
- package/metrics/paths.py +60 -60
- package/metrics/route.py +579 -574
- package/metrics/scheduler.py +275 -275
- package/metrics/sources.py +167 -167
- package/metrics/wrong.py +144 -144
- package/package.json +68 -64
- package/perf/README.md +89 -89
- package/perf/run.py +261 -261
- package/scripts/auto_retire.py +367 -367
- package/scripts/check.py +108 -104
- package/scripts/check_deprecations.py +378 -378
- package/scripts/check_themes.py +103 -103
- package/scripts/init.py +124 -124
- package/scripts/list_served.py +78 -78
- package/scripts/notice.py +78 -78
- package/scripts/onboard.py +401 -331
- package/scripts/provider_tags.py +129 -129
- package/scripts/reprefix.py +136 -136
- package/scripts/sync_config.py +105 -105
- package/scripts/test_auth.py +255 -255
- package/scripts/test_cli.py +189 -0
- package/scripts/test_client.py +233 -233
- package/scripts/test_connect.py +222 -222
- package/scripts/test_first_run.py +180 -180
- package/scripts/test_hubs.py +328 -328
- package/scripts/test_launcher.py +67 -0
- package/scripts/test_llm_log.py +85 -0
- package/scripts/test_mcp.py +178 -0
- package/scripts/test_merged.py +214 -193
- package/scripts/test_no_owui.py +291 -291
- package/scripts/test_owui.py +90 -90
- package/scripts/test_serve_edit.py +448 -386
- package/scripts/test_verdict.py +98 -98
- package/scripts/test_vision.py +228 -228
- package/serve.py +3904 -3662
- package/suite/mine.py +154 -154
- package/suite/pace.py +145 -145
- package/suite/run.py +1046 -1040
- package/suite/seed.py +421 -421
- package/suite/tasks/claim-alias-unbound/fixtures/onboard.py +286 -286
- package/suite/tasks/claim-error-text-string/fixtures/decide.py +187 -187
- package/suite/tasks/claim-list-body/fixtures/gateway.py +235 -235
- package/suite/tasks/claim-member-nominated-twice/fixtures/gateway.py +284 -284
- package/suite/tasks/claim-nominee-uses-slot/fixtures/gateway.py +284 -284
- package/suite/tasks/claim-silent-exit/fixtures/gateway.py +235 -235
- package/suite/tasks/claim-sse-hang/fixtures/gateway.py +235 -235
- package/suite/tasks/claim-unknown-nominee-crash/fixtures/gateway.py +284 -284
- package/suite/tasks/rebench-matchms-809-bug/task.json +23 -23
- package/suite/tasks/rebench-matchms-809-control/task.json +27 -27
- package/suite/tasks/rebench-more-itertools-1028-bug/task.json +23 -23
- package/suite/tasks/rebench-more-itertools-1028-control/task.json +27 -27
- package/suite/tasks/rebench-narwhals-2864-bug/task.json +23 -23
- package/suite/tasks/rebench-narwhals-2864-control/task.json +27 -27
- package/suite/tasks/rebench-quantecon-py-769-bug/task.json +23 -23
- package/suite/tasks/rebench-quantecon-py-769-control/task.json +27 -27
- package/suite/tasks/rebench-scrapy-6867-bug/task.json +23 -23
- package/suite/tasks/rebench-scrapy-6867-control/task.json +27 -27
- package/ui/bench.css +430 -424
- package/ui/bench.js +1756 -1555
- package/ui/themes/dark.css +35 -35
- package/ui/themes/hardwood.css +52 -52
- package/ui/themes/rainforest.css +32 -32
package/BENCHMARKS.md
CHANGED
|
@@ -1,262 +1,262 @@
|
|
|
1
|
-
# Standard benchmarks: which to adopt, and why
|
|
2
|
-
|
|
3
|
-
Two repositories were proposed. They are not the same kind of thing, and only
|
|
4
|
-
one of them is a thing you can run.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## `leobeeson/llm_benchmarks` — a reading list, not a harness
|
|
9
|
-
|
|
10
|
-
**What it is:** a single README cataloguing benchmarks by category, with
|
|
11
|
-
descriptions and links. Three commits. **No code, no datasets, no runner.**
|
|
12
|
-
|
|
13
|
-
**Verdict: read it, cite it, do not vendor it.**
|
|
14
|
-
|
|
15
|
-
There is nothing to pull in. Copying a catalogue into this repo creates a
|
|
16
|
-
second copy that goes stale while the original is one click away. Its value is
|
|
17
|
-
that it is a well-organised map of what exists — use it the way you would use
|
|
18
|
-
a bibliography: to decide what to go and get.
|
|
19
|
-
|
|
20
|
-
Where it *is* useful is deciding what a benchmark is even for. The categories
|
|
21
|
-
it lays out (knowledge, reasoning, coding, instruction-following, safety) are
|
|
22
|
-
a reasonable checklist against which to notice that a model rated well on
|
|
23
|
-
"coding" may be bad at the specific coding task you have.
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## `LiveCodeBench/LiveCodeBench` — a real harness, worth running, scoped
|
|
28
|
-
|
|
29
|
-
**What it is:** the official harness for the *LiveCodeBench* paper. 1,055
|
|
30
|
-
problems from LeetCode, AtCoder and Codeforces spanning May 2023 – April 2025.
|
|
31
|
-
It evaluates code generation, self-repair, code execution and test-output
|
|
32
|
-
prediction. It supports closed API models with a `--multiprocess` flag for
|
|
33
|
-
rate-limit-adjustable parallelism, so an OpenAI-compatible endpoint —
|
|
34
|
-
which is what Open WebUI serves — can be evaluated.
|
|
35
|
-
|
|
36
|
-
**Verdict: SUPERSEDED — do not adopt. See `LIVECODEBENCH.md`.**
|
|
37
|
-
|
|
38
|
-
> **Amended after trying it.** The original verdict below was "adopt it, but
|
|
39
|
-
> scoped". That was wrong, and the fact that disproves it is *in the paragraph
|
|
40
|
-
> above*: the problems span **May 2023 – April 2025**, while our models carry a
|
|
41
|
-
> 2026 cutoff. The date filter — the entire reason to adopt it — therefore
|
|
42
|
-
> selects zero problems, and any score without the filter is contaminated.
|
|
43
|
-
> I recorded the disqualifying date here and then spent six dependency fixes
|
|
44
|
-
> before checking it against the models. The reasoning below is left intact
|
|
45
|
-
> because it is still correct about *why* the property matters; it is only
|
|
46
|
-
> wrong that this benchmark can supply it to us.
|
|
47
|
-
|
|
48
|
-
### Why it is worth having
|
|
49
|
-
|
|
50
|
-
**Contamination-free by construction, which is the whole point.** Every
|
|
51
|
-
problem carries a release date, so you can evaluate a model *only* on problems
|
|
52
|
-
published after its training cutoff. Nearly every other public benchmark has
|
|
53
|
-
leaked into training sets, which is why scores drift upward without models
|
|
54
|
-
getting better at anything. For a file whose entire purpose is tracking
|
|
55
|
-
whether a model is actually improving, that property is worth more than the
|
|
56
|
-
score itself.
|
|
57
|
-
|
|
58
|
-
**It is objective.** Notes like the ones in `MODELS.md` are honest but they
|
|
59
|
-
are *my* judgement of my own offloads, which is exactly the kind of evidence
|
|
60
|
-
that flatters itself. A pass/fail test suite does not care.
|
|
61
|
-
|
|
62
|
-
### The caveats, stated before anyone runs it
|
|
63
|
-
|
|
64
|
-
**Runtime is the binding constraint, not accuracy.** From the smoke tests in
|
|
65
|
-
`runs/2026-09-03`, latency through this Open WebUI path ranges from 6.6 s
|
|
66
|
-
(`north-mini-code`) to 134 s (`nemotron-lightning`) on a *one-word* prompt.
|
|
67
|
-
1,055 problems against the slow end is on the order of **40 hours for one
|
|
68
|
-
model**. A full sweep of six models is not a thing that happens.
|
|
69
|
-
|
|
70
|
-
→ **Run a dated subset.** The most recent 50–100 problems, which are also the
|
|
71
|
-
ones least likely to be contaminated. That is a couple of hours for the fast
|
|
72
|
-
models and an overnight run for the slow ones, and it answers the question.
|
|
73
|
-
|
|
74
|
-
**Python 3.11 and `uv`.** wendell-research is on 3.14. It needs its own
|
|
75
|
-
environment; do not try to share one.
|
|
76
|
-
|
|
77
|
-
**It measures competitive programming, and that is not what we offload.**
|
|
78
|
-
This is the important caveat. The actual tasks routed to these models are:
|
|
79
|
-
read an unfamiliar file and describe its structure; draft a component against
|
|
80
|
-
a written spec; review one small surface adversarially. LiveCodeBench measures
|
|
81
|
-
none of those. A model can be excellent at Codeforces problems and still
|
|
82
|
-
invent a filename that does not exist — which is precisely the failure
|
|
83
|
-
`gemini-flash-3.8` produced twice.
|
|
84
|
-
|
|
85
|
-
→ Treat its score as **one axis**, useful for ranking raw coding capability
|
|
86
|
-
and for noticing when a model has genuinely regressed. Not as a proxy for
|
|
87
|
-
"good at our work".
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## The third thing, which matters more than either
|
|
92
|
-
|
|
93
|
-
**A local task suite built from our own offload shapes.**
|
|
94
|
-
|
|
95
|
-
Neither repository can tell us the thing we most want to know, because the
|
|
96
|
-
thing we most want to know is specific to this work. The suite that would:
|
|
97
|
-
|
|
98
|
-
| Task | Shape | Scored against |
|
|
99
|
-
| --- | --- | --- |
|
|
100
|
-
| Edit-point audit | Pipe 3 unfamiliar React files, ask for every user-editable value | An answer verified by hand against the files |
|
|
101
|
-
| Component draft | A tight spec (exact DOM, exact class names, framework versions) | Does it parse? Does it invent APIs? |
|
|
102
|
-
| Adversarial review | "This route is public. What can an authenticated admin do to make it serve something it should not?" | Did it find the avatar-through-brand-logo case? |
|
|
103
|
-
| Structured extraction | 40 test files → every substring assertion where a line match is meant | A known-good list |
|
|
104
|
-
|
|
105
|
-
Each has **a recorded correct answer already**, because each was done and
|
|
106
|
-
verified. That makes them regression tests for models rather than for code.
|
|
107
|
-
Cheap to run, directly predictive, and they measure the failure mode that
|
|
108
|
-
actually costs us — confident invention — which no public benchmark scores.
|
|
109
|
-
|
|
110
|
-
**ADOPTED 2026-09-04: EvalPlus (HumanEval+/MBPP+), as a floor tier only.**
|
|
111
|
-
See [`floor/README.md`](floor/README.md). It **fails** the date check below —
|
|
112
|
-
HumanEval and MBPP are 2021, our models are 2026 — and was adopted anyway,
|
|
113
|
-
knowingly, because a contaminated benchmark is still valid *downward*:
|
|
114
|
-
memorisation can only inflate a score, so a low one is real evidence and a high
|
|
115
|
-
one is worthless. It supplies the two things our own suite cannot — an absolute
|
|
116
|
-
scale, and a way to baseline a brand-new model against published figures. It
|
|
117
|
-
may never rank our models. That is the difference between adopting it and
|
|
118
|
-
adopting LiveCodeBench, which was adopted for a job it could not do.
|
|
119
|
-
|
|
120
|
-
**Recommended order (amended):** the local suite is the primary
|
|
121
|
-
benchmark, not the first of two. LiveCodeBench is dropped — its data ends
|
|
122
|
-
before our models' training cutoffs. The catalogue stays a bibliography.
|
|
123
|
-
|
|
124
|
-
**Before adopting any benchmark from it, check one thing first:** what is the
|
|
125
|
-
newest question, and is it after the cutoff of the model you want to score?
|
|
126
|
-
Every option in this file except our own suite fails that check today. Our
|
|
127
|
-
suite passes it for a reason no public benchmark can copy: its tasks are
|
|
128
|
-
built on private codebases, so they are in nobody's training set.
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
# Second review — 2026-09-04
|
|
133
|
-
|
|
134
|
-
Five more candidates, assessed against three criteria the operator set: **more
|
|
135
|
-
than Python**, **newer**, and **contamination-free if possible**. Each was
|
|
136
|
-
checked rather than recalled, because the LiveCodeBench detour came from
|
|
137
|
-
trusting a recollection.
|
|
138
|
-
|
|
139
|
-
| Candidate | Beyond Python | Contamination | Verdict |
|
|
140
|
-
| --- | --- | --- | --- |
|
|
141
|
-
| **FuncBenchGen** | Function calling, not code-gen | **Free by construction** | **Adopt** |
|
|
142
|
-
| **MultiPL-E** | **18 languages** | Inherits HumanEval/MBPP (2021) | **Adopt into Floor** |
|
|
143
|
-
| Ag-LiveCodeBench-X | Yes (Lua, Julia, …) | Inherits LCB's 2025-04 ceiling | Wait |
|
|
144
|
-
| LiveCodeBench | Python | Data ends 2025-04-06 | Still blocked |
|
|
145
|
-
| HELM | Very broad | Public datasets | Framework, not a fit |
|
|
146
|
-
| BIG-bench | Broad | 2021–22, absorbed | Skip |
|
|
147
|
-
|
|
148
|
-
## FuncBenchGen — the one that is genuinely uncontaminated
|
|
149
|
-
|
|
150
|
-
It **generates** tasks by traversing a hidden function-dependency DAG with
|
|
151
|
-
controllable depth and distractors, rather than publishing a fixed set. That
|
|
152
|
-
makes it contamination-free *by construction* rather than by date — the only
|
|
153
|
-
durable form, because anything published eventually gets scraped. ICLR 2026,
|
|
154
|
-
and it interfaces through LiteLLM so an OpenAI-compatible endpoint works.
|
|
155
|
-
|
|
156
|
-
It measures **multi-step tool use**, which is a different axis from writing a
|
|
157
|
-
function and one nothing else here covers.
|
|
158
|
-
|
|
159
|
-
## MultiPL-E — the answer to "not just Python"
|
|
160
|
-
|
|
161
|
-
Translates HumanEval and MBPP into **18 further languages**. 1,129 commits, and
|
|
162
|
-
it ships a container with every toolchain.
|
|
163
|
-
|
|
164
|
-
**It is the same 2021 problems, so it is equally contaminated in principle** —
|
|
165
|
-
which is why it belongs in `floor/` under the same downward-only rule, not
|
|
166
|
-
beside the suite. One real nuance: a translation into a low-resource language
|
|
167
|
-
(Lua, Racket, OCaml) is *less* likely to have been memorised verbatim than the
|
|
168
|
-
Python original, simply because less of that code exists to train on. Weaker
|
|
169
|
-
contamination, not absent.
|
|
170
|
-
|
|
171
|
-
**The integration gap:** its runners target HuggingFace and vLLM models, not
|
|
172
|
-
API endpoints. That is the same wall `evalplus.codegen` presented, and the same
|
|
173
|
-
answer applies — take the dataset from the Hub and generate through our own
|
|
174
|
-
`llm` path, using their container only for execution.
|
|
175
|
-
|
|
176
|
-
## Why Ag-LiveCodeBench-X is a wait, not a no
|
|
177
|
-
|
|
178
|
-
Multi-language and agentic, from the same lab as MultiPL-E. But it is a variant
|
|
179
|
-
**of** LiveCodeBench, so it inherits that problem set and therefore the same
|
|
180
|
-
date ceiling that disqualified it: the newest problem predates our models'
|
|
181
|
-
training cutoffs. One commit on main. Revisit when it has its own problems or a
|
|
182
|
-
newer LCB release lands.
|
|
183
|
-
|
|
184
|
-
## HELM and BIG-bench
|
|
185
|
-
|
|
186
|
-
**HELM** is a framework rather than a benchmark — broad, actively maintained,
|
|
187
|
-
genuinely useful for holistic evaluation. Its scenarios are public datasets, so
|
|
188
|
-
it inherits their contamination, and it is heavy. If breadth beyond code is
|
|
189
|
-
ever wanted it is the right tool; it is not the right tool for "is this model
|
|
190
|
-
good at our work".
|
|
191
|
-
|
|
192
|
-
**BIG-bench** is 2021–22, superseded in practice by BIG-Bench Hard, and
|
|
193
|
-
thoroughly absorbed into training sets. Skip.
|
|
194
|
-
|
|
195
|
-
## The rule this review confirms
|
|
196
|
-
|
|
197
|
-
**Only generated benchmarks stay uncontaminated, and only private code stays
|
|
198
|
-
private.** Everything published is on a clock. That is why the tiers are
|
|
199
|
-
shaped as they are: `suite/` (our own repositories) and FuncBenchGen
|
|
200
|
-
(synthesised per run) are the two that can be trusted upward; everything else
|
|
201
|
-
is a floor.
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
# What already existed, and what this should have reused (2026-09-05)
|
|
206
|
-
|
|
207
|
-
Asked late whether an off-the-shelf tool would have done this. **Largely yes,
|
|
208
|
-
for one of the four tiers**, and the honest answer is that it should have been
|
|
209
|
-
checked at the start rather than after the code was written.
|
|
210
|
-
|
|
211
|
-
| What we built | What already does it |
|
|
212
|
-
| --- | --- |
|
|
213
|
-
| `suite/run.py` — run N models over N prompts, assert on output, compare | **promptfoo** — a CLI and library for exactly this, with a viewer |
|
|
214
|
-
| `metrics/cost.py` — token and cost accounting | **Langfuse**, **Helicone** — LLM observability with cost tracking |
|
|
215
|
-
| `floor/` — public code benchmarks | **EvalPlus** (which we did use), `lm-evaluation-harness` |
|
|
216
|
-
| `metrics/route.py` — pick a model per task | **RouteLLM**, **Not Diamond**, OpenRouter's own auto-router |
|
|
217
|
-
|
|
218
|
-
**`promptfoo` is the real overlap.** It would have supplied the runner, the
|
|
219
|
-
assertion mechanism, multi-model comparison and a results viewer — a good
|
|
220
|
-
share of `suite/run.py` and `serve.py`.
|
|
221
|
-
|
|
222
|
-
## What would not have come off a shelf
|
|
223
|
-
|
|
224
|
-
- **The tasks.** Drawn from private repositories with answers verified before
|
|
225
|
-
any model saw them. No tool can supply those; that is the whole point of the
|
|
226
|
-
tier and the reason it can rank when the public ones cannot.
|
|
227
|
-
- **The failure taxonomy.** `structural` / `entitlement` / `capacity` /
|
|
228
|
-
`timeout`, each tied to a different ACTION — fix the registration, keep and
|
|
229
|
-
watch, retry, wait. Generic harnesses record pass/fail, and every hard-won
|
|
230
|
-
correction in this repo came from refusing to collapse those.
|
|
231
|
-
- **The benchmark-versus-offload distinction.** A general tool counts calls. It
|
|
232
|
-
cannot know that 164 of them were a floor run rather than work, which is the
|
|
233
|
-
difference between "most used" and "most measured".
|
|
234
|
-
- **Explore/exploit routing on staleness.** Commercial routers optimise cost
|
|
235
|
-
and quality per call. None of them is trying to stop a local roster of models
|
|
236
|
-
going stale through disuse.
|
|
237
|
-
|
|
238
|
-
## Should it be migrated
|
|
239
|
-
|
|
240
|
-
**Not now, and the reason is where the value sits.** It is in the tasks, the
|
|
241
|
-
verified answers and the recorded reasoning — not in the runner, which is the
|
|
242
|
-
part promptfoo would replace. Swapping it would re-implement the taxonomy and
|
|
243
|
-
the ledger inside somebody else's abstraction for no gain today.
|
|
244
|
-
|
|
245
|
-
**Revisit if the suite gets large — but as a COMPONENT, not a replacement.**
|
|
246
|
-
That is the sharper framing, and it is the one to act on. This repository is
|
|
247
|
-
not an eval runner; it is an integration of four things that are usually
|
|
248
|
-
separate products: evaluation, cost accounting, availability monitoring and
|
|
249
|
-
routing. The glue between them is where its value is, and no single tool sells
|
|
250
|
-
that glue.
|
|
251
|
-
|
|
252
|
-
So at forty or fifty tasks the move is not "migrate to promptfoo". It is
|
|
253
|
-
"let promptfoo be the runner inside `suite/`", keeping the failure taxonomy,
|
|
254
|
-
the offload ledger and the router above it. That swaps ~400 lines we maintain
|
|
255
|
-
for something better maintained, and gives up nothing that is actually ours.
|
|
256
|
-
|
|
257
|
-
The tasks are portable, which is what makes that possible whenever it becomes
|
|
258
|
-
worth doing.
|
|
259
|
-
|
|
260
|
-
**The lesson is the process, not the verdict.** The same check that now
|
|
261
|
-
precedes adopting a benchmark — *does this already exist, and does it fit* —
|
|
262
|
-
should have preceded building one.
|
|
1
|
+
# Standard benchmarks: which to adopt, and why
|
|
2
|
+
|
|
3
|
+
Two repositories were proposed. They are not the same kind of thing, and only
|
|
4
|
+
one of them is a thing you can run.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## `leobeeson/llm_benchmarks` — a reading list, not a harness
|
|
9
|
+
|
|
10
|
+
**What it is:** a single README cataloguing benchmarks by category, with
|
|
11
|
+
descriptions and links. Three commits. **No code, no datasets, no runner.**
|
|
12
|
+
|
|
13
|
+
**Verdict: read it, cite it, do not vendor it.**
|
|
14
|
+
|
|
15
|
+
There is nothing to pull in. Copying a catalogue into this repo creates a
|
|
16
|
+
second copy that goes stale while the original is one click away. Its value is
|
|
17
|
+
that it is a well-organised map of what exists — use it the way you would use
|
|
18
|
+
a bibliography: to decide what to go and get.
|
|
19
|
+
|
|
20
|
+
Where it *is* useful is deciding what a benchmark is even for. The categories
|
|
21
|
+
it lays out (knowledge, reasoning, coding, instruction-following, safety) are
|
|
22
|
+
a reasonable checklist against which to notice that a model rated well on
|
|
23
|
+
"coding" may be bad at the specific coding task you have.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## `LiveCodeBench/LiveCodeBench` — a real harness, worth running, scoped
|
|
28
|
+
|
|
29
|
+
**What it is:** the official harness for the *LiveCodeBench* paper. 1,055
|
|
30
|
+
problems from LeetCode, AtCoder and Codeforces spanning May 2023 – April 2025.
|
|
31
|
+
It evaluates code generation, self-repair, code execution and test-output
|
|
32
|
+
prediction. It supports closed API models with a `--multiprocess` flag for
|
|
33
|
+
rate-limit-adjustable parallelism, so an OpenAI-compatible endpoint —
|
|
34
|
+
which is what Open WebUI serves — can be evaluated.
|
|
35
|
+
|
|
36
|
+
**Verdict: SUPERSEDED — do not adopt. See `LIVECODEBENCH.md`.**
|
|
37
|
+
|
|
38
|
+
> **Amended after trying it.** The original verdict below was "adopt it, but
|
|
39
|
+
> scoped". That was wrong, and the fact that disproves it is *in the paragraph
|
|
40
|
+
> above*: the problems span **May 2023 – April 2025**, while our models carry a
|
|
41
|
+
> 2026 cutoff. The date filter — the entire reason to adopt it — therefore
|
|
42
|
+
> selects zero problems, and any score without the filter is contaminated.
|
|
43
|
+
> I recorded the disqualifying date here and then spent six dependency fixes
|
|
44
|
+
> before checking it against the models. The reasoning below is left intact
|
|
45
|
+
> because it is still correct about *why* the property matters; it is only
|
|
46
|
+
> wrong that this benchmark can supply it to us.
|
|
47
|
+
|
|
48
|
+
### Why it is worth having
|
|
49
|
+
|
|
50
|
+
**Contamination-free by construction, which is the whole point.** Every
|
|
51
|
+
problem carries a release date, so you can evaluate a model *only* on problems
|
|
52
|
+
published after its training cutoff. Nearly every other public benchmark has
|
|
53
|
+
leaked into training sets, which is why scores drift upward without models
|
|
54
|
+
getting better at anything. For a file whose entire purpose is tracking
|
|
55
|
+
whether a model is actually improving, that property is worth more than the
|
|
56
|
+
score itself.
|
|
57
|
+
|
|
58
|
+
**It is objective.** Notes like the ones in `MODELS.md` are honest but they
|
|
59
|
+
are *my* judgement of my own offloads, which is exactly the kind of evidence
|
|
60
|
+
that flatters itself. A pass/fail test suite does not care.
|
|
61
|
+
|
|
62
|
+
### The caveats, stated before anyone runs it
|
|
63
|
+
|
|
64
|
+
**Runtime is the binding constraint, not accuracy.** From the smoke tests in
|
|
65
|
+
`runs/2026-09-03`, latency through this Open WebUI path ranges from 6.6 s
|
|
66
|
+
(`north-mini-code`) to 134 s (`nemotron-lightning`) on a *one-word* prompt.
|
|
67
|
+
1,055 problems against the slow end is on the order of **40 hours for one
|
|
68
|
+
model**. A full sweep of six models is not a thing that happens.
|
|
69
|
+
|
|
70
|
+
→ **Run a dated subset.** The most recent 50–100 problems, which are also the
|
|
71
|
+
ones least likely to be contaminated. That is a couple of hours for the fast
|
|
72
|
+
models and an overnight run for the slow ones, and it answers the question.
|
|
73
|
+
|
|
74
|
+
**Python 3.11 and `uv`.** wendell-research is on 3.14. It needs its own
|
|
75
|
+
environment; do not try to share one.
|
|
76
|
+
|
|
77
|
+
**It measures competitive programming, and that is not what we offload.**
|
|
78
|
+
This is the important caveat. The actual tasks routed to these models are:
|
|
79
|
+
read an unfamiliar file and describe its structure; draft a component against
|
|
80
|
+
a written spec; review one small surface adversarially. LiveCodeBench measures
|
|
81
|
+
none of those. A model can be excellent at Codeforces problems and still
|
|
82
|
+
invent a filename that does not exist — which is precisely the failure
|
|
83
|
+
`gemini-flash-3.8` produced twice.
|
|
84
|
+
|
|
85
|
+
→ Treat its score as **one axis**, useful for ranking raw coding capability
|
|
86
|
+
and for noticing when a model has genuinely regressed. Not as a proxy for
|
|
87
|
+
"good at our work".
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## The third thing, which matters more than either
|
|
92
|
+
|
|
93
|
+
**A local task suite built from our own offload shapes.**
|
|
94
|
+
|
|
95
|
+
Neither repository can tell us the thing we most want to know, because the
|
|
96
|
+
thing we most want to know is specific to this work. The suite that would:
|
|
97
|
+
|
|
98
|
+
| Task | Shape | Scored against |
|
|
99
|
+
| --- | --- | --- |
|
|
100
|
+
| Edit-point audit | Pipe 3 unfamiliar React files, ask for every user-editable value | An answer verified by hand against the files |
|
|
101
|
+
| Component draft | A tight spec (exact DOM, exact class names, framework versions) | Does it parse? Does it invent APIs? |
|
|
102
|
+
| Adversarial review | "This route is public. What can an authenticated admin do to make it serve something it should not?" | Did it find the avatar-through-brand-logo case? |
|
|
103
|
+
| Structured extraction | 40 test files → every substring assertion where a line match is meant | A known-good list |
|
|
104
|
+
|
|
105
|
+
Each has **a recorded correct answer already**, because each was done and
|
|
106
|
+
verified. That makes them regression tests for models rather than for code.
|
|
107
|
+
Cheap to run, directly predictive, and they measure the failure mode that
|
|
108
|
+
actually costs us — confident invention — which no public benchmark scores.
|
|
109
|
+
|
|
110
|
+
**ADOPTED 2026-09-04: EvalPlus (HumanEval+/MBPP+), as a floor tier only.**
|
|
111
|
+
See [`floor/README.md`](floor/README.md). It **fails** the date check below —
|
|
112
|
+
HumanEval and MBPP are 2021, our models are 2026 — and was adopted anyway,
|
|
113
|
+
knowingly, because a contaminated benchmark is still valid *downward*:
|
|
114
|
+
memorisation can only inflate a score, so a low one is real evidence and a high
|
|
115
|
+
one is worthless. It supplies the two things our own suite cannot — an absolute
|
|
116
|
+
scale, and a way to baseline a brand-new model against published figures. It
|
|
117
|
+
may never rank our models. That is the difference between adopting it and
|
|
118
|
+
adopting LiveCodeBench, which was adopted for a job it could not do.
|
|
119
|
+
|
|
120
|
+
**Recommended order (amended):** the local suite is the primary
|
|
121
|
+
benchmark, not the first of two. LiveCodeBench is dropped — its data ends
|
|
122
|
+
before our models' training cutoffs. The catalogue stays a bibliography.
|
|
123
|
+
|
|
124
|
+
**Before adopting any benchmark from it, check one thing first:** what is the
|
|
125
|
+
newest question, and is it after the cutoff of the model you want to score?
|
|
126
|
+
Every option in this file except our own suite fails that check today. Our
|
|
127
|
+
suite passes it for a reason no public benchmark can copy: its tasks are
|
|
128
|
+
built on private codebases, so they are in nobody's training set.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
# Second review — 2026-09-04
|
|
133
|
+
|
|
134
|
+
Five more candidates, assessed against three criteria the operator set: **more
|
|
135
|
+
than Python**, **newer**, and **contamination-free if possible**. Each was
|
|
136
|
+
checked rather than recalled, because the LiveCodeBench detour came from
|
|
137
|
+
trusting a recollection.
|
|
138
|
+
|
|
139
|
+
| Candidate | Beyond Python | Contamination | Verdict |
|
|
140
|
+
| --- | --- | --- | --- |
|
|
141
|
+
| **FuncBenchGen** | Function calling, not code-gen | **Free by construction** | **Adopt** |
|
|
142
|
+
| **MultiPL-E** | **18 languages** | Inherits HumanEval/MBPP (2021) | **Adopt into Floor** |
|
|
143
|
+
| Ag-LiveCodeBench-X | Yes (Lua, Julia, …) | Inherits LCB's 2025-04 ceiling | Wait |
|
|
144
|
+
| LiveCodeBench | Python | Data ends 2025-04-06 | Still blocked |
|
|
145
|
+
| HELM | Very broad | Public datasets | Framework, not a fit |
|
|
146
|
+
| BIG-bench | Broad | 2021–22, absorbed | Skip |
|
|
147
|
+
|
|
148
|
+
## FuncBenchGen — the one that is genuinely uncontaminated
|
|
149
|
+
|
|
150
|
+
It **generates** tasks by traversing a hidden function-dependency DAG with
|
|
151
|
+
controllable depth and distractors, rather than publishing a fixed set. That
|
|
152
|
+
makes it contamination-free *by construction* rather than by date — the only
|
|
153
|
+
durable form, because anything published eventually gets scraped. ICLR 2026,
|
|
154
|
+
and it interfaces through LiteLLM so an OpenAI-compatible endpoint works.
|
|
155
|
+
|
|
156
|
+
It measures **multi-step tool use**, which is a different axis from writing a
|
|
157
|
+
function and one nothing else here covers.
|
|
158
|
+
|
|
159
|
+
## MultiPL-E — the answer to "not just Python"
|
|
160
|
+
|
|
161
|
+
Translates HumanEval and MBPP into **18 further languages**. 1,129 commits, and
|
|
162
|
+
it ships a container with every toolchain.
|
|
163
|
+
|
|
164
|
+
**It is the same 2021 problems, so it is equally contaminated in principle** —
|
|
165
|
+
which is why it belongs in `floor/` under the same downward-only rule, not
|
|
166
|
+
beside the suite. One real nuance: a translation into a low-resource language
|
|
167
|
+
(Lua, Racket, OCaml) is *less* likely to have been memorised verbatim than the
|
|
168
|
+
Python original, simply because less of that code exists to train on. Weaker
|
|
169
|
+
contamination, not absent.
|
|
170
|
+
|
|
171
|
+
**The integration gap:** its runners target HuggingFace and vLLM models, not
|
|
172
|
+
API endpoints. That is the same wall `evalplus.codegen` presented, and the same
|
|
173
|
+
answer applies — take the dataset from the Hub and generate through our own
|
|
174
|
+
`llm` path, using their container only for execution.
|
|
175
|
+
|
|
176
|
+
## Why Ag-LiveCodeBench-X is a wait, not a no
|
|
177
|
+
|
|
178
|
+
Multi-language and agentic, from the same lab as MultiPL-E. But it is a variant
|
|
179
|
+
**of** LiveCodeBench, so it inherits that problem set and therefore the same
|
|
180
|
+
date ceiling that disqualified it: the newest problem predates our models'
|
|
181
|
+
training cutoffs. One commit on main. Revisit when it has its own problems or a
|
|
182
|
+
newer LCB release lands.
|
|
183
|
+
|
|
184
|
+
## HELM and BIG-bench
|
|
185
|
+
|
|
186
|
+
**HELM** is a framework rather than a benchmark — broad, actively maintained,
|
|
187
|
+
genuinely useful for holistic evaluation. Its scenarios are public datasets, so
|
|
188
|
+
it inherits their contamination, and it is heavy. If breadth beyond code is
|
|
189
|
+
ever wanted it is the right tool; it is not the right tool for "is this model
|
|
190
|
+
good at our work".
|
|
191
|
+
|
|
192
|
+
**BIG-bench** is 2021–22, superseded in practice by BIG-Bench Hard, and
|
|
193
|
+
thoroughly absorbed into training sets. Skip.
|
|
194
|
+
|
|
195
|
+
## The rule this review confirms
|
|
196
|
+
|
|
197
|
+
**Only generated benchmarks stay uncontaminated, and only private code stays
|
|
198
|
+
private.** Everything published is on a clock. That is why the tiers are
|
|
199
|
+
shaped as they are: `suite/` (our own repositories) and FuncBenchGen
|
|
200
|
+
(synthesised per run) are the two that can be trusted upward; everything else
|
|
201
|
+
is a floor.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
# What already existed, and what this should have reused (2026-09-05)
|
|
206
|
+
|
|
207
|
+
Asked late whether an off-the-shelf tool would have done this. **Largely yes,
|
|
208
|
+
for one of the four tiers**, and the honest answer is that it should have been
|
|
209
|
+
checked at the start rather than after the code was written.
|
|
210
|
+
|
|
211
|
+
| What we built | What already does it |
|
|
212
|
+
| --- | --- |
|
|
213
|
+
| `suite/run.py` — run N models over N prompts, assert on output, compare | **promptfoo** — a CLI and library for exactly this, with a viewer |
|
|
214
|
+
| `metrics/cost.py` — token and cost accounting | **Langfuse**, **Helicone** — LLM observability with cost tracking |
|
|
215
|
+
| `floor/` — public code benchmarks | **EvalPlus** (which we did use), `lm-evaluation-harness` |
|
|
216
|
+
| `metrics/route.py` — pick a model per task | **RouteLLM**, **Not Diamond**, OpenRouter's own auto-router |
|
|
217
|
+
|
|
218
|
+
**`promptfoo` is the real overlap.** It would have supplied the runner, the
|
|
219
|
+
assertion mechanism, multi-model comparison and a results viewer — a good
|
|
220
|
+
share of `suite/run.py` and `serve.py`.
|
|
221
|
+
|
|
222
|
+
## What would not have come off a shelf
|
|
223
|
+
|
|
224
|
+
- **The tasks.** Drawn from private repositories with answers verified before
|
|
225
|
+
any model saw them. No tool can supply those; that is the whole point of the
|
|
226
|
+
tier and the reason it can rank when the public ones cannot.
|
|
227
|
+
- **The failure taxonomy.** `structural` / `entitlement` / `capacity` /
|
|
228
|
+
`timeout`, each tied to a different ACTION — fix the registration, keep and
|
|
229
|
+
watch, retry, wait. Generic harnesses record pass/fail, and every hard-won
|
|
230
|
+
correction in this repo came from refusing to collapse those.
|
|
231
|
+
- **The benchmark-versus-offload distinction.** A general tool counts calls. It
|
|
232
|
+
cannot know that 164 of them were a floor run rather than work, which is the
|
|
233
|
+
difference between "most used" and "most measured".
|
|
234
|
+
- **Explore/exploit routing on staleness.** Commercial routers optimise cost
|
|
235
|
+
and quality per call. None of them is trying to stop a local roster of models
|
|
236
|
+
going stale through disuse.
|
|
237
|
+
|
|
238
|
+
## Should it be migrated
|
|
239
|
+
|
|
240
|
+
**Not now, and the reason is where the value sits.** It is in the tasks, the
|
|
241
|
+
verified answers and the recorded reasoning — not in the runner, which is the
|
|
242
|
+
part promptfoo would replace. Swapping it would re-implement the taxonomy and
|
|
243
|
+
the ledger inside somebody else's abstraction for no gain today.
|
|
244
|
+
|
|
245
|
+
**Revisit if the suite gets large — but as a COMPONENT, not a replacement.**
|
|
246
|
+
That is the sharper framing, and it is the one to act on. This repository is
|
|
247
|
+
not an eval runner; it is an integration of four things that are usually
|
|
248
|
+
separate products: evaluation, cost accounting, availability monitoring and
|
|
249
|
+
routing. The glue between them is where its value is, and no single tool sells
|
|
250
|
+
that glue.
|
|
251
|
+
|
|
252
|
+
So at forty or fifty tasks the move is not "migrate to promptfoo". It is
|
|
253
|
+
"let promptfoo be the runner inside `suite/`", keeping the failure taxonomy,
|
|
254
|
+
the offload ledger and the router above it. That swaps ~400 lines we maintain
|
|
255
|
+
for something better maintained, and gives up nothing that is actually ours.
|
|
256
|
+
|
|
257
|
+
The tasks are portable, which is what makes that possible whenever it becomes
|
|
258
|
+
worth doing.
|
|
259
|
+
|
|
260
|
+
**The lesson is the process, not the verdict.** The same check that now
|
|
261
|
+
precedes adopting a benchmark — *does this already exist, and does it fit* —
|
|
262
|
+
should have preceded building one.
|