opencode-models 0.1.0__py3-none-any.whl
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.
- opencode_models/__init__.py +8 -0
- opencode_models/__main__.py +5 -0
- opencode_models/arena.py +108 -0
- opencode_models/auth.py +48 -0
- opencode_models/availability.py +102 -0
- opencode_models/benchmarks.py +19 -0
- opencode_models/boards.py +518 -0
- opencode_models/cli.py +1172 -0
- opencode_models/data.py +82 -0
- opencode_models/fetch.py +101 -0
- opencode_models/identity.py +100 -0
- opencode_models/labelmap.py +84 -0
- opencode_models/live.py +88 -0
- opencode_models/overrides.py +252 -0
- opencode_models/pareto.py +34 -0
- opencode_models/pricing.py +415 -0
- opencode_models/ranking.py +591 -0
- opencode_models/scoring.py +230 -0
- opencode_models/seed.py +184 -0
- opencode_models/sources/go.txt +45 -0
- opencode_models/sources/zen.txt +87 -0
- opencode_models/sources.py +55 -0
- opencode_models/tables.py +94 -0
- opencode_models-0.1.0.dist-info/METADATA +544 -0
- opencode_models-0.1.0.dist-info/RECORD +28 -0
- opencode_models-0.1.0.dist-info/WHEEL +4 -0
- opencode_models-0.1.0.dist-info/entry_points.txt +2 -0
- opencode_models-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"""Curated score overlays layered over the fetched upstream records.
|
|
2
|
+
|
|
3
|
+
``data/opencode/`` is verbatim upstream (``fetch`` writes only there) and
|
|
4
|
+
``data/overrides/`` is hand-written: one sparse JSON per model carrying only
|
|
5
|
+
the entries we vouched for — never a full copy. Both are merged at load
|
|
6
|
+
time here, keyed by (benchmark name, version), so an override can add a
|
|
7
|
+
score upstream lacks (Grok 4.6's Terminal-Bench 2.1, measured by
|
|
8
|
+
Artificial Analysis but absent from the registry) or pin a value upstream
|
|
9
|
+
also carries (Grok 4.7's 4.0 number, where we prefer the independent run
|
|
10
|
+
over the vendor's own).
|
|
11
|
+
|
|
12
|
+
Not every source means the same thing. A score carries more cross-model
|
|
13
|
+
meaning when one evaluator ran every model on one harness than when a lab
|
|
14
|
+
published its own best-scaffold run, so each entry is tiered by where it
|
|
15
|
+
comes from and the override layer only overrides when it is at least as
|
|
16
|
+
good a source — otherwise the disagreement is surfaced, not silently
|
|
17
|
+
applied. :func:`load_curated` returns those disagreements for the
|
|
18
|
+
``conflicts`` command.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import json
|
|
24
|
+
from dataclasses import dataclass, replace
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
from .data import Model, benchmark_key, load_models
|
|
28
|
+
|
|
29
|
+
#: Independent evaluator that runs every model on one harness — the only
|
|
30
|
+
#: regime where cross-model differences are model differences.
|
|
31
|
+
TIER_INDEPENDENT = 1
|
|
32
|
+
#: Official benchmark leaderboard: standardized tasks and intervals, but the
|
|
33
|
+
#: agent scaffold is the submitter's choice (recorded per row, auditable).
|
|
34
|
+
TIER_OFFICIAL = 2
|
|
35
|
+
#: The lab's own model card / launch post: best scaffold, cherry-picked.
|
|
36
|
+
TIER_SELF_REPORTED = 3
|
|
37
|
+
|
|
38
|
+
TIER_LABELS = {
|
|
39
|
+
TIER_INDEPENDENT: "independent",
|
|
40
|
+
TIER_OFFICIAL: "official board",
|
|
41
|
+
TIER_SELF_REPORTED: "self-reported",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#: Hosts whose runs are independent (they evaluate, not publish).
|
|
45
|
+
INDEPENDENT_HOSTS = ("artificialanalysis.ai",)
|
|
46
|
+
#: Hosts that run the official benchmark submission boards.
|
|
47
|
+
OFFICIAL_HOSTS = ("tbench.ai", "www.tbench.ai", "www.swebench.com", "swebench.com")
|
|
48
|
+
|
|
49
|
+
OVERRIDES_DIR = "overrides"
|
|
50
|
+
|
|
51
|
+
#: The Terminal-Bench 2.1 → 4.0 band, fitted on the models whose vendor
|
|
52
|
+
#: cards carry *both* versions (tb4 ≈ 1.131·tb21 − 71.39, R² ≈ 0.77,
|
|
53
|
+
#: residuals up to ±10 points). A smoke alarm, never a projection: a score
|
|
54
|
+
#: this far off the band is a prompt to check who ran it, not a value to
|
|
55
|
+
#: substitute — the residuals are as large as the differences that matter.
|
|
56
|
+
TB40_BAND = (1.131, -71.39)
|
|
57
|
+
#: How far off the band a pair must sit before it is worth a look.
|
|
58
|
+
TB40_BAND_SLACK = 10.0
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def source_tier(source: str | None) -> int:
|
|
62
|
+
"""Tier of a benchmark entry's source URL.
|
|
63
|
+
|
|
64
|
+
Independent evaluators come first (same harness for every model, so the
|
|
65
|
+
number is comparable across labs), then official benchmark boards (the
|
|
66
|
+
tasks and intervals are standardized even if the agent is not), then
|
|
67
|
+
everything else — vendor model cards, launch posts and aggregators
|
|
68
|
+
without a published methodology.
|
|
69
|
+
"""
|
|
70
|
+
if not source:
|
|
71
|
+
return TIER_SELF_REPORTED
|
|
72
|
+
host = source.split("//", 1)[-1].split("/", 1)[0].lower()
|
|
73
|
+
if host in INDEPENDENT_HOSTS:
|
|
74
|
+
return TIER_INDEPENDENT
|
|
75
|
+
if host in OFFICIAL_HOSTS:
|
|
76
|
+
return TIER_OFFICIAL
|
|
77
|
+
return TIER_SELF_REPORTED
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@dataclass(frozen=True)
|
|
81
|
+
class Conflict:
|
|
82
|
+
"""An override that disagrees with the upstream value it overlays."""
|
|
83
|
+
|
|
84
|
+
model_id: str
|
|
85
|
+
benchmark: str
|
|
86
|
+
upstream: float
|
|
87
|
+
override: float
|
|
88
|
+
upstream_source: str | None
|
|
89
|
+
override_source: str | None
|
|
90
|
+
reason: str
|
|
91
|
+
#: Whether the override actually landed (tier decided). A same-tier
|
|
92
|
+
#: disagreement is reported and *kept as upstream* — the console must
|
|
93
|
+
#: not claim an application that did not happen.
|
|
94
|
+
applied: bool = True
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def used(self) -> float:
|
|
98
|
+
"""The value the console actually keeps.
|
|
99
|
+
|
|
100
|
+
Naming it here rather than leaving the reader to infer it from the
|
|
101
|
+
two columns: the second number is not necessarily the one in the
|
|
102
|
+
view, and "override wins" was the wrong way to say so for a board
|
|
103
|
+
row, where nothing is being overridden.
|
|
104
|
+
"""
|
|
105
|
+
return self.override if self.applied else self.upstream
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def used_source(self) -> str | None:
|
|
109
|
+
"""The source of the value in the view."""
|
|
110
|
+
return self.override_source if self.applied else self.upstream_source
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
def override_wins(self) -> bool:
|
|
114
|
+
"""The override applies only when its source is at least as good.
|
|
115
|
+
|
|
116
|
+
The curated layer exists to fix the record, not to spray opinions
|
|
117
|
+
over it: a vendor's own number stays put against a random blog,
|
|
118
|
+
but an independent rerun beats the vendor.
|
|
119
|
+
"""
|
|
120
|
+
return source_tier(self.override_source) <= source_tier(self.upstream_source)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def load_overrides(overrides_dir: Path) -> dict[str, dict]:
|
|
124
|
+
"""Parse ``*.json`` in *overrides_dir* into ``{model id: document}*.
|
|
125
|
+
|
|
126
|
+
Matching is on the ``model.id`` the file pins, not on the filename, so a
|
|
127
|
+
renamed file still finds its model. A file without a usable id is
|
|
128
|
+
skipped rather than trusted, and so is any *entry* without a source: an
|
|
129
|
+
unattributed score cannot be tiered, so the tier policy would quietly
|
|
130
|
+
treat it as a vendor self-report — the worst case. Dropping it here
|
|
131
|
+
means a hand-written override either carries its provenance or does not
|
|
132
|
+
land at all.
|
|
133
|
+
"""
|
|
134
|
+
found: dict[str, dict] = {}
|
|
135
|
+
for path in sorted(Path(overrides_dir).glob("*.json")):
|
|
136
|
+
try:
|
|
137
|
+
doc = json.loads(path.read_text())["model"]
|
|
138
|
+
model_id = doc["id"]
|
|
139
|
+
except (json.JSONDecodeError, KeyError, TypeError):
|
|
140
|
+
continue
|
|
141
|
+
doc = {
|
|
142
|
+
**doc,
|
|
143
|
+
"benchmarks": [
|
|
144
|
+
e
|
|
145
|
+
for e in (doc.get("benchmarks") or [])
|
|
146
|
+
if isinstance(e, dict) and e.get("source")
|
|
147
|
+
],
|
|
148
|
+
}
|
|
149
|
+
found[model_id] = doc
|
|
150
|
+
return found
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def apply(model: Model, override: dict) -> tuple[Model, list[Conflict]]:
|
|
154
|
+
"""Layer *override* onto *model*; return the model and its conflicts.
|
|
155
|
+
|
|
156
|
+
Entries are keyed by (name, version) — the same key the catalog uses.
|
|
157
|
+
An override adds a benchmark upstream lacks, or pins a value upstream
|
|
158
|
+
also carries; pinning a *different* value is only applied when the
|
|
159
|
+
override's source is at least as good (:attr:`Conflict.override_wins`),
|
|
160
|
+
and either way the disagreement is returned for ``conflicts``.
|
|
161
|
+
"""
|
|
162
|
+
scores = dict(model.scores)
|
|
163
|
+
sources = dict(model.sources)
|
|
164
|
+
note = override.get("note") or ""
|
|
165
|
+
conflicts: list[Conflict] = []
|
|
166
|
+
for entry in override.get("benchmarks") or []:
|
|
167
|
+
key = benchmark_key(entry)
|
|
168
|
+
value = entry.get("score")
|
|
169
|
+
if not isinstance(value, (int, float)):
|
|
170
|
+
continue # a note or a half-filled entry adds nothing
|
|
171
|
+
if key in scores and scores[key] != value:
|
|
172
|
+
conflict = Conflict(
|
|
173
|
+
model_id=model.model_id,
|
|
174
|
+
benchmark=key,
|
|
175
|
+
upstream=scores[key],
|
|
176
|
+
override=value,
|
|
177
|
+
upstream_source=model.sources.get(key),
|
|
178
|
+
override_source=entry.get("source"),
|
|
179
|
+
reason=entry.get("note") or note,
|
|
180
|
+
)
|
|
181
|
+
conflicts.append(replace(conflict, applied=conflict.override_wins))
|
|
182
|
+
if not conflict.override_wins:
|
|
183
|
+
continue
|
|
184
|
+
sources[key] = entry.get("source")
|
|
185
|
+
scores[key] = value
|
|
186
|
+
return replace(model, scores=scores, sources=sources), conflicts
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@dataclass(frozen=True)
|
|
190
|
+
class Curated:
|
|
191
|
+
"""Upstream records with overlays applied, plus the audit trail.
|
|
192
|
+
|
|
193
|
+
``conflicts`` is every disagreement between an override and upstream
|
|
194
|
+
(whether or not the override won); ``orphans`` are override files whose
|
|
195
|
+
model id no longer exists upstream — the signature of a typo or of a
|
|
196
|
+
model pulled from the registry.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
models: list[Model]
|
|
200
|
+
conflicts: list[Conflict]
|
|
201
|
+
curated: set[str]
|
|
202
|
+
orphans: set[str]
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def load_curated(upstream_dir: Path, overrides_dir: Path) -> Curated:
|
|
206
|
+
"""Load upstream records with the curated overlays applied.
|
|
207
|
+
|
|
208
|
+
Models without an override come back untouched; a model carrying one
|
|
209
|
+
gets its benchmarks merged and any disagreement recorded.
|
|
210
|
+
"""
|
|
211
|
+
models: list[Model] = []
|
|
212
|
+
conflicts: list[Conflict] = []
|
|
213
|
+
curated: set[str] = set()
|
|
214
|
+
overrides = load_overrides(overrides_dir)
|
|
215
|
+
for model in load_models(upstream_dir):
|
|
216
|
+
override = overrides.pop(model.model_id, None)
|
|
217
|
+
if override:
|
|
218
|
+
model, found = apply(model, override)
|
|
219
|
+
conflicts.extend(found)
|
|
220
|
+
curated.add(model.model_id)
|
|
221
|
+
models.append(model)
|
|
222
|
+
conflicts.sort(key=lambda c: (c.model_id, c.benchmark))
|
|
223
|
+
return Curated(
|
|
224
|
+
models=models, conflicts=conflicts, curated=curated, orphans=set(overrides)
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def curated_ids(overrides_dir: Path) -> set[str]:
|
|
229
|
+
"""Model ids that carry an override file, applied or not."""
|
|
230
|
+
return set(load_overrides(overrides_dir))
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def off_band_models(models: list[Model]) -> list[tuple[str, float, float, float]]:
|
|
234
|
+
"""Models whose Terminal-Bench 4.0 sits far from the 2.1→4.0 band.
|
|
235
|
+
|
|
236
|
+
Returns ``(model id, 2.1 score, 4.0 score, residual)`` sorted by how
|
|
237
|
+
far off the pair sits. The band is fitted on vendor-sourced pairs
|
|
238
|
+
(deepseek-v4.1-flash, gemini-3.8-flash, the three MiMo v2.5/v2.6
|
|
239
|
+
pairs) and early 4.0 runs are genuinely noisy, so a hit is a review
|
|
240
|
+
prompt — it justifies no change on its own.
|
|
241
|
+
"""
|
|
242
|
+
slope, intercept = TB40_BAND
|
|
243
|
+
out: list[tuple[str, float, float, float]] = []
|
|
244
|
+
for m in models:
|
|
245
|
+
score21 = m.scores.get("Terminal-Bench 2.1")
|
|
246
|
+
score40 = m.scores.get("Terminal-Bench 4.0")
|
|
247
|
+
if score21 is None or score40 is None:
|
|
248
|
+
continue
|
|
249
|
+
residual = score40 - (slope * score21 + intercept)
|
|
250
|
+
if abs(residual) > TB40_BAND_SLACK:
|
|
251
|
+
out.append((m.model_id, score21, score40, residual))
|
|
252
|
+
return sorted(out, key=lambda row: -abs(row[3]))
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Pareto frontier of models over (price, score).
|
|
2
|
+
|
|
3
|
+
A model is on the frontier when no other model is both cheaper and scores
|
|
4
|
+
higher (or equal on one axis and strictly better on the other). Input price
|
|
5
|
+
in USD per 1M tokens is the cost axis; the chosen benchmark's score is the
|
|
6
|
+
quality axis. Models lacking a price or that benchmark's score cannot be
|
|
7
|
+
placed and are excluded.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from .data import Model
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def frontier(models: list[Model], benchmark: str) -> list[Model]:
|
|
16
|
+
"""Return the price-vs-score Pareto set, cheapest first.
|
|
17
|
+
|
|
18
|
+
On an exact (price, score) tie the earlier model in the input wins.
|
|
19
|
+
"""
|
|
20
|
+
competitors = [
|
|
21
|
+
m for m in models if m.price_input is not None and benchmark in m.scores
|
|
22
|
+
]
|
|
23
|
+
kept: list[Model] = []
|
|
24
|
+
# Cheapest first; on equal price, highest score first — so the tie-winner
|
|
25
|
+
# is decided before any comparison happens.
|
|
26
|
+
for m in sorted(competitors, key=lambda m: (m.price_input, -m.scores[benchmark])):
|
|
27
|
+
if any(
|
|
28
|
+
k.price_input <= m.price_input
|
|
29
|
+
and k.scores[benchmark] >= m.scores[benchmark]
|
|
30
|
+
for k in kept
|
|
31
|
+
):
|
|
32
|
+
continue
|
|
33
|
+
kept.append(m)
|
|
34
|
+
return kept
|