Repository navigation
Model price profiles: one entry per model, exact price matching, max price for unmatched models - #218
Merged
Merged
Conversation
…ls the max price - model_cost/model_profiles.yaml is now the source of truth for prices: one profile per model with aliases; model_cost.json is generated from it by scripts/pricing/build_model_cost.py (--check verifies it is in sync). - Duplicate spellings are folded into aliases where that moves no score. Three models stay double-profiled with a conflict note (qwen3-235b, claude-haiku-4.5, qwen3-30b) because different board entries are charged different prices for them today. - Evaluator: price lookup is exact id/alias only (the substring fallback is removed). Spellings that relied on it are added as explicit aliases. - A model with no price profile is charged the highest input/output price in the table instead of $0, and an unknown model name is graded and charged rather than dropped. The submission check warns instead of failing. - Re-pricing all 265,568 rows in router_inference/predictions gives identical costs before and after. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Runs scripts/pricing/build_model_cost.py --check whenever model_cost/ or scripts/pricing/ changes, locally and in the Pre-commit CI job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 29, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every name a price can be looked up by is now an id or alias of one profile: the 136 model_cost.json keys on main, the profile ids and aliases, and every model name billed in a prediction file (routed or served). 144 names become 106 profiles; 75 are keyed by the model's OpenRouter id, and the other spellings (provider prefix, date, effort suffix such as @high, provider_model) are aliases. With exact matching, every row of every leaderboard router now finds a price; before, some were priced only by the substring fallback (e.g. deepseek/deepseek-reasoner, anthropic/claude-sonnet-4). Prices are not synced here. Each profile keeps the price the evaluator charges most of that model's rows today; spellings that had a different price are listed in the profile's note (8 table entries change, e.g. claude-haiku-4-5 0.80/4.00 -> 1.00/5.00, OrcaRouter's Alibaba spelling of qwen3-235b 0.50/2.00 -> 0.071/0.10). Re-costing the leaderboard with this table moves two routers: OrcaRouter 72.41 -> 72.49, Hybrid Router 72.15 -> 72.13. Profiles without an OpenRouter id: models retired from OpenRouter (grok-4-1-fast-reasoning, claude-sonnet-4, claude-3-haiku), DeepSeek's API names (deepseek-reasoner), models never listed (agnes-2.0-flash, GLM-4-9B-0414, DeepSeek-R1-0528-Qwen3-8B, glm-4-air), and unused older entries. README: new models are added to model_profiles.yaml, and model_cost.json is regenerated from it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduces model price profiles as the single source of truth for prices, makes price lookup exact, and charges models with no price profile the highest price in the table instead of $0. Prices are not synced to the market here; that is the next PR.
Update (Oct 31): merged with
main, one entry per modelMerge: brings in
main, including the 31 price entries added by submissions since September (BizRouter, NuRoute, Divyam, DT-Router, Corealis, …).One profile per model. Every name a price can be looked up by is now an id or alias of exactly one profile. That covers the
model_cost.jsonkeys, the earlier profiles, and every model name billed in a prediction file, whether routed or served (model_used).@high,provider_model) are aliases.deepseek/deepseek-reasoner,anthropic/claude-sonnet-4and Lynkr'sopenai/gpt-oss-120bwere priced only by the substring fallback.Prices kept, not synced. Each profile keeps the price the evaluator charges most of that model's rows today. Spellings that had another price are listed in the profile's
note. 8 table entries change:claude-haiku-4-5claude-haiku-4.5qwen3-235b-a22b-instruct-2507qwen/qwen3-235b-a22b-2507(OrcaRouter's Alibaba spelling)qwen/qwen3-30b-a3b-instruct-2507glm-5.3-flash,z-ai/glm-5.3-flashz-ai/glm-5.3-flash@defaultdeepseek-v3.2,openai_gpt-oss-120b,qwen_qwen3-235b-a22b-2507Re-costing the leaderboard with this table moves two routers: OrcaRouter 72.41 → 72.49 and Hybrid Router 72.15 → 72.13. The README isn't re-priced in this PR.
No OpenRouter id:
grok-4-1-fast-reasoning,claude-sonnet-4,claude-3-haiku;deepseek-reasoner;agnes-2.0-flash,GLM-4-9B-0414,DeepSeek-R1-0528-Qwen3-8B,glm-4-air;README: submitters add new models to
model_profiles.yamland regeneratemodel_cost.json.What this PR changes overall
model_cost/model_profiles.yaml(new): one profile per model with its price (USD per 1M input/output tokens), aliases,as_of,sourceandnote.scripts/pricing/build_model_cost.py(new): generatesmodel_cost.jsonfrom the profiles, so the evaluator, the/evaluatebot and other tools keep reading the same file.--checkfails if the JSON was edited by hand. It's wired in as a pre-commit hook, so CI runs it.evaluate_models.py): price lookup is exact id or alias only, with no substring fallback. A model with no price profile is charged the table's highest input and output price. It's warned about once per name and summarized at the end of the run.run.py: a row whose model name isn't inuniversal_model_names.pyis now graded and charged the maximum price, instead of being dropped from the results.Testing
tests/test_pricing.py, 7)main's evaluator🤖 Generated with Claude Code