From 8c7496099bfaa095bb0f9808dcf44c187be1f07b Mon Sep 17 00:00:00 2001 From: Parallel Entrepreneur <40026523+ParallelEntrepreneur@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:37:12 +0800 Subject: [PATCH] feat(#71): token math per model - add per-model quota weights and estimates Add optional model_weights array to subscriptions to enable per-model token math. Implement schema changes, validator rules, and build logic to compute estimates_by_model. For Z.AI GLM plans, populate weights for GLM-5.3 (6.9/1.7/24) and GLM-5.3-Flash (2.3/0.56/8) from https://docs.z.ai/devpack/overview. Build computes per-model estimates showing Flash yields 3x more tokens/month at 1/3 the cost per token. - Schema: Add model_weights[], default_model, estimates_by_model to subscriptions - Validator: Enforce that every weight's model is in models_included - Build: Compute estimates_by_model using STANDARD profile and per-model credit conversions - Tests: Verify GLM-5.3 estimate matches top-level; Flash yields more tokens at lower cost - API: Worker does not yet serve subscription data (skipped per #71 scope) Co-authored-by: Colonizer Settlers <331648616+colonizer-settlers@users.noreply.github.com> --- data/pricing.json | 1043 +++++++++++++++++++++++---------------- docs/SCHEMA.md | 18 + schema/pricing.v1.json | 59 +++ tools/build.mjs | 92 +++- tools/math.test.mjs | 30 ++ tools/validate.mjs | 29 ++ tools/validate.test.mjs | 42 ++ 7 files changed, 876 insertions(+), 437 deletions(-) diff --git a/data/pricing.json b/data/pricing.json index 597426b..b513933 100644 --- a/data/pricing.json +++ b/data/pricing.json @@ -711,7 +711,7 @@ "output_per_mtok": 50, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": 12.5, - "blended_3to1": 20.0 + "blended_3to1": 20 }, "last_verified_at": "2026-10-05", "provenance": { @@ -769,7 +769,7 @@ "output_per_mtok": 50, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": 12.5, - "blended_3to1": 20.0 + "blended_3to1": 20 }, "last_verified_at": "2026-10-05", "provenance": { @@ -827,7 +827,7 @@ "output_per_mtok": 20, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 5, - "blended_3to1": 8.0 + "blended_3to1": 8 }, "last_verified_at": "2026-10-05", "provenance": { @@ -886,7 +886,7 @@ "output_per_mtok": 25, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": 6.25, - "blended_3to1": 10.0 + "blended_3to1": 10 }, "last_verified_at": "2026-10-05", "provenance": { @@ -944,7 +944,7 @@ "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -1003,7 +1003,7 @@ "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -1061,7 +1061,7 @@ "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": 3.75, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -1119,7 +1119,7 @@ "output_per_mtok": 5, "cached_input_per_mtok": 0.1, "cache_write_per_mtok": 1.25, - "blended_3to1": 2.0 + "blended_3to1": 2 }, "last_verified_at": "2026-10-05", "provenance": { @@ -1153,7 +1153,7 @@ "currency": "USD", "input_per_mtok": 10, "output_per_mtok": 50, - "cached_input_per_mtok": 1.0, + "cached_input_per_mtok": 1, "cache_write_per_mtok": 12.5, "batch_discount_pct": 50, "offpeak": null, @@ -1175,9 +1175,9 @@ "usd": { "input_per_mtok": 10, "output_per_mtok": 50, - "cached_input_per_mtok": 1.0, + "cached_input_per_mtok": 1, "cache_write_per_mtok": 12.5, - "blended_3to1": 20.0 + "blended_3to1": 20 }, "last_verified_at": "2026-10-05", "provenance": { @@ -1235,7 +1235,7 @@ "output_per_mtok": 10, "cached_input_per_mtok": 0.1, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -1293,7 +1293,7 @@ "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -1409,7 +1409,7 @@ "output_per_mtok": 20, "cached_input_per_mtok": 0.4, "cache_write_per_mtok": 5, - "blended_3to1": 8.0 + "blended_3to1": 8 }, "last_verified_at": "2026-10-05", "provenance": { @@ -1790,7 +1790,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": null, "batch_discount_pct": 50, @@ -1812,7 +1812,7 @@ }, "usd": { "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": null, "blended_3to1": 3.375 @@ -1963,8 +1963,8 @@ "model_creator": "google", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 12.0, + "input_per_mtok": 2, + "output_per_mtok": 12, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": null, "batch_discount_pct": 50, @@ -1985,8 +1985,8 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 12.0, + "input_per_mtok": 2, + "output_per_mtok": 12, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": null, "blended_3to1": 4.5 @@ -2022,7 +2022,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 1.25, - "output_per_mtok": 10.0, + "output_per_mtok": 10, "cached_input_per_mtok": 0.125, "cache_write_per_mtok": null, "batch_discount_pct": 50, @@ -2044,7 +2044,7 @@ }, "usd": { "input_per_mtok": 1.25, - "output_per_mtok": 10.0, + "output_per_mtok": 10, "cached_input_per_mtok": 0.125, "cache_write_per_mtok": null, "blended_3to1": 3.4375 @@ -2195,8 +2195,8 @@ "model_creator": "xai", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -2217,11 +2217,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -2253,8 +2253,8 @@ "model_creator": "xai", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": "unknown", "batch_discount_pct": 0, @@ -2275,11 +2275,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -2311,8 +2311,8 @@ "model_creator": "xai", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": "unknown", "batch_discount_pct": 0, @@ -2333,11 +2333,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -2485,8 +2485,8 @@ "model_creator": "xai", "open_weights": false, "currency": "USD", - "input_per_mtok": 1.0, - "output_per_mtok": 2.0, + "input_per_mtok": 1, + "output_per_mtok": 2, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": "unknown", "batch_discount_pct": 0, @@ -2507,8 +2507,8 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 1.0, - "output_per_mtok": 2.0, + "input_per_mtok": 1, + "output_per_mtok": 2, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": null, "blended_3to1": 1.25 @@ -2569,7 +2569,7 @@ "output_per_mtok": 7.5, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -2949,8 +2949,8 @@ "model_creator": "cohere", "open_weights": true, "currency": "USD", - "input_per_mtok": 0.0, - "output_per_mtok": 0.0, + "input_per_mtok": 0, + "output_per_mtok": 0, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -2971,11 +2971,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 0.0, - "output_per_mtok": 0.0, + "input_per_mtok": 0, + "output_per_mtok": 0, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 0.0 + "blended_3to1": 0 }, "last_verified_at": "2026-10-05", "provenance": { @@ -3124,7 +3124,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 2.5, - "output_per_mtok": 10.0, + "output_per_mtok": 10, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -3146,7 +3146,7 @@ }, "usd": { "input_per_mtok": 2.5, - "output_per_mtok": 10.0, + "output_per_mtok": 10, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 4.375 @@ -3323,7 +3323,7 @@ "output_per_mtok": 1, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 1.0 + "blended_3to1": 1 }, "last_verified_at": "2026-10-05", "provenance": { @@ -3381,7 +3381,7 @@ "output_per_mtok": 15, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -3555,7 +3555,7 @@ "output_per_mtok": 6, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -3762,7 +3762,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 1.25, - "output_per_mtok": 10.0, + "output_per_mtok": 10, "cached_input_per_mtok": 0.3125, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -3784,7 +3784,7 @@ }, "usd": { "input_per_mtok": 1.25, - "output_per_mtok": 10.0, + "output_per_mtok": 10, "cached_input_per_mtok": 0.3125, "cache_write_per_mtok": null, "blended_3to1": 3.4375 @@ -3903,7 +3903,7 @@ "output_per_mtok": 12.5, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 5.0 + "blended_3to1": 5 }, "last_verified_at": "2026-10-05", "provenance": { @@ -4109,8 +4109,8 @@ "model_creator": "writer", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 8.0, + "input_per_mtok": 2, + "output_per_mtok": 8, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -4131,8 +4131,8 @@ "volatility": "low" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 8.0, + "input_per_mtok": 2, + "output_per_mtok": 8, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 3.5 @@ -4168,7 +4168,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 0.6, - "output_per_mtok": 6.0, + "output_per_mtok": 6, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -4190,7 +4190,7 @@ }, "usd": { "input_per_mtok": 0.6, - "output_per_mtok": 6.0, + "output_per_mtok": 6, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 1.95 @@ -4226,7 +4226,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 2.5, - "output_per_mtok": 10.0, + "output_per_mtok": 10, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -4248,7 +4248,7 @@ }, "usd": { "input_per_mtok": 2.5, - "output_per_mtok": 10.0, + "output_per_mtok": 10, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 4.375 @@ -4457,8 +4457,8 @@ "model_creator": "sakana", "open_weights": false, "currency": "USD", - "input_per_mtok": 5.0, - "output_per_mtok": 30.0, + "input_per_mtok": 5, + "output_per_mtok": 30, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -4479,8 +4479,8 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 5.0, - "output_per_mtok": 30.0, + "input_per_mtok": 5, + "output_per_mtok": 30, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": null, "blended_3to1": 11.25 @@ -4515,8 +4515,8 @@ "model_creator": "sakana", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -4537,11 +4537,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -4574,7 +4574,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -4596,7 +4596,7 @@ }, "usd": { "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": null, "blended_3to1": 1.7125 @@ -4982,8 +4982,8 @@ "model_creator": "deepseek", "open_weights": true, "currency": "CNY", - "input_per_mtok": 9.0, - "output_per_mtok": 27.0, + "input_per_mtok": 9, + "output_per_mtok": 27, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, "batch_discount_pct": null, @@ -5041,8 +5041,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": "unknown", "batch_discount_pct": 40, @@ -5063,11 +5063,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -5100,7 +5100,7 @@ "open_weights": "unknown", "currency": "USD", "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.19, "cache_write_per_mtok": null, "batch_discount_pct": 40, @@ -5122,7 +5122,7 @@ }, "usd": { "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.19, "cache_write_per_mtok": null, "blended_3to1": 1.7125 @@ -5158,7 +5158,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.16, "cache_write_per_mtok": null, "batch_discount_pct": 40, @@ -5180,7 +5180,7 @@ }, "usd": { "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.16, "cache_write_per_mtok": null, "blended_3to1": 1.7125 @@ -5215,9 +5215,9 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "CNY", - "input_per_mtok": 20.0, - "output_per_mtok": 100.0, - "cached_input_per_mtok": 2.0, + "input_per_mtok": 20, + "output_per_mtok": 100, + "cached_input_per_mtok": 2, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", "offpeak": null, @@ -5275,7 +5275,7 @@ "open_weights": true, "currency": "CNY", "input_per_mtok": 6.5, - "output_per_mtok": 27.0, + "output_per_mtok": 27, "cached_input_per_mtok": 1.1, "cache_write_per_mtok": null, "batch_discount_pct": "unknown", @@ -5591,7 +5591,7 @@ "output_per_mtok": 0, "cached_input_per_mtok": 0, "cache_write_per_mtok": null, - "blended_3to1": 0.0 + "blended_3to1": 0 }, "last_verified_at": "2026-10-05", "provenance": { @@ -5822,12 +5822,12 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 0.0, - "output_per_mtok": 0.0, - "cached_input_per_mtok": 0.0, + "input_per_mtok": 0, + "output_per_mtok": 0, + "cached_input_per_mtok": 0, "cache_write_per_mtok": null, "fx_rate_date": "2026-10-02", - "blended_3to1": 0.0 + "blended_3to1": 0 }, "last_verified_at": "2026-10-05", "provenance": { @@ -6177,7 +6177,7 @@ "output_per_mtok": 6, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -6467,7 +6467,7 @@ "output_per_mtok": 5, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 1.25, - "blended_3to1": 2.0 + "blended_3to1": 2 }, "last_verified_at": "2026-10-05", "provenance": { @@ -6735,8 +6735,8 @@ "model_creator": "bytedance", "open_weights": false, "currency": "CNY", - "input_per_mtok": 6.0, - "output_per_mtok": 30.0, + "input_per_mtok": 6, + "output_per_mtok": 30, "cached_input_per_mtok": 1.2, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -6794,8 +6794,8 @@ "model_creator": "bytedance", "open_weights": false, "currency": "CNY", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.6, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -6913,7 +6913,7 @@ "open_weights": false, "currency": "CNY", "input_per_mtok": 3.2, - "output_per_mtok": 16.0, + "output_per_mtok": 16, "cached_input_per_mtok": 0.64, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -6972,7 +6972,7 @@ "open_weights": false, "currency": "CNY", "input_per_mtok": 0.2, - "output_per_mtok": 2.0, + "output_per_mtok": 2, "cached_input_per_mtok": 0.04, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -7030,8 +7030,8 @@ "model_creator": "deepseek", "open_weights": true, "currency": "CNY", - "input_per_mtok": 2.0, - "output_per_mtok": 8.0, + "input_per_mtok": 2, + "output_per_mtok": 8, "cached_input_per_mtok": 0.04, "cache_write_per_mtok": "unknown", "batch_discount_pct": null, @@ -7115,7 +7115,7 @@ "output_per_mtok": 2.5, "cached_input_per_mtok": 0.1, "cache_write_per_mtok": null, - "blended_3to1": 1.0 + "blended_3to1": 1 }, "last_verified_at": "2026-10-05", "provenance": { @@ -7148,7 +7148,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 0.5, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": 0.1, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -7170,7 +7170,7 @@ }, "usd": { "input_per_mtok": 0.5, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": 0.1, "cache_write_per_mtok": null, "blended_3to1": 1.125 @@ -7206,7 +7206,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 0.25, - "output_per_mtok": 2.0, + "output_per_mtok": 2, "cached_input_per_mtok": 0.05, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -7228,7 +7228,7 @@ }, "usd": { "input_per_mtok": 0.25, - "output_per_mtok": 2.0, + "output_per_mtok": 2, "cached_input_per_mtok": 0.05, "cache_write_per_mtok": null, "blended_3to1": 0.6875 @@ -8144,7 +8144,7 @@ "model_creator": "stepfun", "open_weights": "unknown", "currency": "USD", - "input_per_mtok": 1.0, + "input_per_mtok": 1, "output_per_mtok": 2.7, "cached_input_per_mtok": 0.05, "cache_write_per_mtok": null, @@ -8166,7 +8166,7 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 1.0, + "input_per_mtok": 1, "output_per_mtok": 2.7, "cached_input_per_mtok": 0.05, "cache_write_per_mtok": null, @@ -8908,8 +8908,8 @@ "model_creator": "deepseek", "open_weights": true, "currency": "CNY", - "input_per_mtok": 3.0, - "output_per_mtok": 9.0, + "input_per_mtok": 3, + "output_per_mtok": 9, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, "batch_discount_pct": "unknown", @@ -9435,8 +9435,8 @@ "model_creator": "qwen", "open_weights": "unknown", "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": null, "batch_discount_pct": "unknown", @@ -9457,11 +9457,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -9493,8 +9493,8 @@ "model_creator": "xiaomi", "open_weights": "unknown", "currency": "CNY", - "input_per_mtok": 3.0, - "output_per_mtok": 6.0, + "input_per_mtok": 3, + "output_per_mtok": 6, "cached_input_per_mtok": 0.025, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -9552,8 +9552,8 @@ "model_creator": "xiaomi", "open_weights": "unknown", "currency": "CNY", - "input_per_mtok": 1.0, - "output_per_mtok": 2.0, + "input_per_mtok": 1, + "output_per_mtok": 2, "cached_input_per_mtok": 0.02, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -9611,8 +9611,8 @@ "model_creator": "xiaomi", "open_weights": "unknown", "currency": "CNY", - "input_per_mtok": 30.0, - "output_per_mtok": 60.0, + "input_per_mtok": 30, + "output_per_mtok": 60, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -10077,7 +10077,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.45, - "output_per_mtok": 5.0, + "output_per_mtok": 5, "cached_input_per_mtok": 0.4, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -10099,7 +10099,7 @@ }, "usd": { "input_per_mtok": 0.45, - "output_per_mtok": 5.0, + "output_per_mtok": 5, "cached_input_per_mtok": 0.4, "cache_write_per_mtok": null, "blended_3to1": 1.5875 @@ -10250,8 +10250,8 @@ "model_creator": "qwen", "open_weights": true, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -10272,11 +10272,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -10773,7 +10773,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.67, - "output_per_mtok": 14.0, + "output_per_mtok": 14, "cached_input_per_mtok": 0.22, "cache_write_per_mtok": "unknown", "batch_discount_pct": -240, @@ -10795,7 +10795,7 @@ }, "usd": { "input_per_mtok": 0.67, - "output_per_mtok": 14.0, + "output_per_mtok": 14, "cached_input_per_mtok": 0.22, "cache_write_per_mtok": null, "blended_3to1": 4.0025 @@ -10831,7 +10831,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.16, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -10853,7 +10853,7 @@ }, "usd": { "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.16, "cache_write_per_mtok": null, "blended_3to1": 1.7125 @@ -11178,10 +11178,10 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, - "cache_write_per_mtok": 5.0, + "cache_write_per_mtok": 5, "batch_discount_pct": 50, "offpeak": null, "tiered_pricing": null, @@ -11200,11 +11200,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, - "cache_write_per_mtok": 5.0, - "blended_3to1": 8.0 + "cache_write_per_mtok": 5, + "blended_3to1": 8 }, "last_verified_at": "2026-10-05", "provenance": { @@ -11236,8 +11236,8 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, "batch_discount_pct": 50, @@ -11258,11 +11258,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -11294,8 +11294,8 @@ "model_creator": "openai", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, "batch_discount_pct": 50, @@ -11316,11 +11316,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -11410,8 +11410,8 @@ "model_creator": "openai", "open_weights": false, "currency": "USD", - "input_per_mtok": 5.0, - "output_per_mtok": 30.0, + "input_per_mtok": 5, + "output_per_mtok": 30, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -11432,8 +11432,8 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 5.0, - "output_per_mtok": 30.0, + "input_per_mtok": 5, + "output_per_mtok": 30, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": null, "blended_3to1": 11.25 @@ -11527,7 +11527,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": 0.083333, "batch_discount_pct": 50, @@ -11549,7 +11549,7 @@ }, "usd": { "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": 0.083333, "blended_3to1": 3.375 @@ -11584,8 +11584,8 @@ "model_creator": "google", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 12.0, + "input_per_mtok": 2, + "output_per_mtok": 12, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 0.375, "batch_discount_pct": 50, @@ -11606,8 +11606,8 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 12.0, + "input_per_mtok": 2, + "output_per_mtok": 12, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 0.375, "blended_3to1": 4.5 @@ -11758,8 +11758,8 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -11780,11 +11780,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": null, - "blended_3to1": 8.0 + "blended_3to1": 8 }, "last_verified_at": "2026-10-05", "provenance": { @@ -11933,7 +11933,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.9, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -11955,7 +11955,7 @@ }, "usd": { "input_per_mtok": 0.9, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": null, "blended_3to1": 1.675 @@ -12222,8 +12222,8 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -12244,11 +12244,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -12338,8 +12338,8 @@ "model_creator": "qwen", "open_weights": true, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -12360,11 +12360,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -12687,7 +12687,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.45, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": 0.22, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -12709,7 +12709,7 @@ }, "usd": { "input_per_mtok": 0.45, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": 0.22, "cache_write_per_mtok": null, "blended_3to1": 1.0875 @@ -12745,7 +12745,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -12767,7 +12767,7 @@ }, "usd": { "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 3.375 @@ -13324,8 +13324,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -13346,11 +13346,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -13582,7 +13582,7 @@ "output_per_mtok": 3.2, "cached_input_per_mtok": 0.135, "cache_write_per_mtok": null, - "blended_3to1": 2.0 + "blended_3to1": 2 }, "last_verified_at": "2026-10-05", "provenance": { @@ -13615,7 +13615,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.42, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": 0.085, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -13637,7 +13637,7 @@ }, "usd": { "input_per_mtok": 0.42, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": 0.085, "cache_write_per_mtok": null, "blended_3to1": 1.065 @@ -13672,8 +13672,8 @@ "model_creator": "qwen", "open_weights": true, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -13694,11 +13694,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -14310,8 +14310,8 @@ "model_creator": "qwen", "open_weights": true, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -14332,11 +14332,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.25, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -14369,7 +14369,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.5, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": 0.1, "cache_write_per_mtok": 0.625, "batch_discount_pct": "unknown", @@ -14391,7 +14391,7 @@ }, "usd": { "input_per_mtok": 0.5, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": 0.1, "cache_write_per_mtok": 0.625, "blended_3to1": 1.125 @@ -14426,10 +14426,10 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, - "cache_write_per_mtok": 5.0, + "cache_write_per_mtok": 5, "batch_discount_pct": "unknown", "offpeak": null, "tiered_pricing": null, @@ -14448,11 +14448,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, - "cache_write_per_mtok": 5.0, - "blended_3to1": 8.0 + "cache_write_per_mtok": 5, + "blended_3to1": 8 }, "last_verified_at": "2026-10-05", "provenance": { @@ -14484,8 +14484,8 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, "batch_discount_pct": "unknown", @@ -14506,11 +14506,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -14891,7 +14891,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -14913,7 +14913,7 @@ }, "usd": { "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": null, "blended_3to1": 3.375 @@ -15297,7 +15297,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.16, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -15319,7 +15319,7 @@ }, "usd": { "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.16, "cache_write_per_mtok": null, "blended_3to1": 1.7125 @@ -15354,8 +15354,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -15376,11 +15376,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -15412,8 +15412,8 @@ "model_creator": "openai", "open_weights": false, "currency": "USD", - "input_per_mtok": 5.0, - "output_per_mtok": 30.0, + "input_per_mtok": 5, + "output_per_mtok": 30, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -15434,8 +15434,8 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 5.0, - "output_per_mtok": 30.0, + "input_per_mtok": 5, + "output_per_mtok": 30, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": null, "blended_3to1": 11.25 @@ -15528,8 +15528,8 @@ "model_creator": "openai", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, "batch_discount_pct": "unknown", @@ -15550,11 +15550,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -16050,8 +16050,8 @@ "model_creator": "qwen", "open_weights": true, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -16072,11 +16072,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -16514,10 +16514,10 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, - "cache_write_per_mtok": 15.0, + "cache_write_per_mtok": 15, "batch_discount_pct": "unknown", "offpeak": null, "tiered_pricing": null, @@ -16536,11 +16536,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, - "cache_write_per_mtok": 15.0, - "blended_3to1": 6.0 + "cache_write_per_mtok": 15, + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -16573,7 +16573,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.16, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -16595,7 +16595,7 @@ }, "usd": { "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.16, "cache_write_per_mtok": null, "blended_3to1": 1.7125 @@ -16862,10 +16862,10 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, - "cache_write_per_mtok": 5.0, + "cache_write_per_mtok": 5, "batch_discount_pct": "unknown", "offpeak": null, "tiered_pricing": null, @@ -16884,11 +16884,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, - "cache_write_per_mtok": 5.0, - "blended_3to1": 8.0 + "cache_write_per_mtok": 5, + "blended_3to1": 8 }, "last_verified_at": "2026-10-05", "provenance": { @@ -16920,8 +16920,8 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, "batch_discount_pct": "unknown", @@ -16942,11 +16942,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -16978,8 +16978,8 @@ "model_creator": "openai", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, "batch_discount_pct": "unknown", @@ -17000,11 +17000,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -17094,8 +17094,8 @@ "model_creator": "openai", "open_weights": false, "currency": "USD", - "input_per_mtok": 5.0, - "output_per_mtok": 30.0, + "input_per_mtok": 5, + "output_per_mtok": 30, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -17116,8 +17116,8 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 5.0, - "output_per_mtok": 30.0, + "input_per_mtok": 5, + "output_per_mtok": 30, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": null, "blended_3to1": 11.25 @@ -17211,7 +17211,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": 1.583, "batch_discount_pct": "unknown", @@ -17233,7 +17233,7 @@ }, "usd": { "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": 1.583, "blended_3to1": 3.375 @@ -17674,8 +17674,8 @@ "model_creator": "qwen", "open_weights": true, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -17696,11 +17696,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -17791,7 +17791,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.45, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -17813,7 +17813,7 @@ }, "usd": { "input_per_mtok": 0.45, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 1.0875 @@ -18313,7 +18313,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.9, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -18335,7 +18335,7 @@ }, "usd": { "input_per_mtok": 0.9, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 1.675 @@ -18602,8 +18602,8 @@ "model_creator": "deepseek", "open_weights": true, "currency": "USD", - "input_per_mtok": 1.0, - "output_per_mtok": 1.0, + "input_per_mtok": 1, + "output_per_mtok": 1, "cached_input_per_mtok": 0.1, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -18624,11 +18624,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 1.0, - "output_per_mtok": 1.0, + "input_per_mtok": 1, + "output_per_mtok": 1, "cached_input_per_mtok": 0.1, "cache_write_per_mtok": null, - "blended_3to1": 1.0 + "blended_3to1": 1 }, "last_verified_at": "2026-10-05", "provenance": { @@ -18661,7 +18661,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.45, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": 0.045, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -18683,7 +18683,7 @@ }, "usd": { "input_per_mtok": 0.45, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": 0.045, "cache_write_per_mtok": null, "blended_3to1": 1.0875 @@ -18892,8 +18892,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -18914,11 +18914,11 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -19008,7 +19008,7 @@ "model_creator": "deepseek", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, + "input_per_mtok": 3, "output_per_mtok": 4.5, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", @@ -19030,7 +19030,7 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 3.0, + "input_per_mtok": 3, "output_per_mtok": 4.5, "cached_input_per_mtok": null, "cache_write_per_mtok": null, @@ -19788,7 +19788,7 @@ "output_per_mtok": 3.2, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 2.0 + "blended_3to1": 2 }, "last_verified_at": "2026-10-05", "provenance": { @@ -19878,8 +19878,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -19900,11 +19900,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -20168,8 +20168,8 @@ "model_creator": "qwen", "open_weights": true, "currency": "USD", - "input_per_mtok": 1.0, - "output_per_mtok": 4.0, + "input_per_mtok": 1, + "output_per_mtok": 4, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -20190,8 +20190,8 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 1.0, - "output_per_mtok": 4.0, + "input_per_mtok": 1, + "output_per_mtok": 4, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 1.75 @@ -20285,7 +20285,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.4, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -20307,7 +20307,7 @@ }, "usd": { "input_per_mtok": 0.4, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 1.05 @@ -20632,8 +20632,8 @@ "model_creator": "qwen", "open_weights": true, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -20654,11 +20654,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 6.0, + "input_per_mtok": 2, + "output_per_mtok": 6, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 3.0 + "blended_3to1": 3 }, "last_verified_at": "2026-10-05", "provenance": { @@ -20864,8 +20864,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -20886,11 +20886,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -21271,7 +21271,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.8, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -21293,7 +21293,7 @@ }, "usd": { "input_per_mtok": 0.8, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 1.6 @@ -21386,8 +21386,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -21408,11 +21408,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -22140,8 +22140,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -22162,11 +22162,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -22257,7 +22257,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 3.75, - "output_per_mtok": 10.0, + "output_per_mtok": 10, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -22279,7 +22279,7 @@ }, "usd": { "input_per_mtok": 3.75, - "output_per_mtok": 10.0, + "output_per_mtok": 10, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 5.3125 @@ -23022,7 +23022,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.67, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -23044,7 +23044,7 @@ }, "usd": { "input_per_mtok": 0.67, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 1.5025 @@ -23313,7 +23313,7 @@ "open_weights": true, "currency": "CHF", "input_per_mtok": 0.6, - "output_per_mtok": 3.0, + "output_per_mtok": 3, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -23722,7 +23722,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -23744,7 +23744,7 @@ }, "usd": { "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 1.7125 @@ -23953,8 +23953,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -23975,11 +23975,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -24534,7 +24534,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.35, - "output_per_mtok": 1.0, + "output_per_mtok": 1, "cached_input_per_mtok": 0.17, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -24556,7 +24556,7 @@ }, "usd": { "input_per_mtok": 0.35, - "output_per_mtok": 1.0, + "output_per_mtok": 1, "cached_input_per_mtok": 0.17, "cache_write_per_mtok": null, "blended_3to1": 0.5125 @@ -24998,7 +24998,7 @@ "open_weights": false, "currency": "USD", "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -25020,7 +25020,7 @@ }, "usd": { "input_per_mtok": 1.5, - "output_per_mtok": 9.0, + "output_per_mtok": 9, "cached_input_per_mtok": 0.15, "cache_write_per_mtok": null, "blended_3to1": 3.375 @@ -25055,8 +25055,8 @@ "model_creator": "google", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 12.0, + "input_per_mtok": 2, + "output_per_mtok": 12, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -25077,8 +25077,8 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 12.0, + "input_per_mtok": 2, + "output_per_mtok": 12, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": null, "blended_3to1": 4.5 @@ -25113,10 +25113,10 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, - "cache_write_per_mtok": 5.0, + "cache_write_per_mtok": 5, "batch_discount_pct": "unknown", "offpeak": null, "tiered_pricing": null, @@ -25135,11 +25135,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, - "cache_write_per_mtok": 5.0, - "blended_3to1": 8.0 + "cache_write_per_mtok": 5, + "blended_3to1": 8 }, "last_verified_at": "2026-10-05", "provenance": { @@ -25171,8 +25171,8 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, "batch_discount_pct": 50, @@ -25193,11 +25193,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -26099,8 +26099,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": 45, @@ -26121,11 +26121,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -26215,10 +26215,10 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, - "cache_write_per_mtok": 5.0, + "cache_write_per_mtok": 5, "batch_discount_pct": "unknown", "offpeak": null, "tiered_pricing": null, @@ -26237,11 +26237,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 4.0, - "output_per_mtok": 20.0, + "input_per_mtok": 4, + "output_per_mtok": 20, "cached_input_per_mtok": 0.2, - "cache_write_per_mtok": 5.0, - "blended_3to1": 8.0 + "cache_write_per_mtok": 5, + "blended_3to1": 8 }, "last_verified_at": "2026-10-05", "provenance": { @@ -26273,8 +26273,8 @@ "model_creator": "anthropic", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, "batch_discount_pct": "unknown", @@ -26295,11 +26295,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -26331,8 +26331,8 @@ "model_creator": "openai", "open_weights": false, "currency": "USD", - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, "batch_discount_pct": "unknown", @@ -26353,11 +26353,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 2.0, - "output_per_mtok": 10.0, + "input_per_mtok": 2, + "output_per_mtok": 10, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": 2.5, - "blended_3to1": 4.0 + "blended_3to1": 4 }, "last_verified_at": "2026-10-05", "provenance": { @@ -26447,8 +26447,8 @@ "model_creator": "openai", "open_weights": false, "currency": "USD", - "input_per_mtok": 5.0, - "output_per_mtok": 30.0, + "input_per_mtok": 5, + "output_per_mtok": 30, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": "unknown", "batch_discount_pct": 50, @@ -26469,8 +26469,8 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 5.0, - "output_per_mtok": 30.0, + "input_per_mtok": 5, + "output_per_mtok": 30, "cached_input_per_mtok": 0.5, "cache_write_per_mtok": null, "blended_3to1": 11.25 @@ -26622,7 +26622,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.25, - "output_per_mtok": 1.0, + "output_per_mtok": 1, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -26644,7 +26644,7 @@ }, "usd": { "input_per_mtok": 0.25, - "output_per_mtok": 1.0, + "output_per_mtok": 1, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 0.4375 @@ -26679,8 +26679,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -26701,11 +26701,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": 0.3, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -26738,7 +26738,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.16, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -26760,7 +26760,7 @@ }, "usd": { "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.16, "cache_write_per_mtok": null, "blended_3to1": 1.7125 @@ -27434,7 +27434,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -27456,7 +27456,7 @@ }, "usd": { "input_per_mtok": 0.95, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": null, "cache_write_per_mtok": null, "blended_3to1": 1.7125 @@ -27491,8 +27491,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": "unknown", "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -27513,11 +27513,11 @@ "volatility": "medium" }, "usd": { - "input_per_mtok": 3.0, - "output_per_mtok": 15.0, + "input_per_mtok": 3, + "output_per_mtok": 15, "cached_input_per_mtok": null, "cache_write_per_mtok": null, - "blended_3to1": 6.0 + "blended_3to1": 6 }, "last_verified_at": "2026-10-05", "provenance": { @@ -28246,7 +28246,7 @@ "open_weights": true, "currency": "USD", "input_per_mtok": 1.2, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -28268,7 +28268,7 @@ }, "usd": { "input_per_mtok": 1.2, - "output_per_mtok": 4.0, + "output_per_mtok": 4, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": null, "blended_3to1": 1.9 @@ -28477,8 +28477,8 @@ "model_creator": "moonshotai", "open_weights": true, "currency": "USD", - "input_per_mtok": 1.0, - "output_per_mtok": 4.0, + "input_per_mtok": 1, + "output_per_mtok": 4, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": "unknown", "batch_discount_pct": "unknown", @@ -28499,8 +28499,8 @@ "volatility": "high" }, "usd": { - "input_per_mtok": 1.0, - "output_per_mtok": 4.0, + "input_per_mtok": 1, + "output_per_mtok": 4, "cached_input_per_mtok": 0.2, "cache_write_per_mtok": null, "blended_3to1": 1.75 @@ -29392,7 +29392,7 @@ ], "fair_use": null, "est_tokens_per_month": 645000000, - "est_usd_per_mtok_at_full_use": 0.0, + "est_usd_per_mtok_at_full_use": 0, "estimate_assumption": "STANDARD: 1 request/prompt/message = 1 agentic model call of 20,000 input tokens (18,000 cache-read + 2,000 uncached) + 1,500 output = 21,500 tokens. Window plans: 4 usable 5h windows/day x 30 days = 120 windows/month, then capped by weekly cap x 30/7 and by any monthly cap (whichever binds first). Dollar-pool plans: pool / blended reference rate for the same token mix at Claude Sonnet 5.5 list ($2 in / $0.20 cache-read / $10 out per Mtok) = $1.0512/Mtok. Gemini CLI: 1 model request = 1 standard call; daily cap x 30 (5h-window app limits are separate and not numeric).", "source": "https://geminicli.com/docs/resources/quota-and-pricing", "checked": "2026-10-05", @@ -30828,11 +30828,11 @@ "price_month": 18, "price_year": null }, - "last_verified_at": "2026-10-05", + "last_verified_at": "2026-10-10", "provenance": { "default": { "source": "https://docs.z.ai/devpack/overview", - "fetched_at": "2026-10-05", + "fetched_at": "2026-10-10", "method": "docs_markdown", "confidence": "official_docs" }, @@ -30841,7 +30841,48 @@ "price_year": "default", "limits_published": "default", "fair_use": "default", - "est_usd_per_mtok_at_full_use": "default" + "est_usd_per_mtok_at_full_use": "default", + "model_weights": "default", + "default_model": "default" + } + }, + "model_weights": [ + { + "model": "glm-5.3", + "input": 6.9, + "cached_input": 1.7, + "output": 24, + "unit": "credits", + "quote": "Model credit usage = (Input tokens × Input multiplier + Cached Input tokens × Cached Input multiplier + Output tokens × Output multiplier) / 10,000 [GLM-5.3: 6.9 / 1.7 / 24]", + "source": "https://docs.z.ai/devpack/overview", + "checked": "2026-10-10" + }, + { + "model": "glm-5.3-flash", + "input": 2.3, + "cached_input": 0.56, + "output": 8, + "unit": "credits", + "quote": "Model credit usage = (Input tokens × Input multiplier + Cached Input tokens × Cached Input multiplier + Output tokens × Output multiplier) / 10,000 [GLM-5.3-Flash: 2.3 / 0.56 / 8]", + "source": "https://docs.z.ai/devpack/overview", + "checked": "2026-10-10" + } + ], + "default_model": "glm-5.3", + "estimates_by_model": { + "glm-5.3": { + "tokens_per_5h": 5348258.706467662, + "tokens_per_week": 26741293.532338314, + "tokens_per_month": 114605544, + "usd_per_mtok_at_full_use": 0.1571, + "binds": "weekly" + }, + "glm-5.3-flash": { + "tokens_per_5h": 16116941.529235382, + "tokens_per_week": 80584707.6461769, + "tokens_per_month": 345363033, + "usd_per_mtok_at_full_use": 0.0521, + "binds": "weekly" } } }, @@ -30897,11 +30938,11 @@ "price_month": 80, "price_year": null }, - "last_verified_at": "2026-10-05", + "last_verified_at": "2026-10-10", "provenance": { "default": { "source": "https://docs.z.ai/devpack/overview", - "fetched_at": "2026-10-05", + "fetched_at": "2026-10-10", "method": "docs_markdown", "confidence": "secondary" }, @@ -30910,7 +30951,40 @@ "price_year": "default", "limits_published": "default", "fair_use": "default", - "est_usd_per_mtok_at_full_use": "default" + "est_usd_per_mtok_at_full_use": "default", + "model_weights": "default", + "default_model": "default" + } + }, + "model_weights": [ + { + "model": "glm-5.3", + "input": 6.9, + "cached_input": 1.7, + "output": 24, + "unit": "credits", + "quote": "Model credit usage = (Input tokens × Input multiplier + Cached Input tokens × Cached Input multiplier + Output tokens × Output multiplier) / 10,000 [GLM-5.3: 6.9 / 1.7 / 24]", + "source": "https://docs.z.ai/devpack/overview", + "checked": "2026-10-10" + }, + { + "model": "glm-5.3-flash", + "input": 2.3, + "cached_input": 0.56, + "output": 8, + "unit": "credits", + "quote": "Model credit usage = (Input tokens × Input multiplier + Cached Input tokens × Cached Input multiplier + Output tokens × Output multiplier) / 10,000 [GLM-5.3-Flash: 2.3 / 0.56 / 8]", + "source": "https://docs.z.ai/devpack/overview", + "checked": "2026-10-10" + } + ], + "default_model": "glm-5.3", + "estimates_by_model": { + "glm-5.3": { + "status": "not_published" + }, + "glm-5.3-flash": { + "status": "not_published" } } }, @@ -30966,11 +31040,11 @@ "price_month": 168, "price_year": null }, - "last_verified_at": "2026-10-05", + "last_verified_at": "2026-10-10", "provenance": { "default": { "source": "https://docs.z.ai/devpack/overview", - "fetched_at": "2026-10-05", + "fetched_at": "2026-10-10", "method": "docs_markdown", "confidence": "secondary" }, @@ -30979,7 +31053,40 @@ "price_year": "default", "limits_published": "default", "fair_use": "default", - "est_usd_per_mtok_at_full_use": "default" + "est_usd_per_mtok_at_full_use": "default", + "model_weights": "default", + "default_model": "default" + } + }, + "model_weights": [ + { + "model": "glm-5.3", + "input": 6.9, + "cached_input": 1.7, + "output": 24, + "unit": "credits", + "quote": "Model credit usage = (Input tokens × Input multiplier + Cached Input tokens × Cached Input multiplier + Output tokens × Output multiplier) / 10,000 [GLM-5.3: 6.9 / 1.7 / 24]", + "source": "https://docs.z.ai/devpack/overview", + "checked": "2026-10-10" + }, + { + "model": "glm-5.3-flash", + "input": 2.3, + "cached_input": 0.56, + "output": 8, + "unit": "credits", + "quote": "Model credit usage = (Input tokens × Input multiplier + Cached Input tokens × Cached Input multiplier + Output tokens × Output multiplier) / 10,000 [GLM-5.3-Flash: 2.3 / 0.56 / 8]", + "source": "https://docs.z.ai/devpack/overview", + "checked": "2026-10-10" + } + ], + "default_model": "glm-5.3", + "estimates_by_model": { + "glm-5.3": { + "status": "not_published" + }, + "glm-5.3-flash": { + "status": "not_published" } } }, @@ -31029,11 +31136,11 @@ "price_month": null, "price_year": null }, - "last_verified_at": "2026-10-05", + "last_verified_at": "2026-10-10", "provenance": { "default": { "source": "https://docs.z.ai/devpack/teamplan", - "fetched_at": "2026-10-05", + "fetched_at": "2026-10-10", "method": "docs_markdown", "confidence": "official_page" }, @@ -31042,7 +31149,46 @@ "price_year": "default", "limits_published": "default", "fair_use": "default", - "est_usd_per_mtok_at_full_use": "default" + "est_usd_per_mtok_at_full_use": "default", + "model_weights": "default", + "default_model": "default" + } + }, + "model_weights": [ + { + "model": "glm-5.3", + "input": 6.9, + "cached_input": 1.7, + "output": 24, + "unit": "credits", + "quote": "Model credit usage = (Input tokens × Input multiplier + Cached Input tokens × Cached Input multiplier + Output tokens × Output multiplier) / 10,000 [GLM-5.3: 6.9 / 1.7 / 24]", + "source": "https://docs.z.ai/devpack/overview", + "checked": "2026-10-10" + }, + { + "model": "glm-5.3-flash", + "input": 2.3, + "cached_input": 0.56, + "output": 8, + "unit": "credits", + "quote": "Model credit usage = (Input tokens × Input multiplier + Cached Input tokens × Cached Input multiplier + Output tokens × Output multiplier) / 10,000 [GLM-5.3-Flash: 2.3 / 0.56 / 8]", + "source": "https://docs.z.ai/devpack/overview", + "checked": "2026-10-10" + } + ], + "default_model": "glm-5.3", + "estimates_by_model": { + "glm-5.3": { + "tokens_per_5h": 40111940.29850747, + "tokens_per_week": 176492537.31343284, + "tokens_per_month": 756396588, + "binds": "weekly" + }, + "glm-5.3-flash": { + "tokens_per_5h": 120877061.46926536, + "tokens_per_week": 531859070.4647676, + "tokens_per_month": 2279396016, + "binds": "weekly" } } }, @@ -31092,11 +31238,11 @@ "price_month": null, "price_year": null }, - "last_verified_at": "2026-10-05", + "last_verified_at": "2026-10-10", "provenance": { "default": { "source": "https://docs.z.ai/devpack/teamplan", - "fetched_at": "2026-10-05", + "fetched_at": "2026-10-10", "method": "docs_markdown", "confidence": "official_page" }, @@ -31105,7 +31251,46 @@ "price_year": "default", "limits_published": "default", "fair_use": "default", - "est_usd_per_mtok_at_full_use": "default" + "est_usd_per_mtok_at_full_use": "default", + "model_weights": "default", + "default_model": "default" + } + }, + "model_weights": [ + { + "model": "glm-5.3", + "input": 6.9, + "cached_input": 1.7, + "output": 24, + "unit": "credits", + "quote": "Model credit usage = (Input tokens × Input multiplier + Cached Input tokens × Cached Input multiplier + Output tokens × Output multiplier) / 10,000 [GLM-5.3: 6.9 / 1.7 / 24]", + "source": "https://docs.z.ai/devpack/overview", + "checked": "2026-10-10" + }, + { + "model": "glm-5.3-flash", + "input": 2.3, + "cached_input": 0.56, + "output": 8, + "unit": "credits", + "quote": "Model credit usage = (Input tokens × Input multiplier + Cached Input tokens × Cached Input multiplier + Output tokens × Output multiplier) / 10,000 [GLM-5.3-Flash: 2.3 / 0.56 / 8]", + "source": "https://docs.z.ai/devpack/overview", + "checked": "2026-10-10" + } + ], + "default_model": "glm-5.3", + "estimates_by_model": { + "glm-5.3": { + "tokens_per_5h": 93594527.3631841, + "tokens_per_week": 414490049.7512438, + "tokens_per_month": 1776385928, + "binds": "weekly" + }, + "glm-5.3-flash": { + "tokens_per_5h": 282046476.7616192, + "tokens_per_week": 1249062968.515742, + "tokens_per_month": 5353127008, + "binds": "weekly" } } }, @@ -33793,7 +33978,7 @@ ], "fair_use": null, "est_tokens_per_month": 2853982, - "est_usd_per_mtok_at_full_use": 0.0, + "est_usd_per_mtok_at_full_use": 0, "estimate_assumption": "STANDARD: 1 request/prompt/message = 1 agentic model call of 20,000 input tokens (18,000 cache-read + 2,000 uncached) + 1,500 output = 21,500 tokens. Window plans: 4 usable 5h windows/day x 30 days = 120 windows/month, then capped by weekly cap x 30/7 and by any monthly cap (whichever binds first). Dollar-pool plans: pool / blended reference rate for the same token mix at Claude Sonnet 5.5 list ($2 in / $0.20 cache-read / $10 out per Mtok) = $1.0512/Mtok.", "source": "https://www.jetbrains.com/help/ai-assistant/licensing-and-subscriptions.html", "checked": "2026-10-05", @@ -34557,7 +34742,7 @@ ], "fair_use": null, "est_tokens_per_month": 10000000, - "est_usd_per_mtok_at_full_use": 3.0, + "est_usd_per_mtok_at_full_use": 3, "estimate_assumption": "Vendor counts tokens directly.", "source": "https://bolt.new/pricing", "checked": "2026-10-05", @@ -34965,7 +35150,7 @@ "gpt-6-sol": { "offers": 5, "cheapest_offer": "azure/gpt-6-sol", - "blended_3to1_usd": 4.0 + "blended_3to1_usd": 4 }, "gpt-6-luna": { "offers": 5, @@ -35025,7 +35210,7 @@ "glm-4.7-flash": { "offers": 2, "cheapest_offer": "zai/glm-4.7-flash-cn", - "blended_3to1_usd": 0.0 + "blended_3to1_usd": 0 }, "minimax-m3": { "offers": 14, @@ -35185,12 +35370,12 @@ "claude-opus-5.5": { "offers": 7, "cheapest_offer": "anthropic/claude-opus-5.5", - "blended_3to1_usd": 8.0 + "blended_3to1_usd": 8 }, "claude-sonnet-5.5": { "offers": 7, "cheapest_offer": "anthropic/claude-sonnet-5.5", - "blended_3to1_usd": 4.0 + "blended_3to1_usd": 4 }, "deepseek-r1": { "offers": 2, diff --git a/docs/SCHEMA.md b/docs/SCHEMA.md index 47152c1..344ba75 100644 --- a/docs/SCHEMA.md +++ b/docs/SCHEMA.md @@ -109,14 +109,32 @@ into one canonical id per lab; the other spellings are `aliases`. | `currency` | ISO 4217 | | `price_month`, `price_year` | number >= 0 \| `null` \| `"unknown"` (`price_year` = total per year if annual billing is offered) | | `models_included` | array of non-empty strings | +| `model_weights` *(optional)* | [model_weights[]](#model_weights) — per-model quota weights, used to compute `estimates_by_model`; may be empty or absent | | `limits_published` | [limits_published[]](#limits_published); may be empty | | `fair_use` | string \| `null` — verbatim fair-use wording | | `est_tokens_per_month`, `est_usd_per_mtok_at_full_use` | number >= 0 \| `"unknown"` | | `estimate_assumption` | non-empty string — how the estimate was derived | +| `default_model` *(optional)* | slug from `models_included` — the model the top-level estimate uses; required if `est_tokens_per_month` is numeric and `model_weights` is non-empty | +| `estimates_by_model` *(optional)* | map of model slug → estimate block (build output, never hand-edited) | | `source`, `checked`, `confidence`, `notes`, `last_verified_at`, `provenance` | as in api_offers[] | | `fetch_recipe`, `usd` | [shared objects](#shared-objects) (`usd` is the subscription block) | | `supersedes` *(optional)* | composite id this row replaces | +### model_weights[] (all fields required) + +Per-model quota weight: the input/cached-input/output credit or token multipliers published for that model. + +| Field | Type | +|---|---| +| `model` | slug from the plan's `models_included` | +| `input` | number >= 0 — input token multiplier | +| `cached_input` | number >= 0 — cached-input token multiplier | +| `output` | number >= 0 — output token multiplier | +| `unit` | `"credits"` \| `"tokens"` — what the multipliers count in | +| `quote` | non-empty string — the multipliers quoted verbatim from the source | +| `source` | non-empty string — the exact URL the weights came from | +| `checked` | ISO date — when the weight was verified | + ### limits_published[] (all fields required) The vendor's limits, quoted verbatim — an estimate never invents a cap. diff --git a/schema/pricing.v1.json b/schema/pricing.v1.json index 129ee50..5ae6a13 100644 --- a/schema/pricing.v1.json +++ b/schema/pricing.v1.json @@ -250,6 +250,50 @@ } } }, + "model_weight": { + "type": "object", + "additionalProperties": false, + "required": ["model", "input", "cached_input", "output", "unit", "quote", "source", "checked"], + "properties": { + "model": { "$ref": "#/$defs/slug" }, + "input": { "type": "number", "minimum": 0 }, + "cached_input": { "type": "number", "minimum": 0 }, + "output": { "type": "number", "minimum": 0 }, + "unit": { + "enum": ["credits", "tokens"], + "description": "The unit that the multipliers count in." + }, + "quote": { + "type": "string", + "minLength": 1, + "description": "The multipliers quoted verbatim from the source." + }, + "source": { + "type": "string", + "minLength": 1, + "description": "The exact URL where the weights came from." + }, + "checked": { "$ref": "#/$defs/iso_date" } + } + }, + "estimate_by_model": { + "type": "object", + "additionalProperties": false, + "properties": { + "tokens_per_5h": { "type": "number", "minimum": 0 }, + "tokens_per_week": { "type": "number", "minimum": 0 }, + "tokens_per_month": { "type": "number", "minimum": 0 }, + "usd_per_mtok_at_full_use": { "type": "number", "minimum": 0 }, + "binds": { + "enum": ["5h_rolling", "daily", "weekly", "monthly"], + "description": "Which window binds the monthly estimate." + }, + "status": { + "enum": ["not_published"], + "description": "When model weights are not published, the estimate is marked 'not_published' instead of computed." + } + } + }, "api_offer": { "type": "object", "additionalProperties": false, @@ -370,6 +414,15 @@ "type": "array", "items": { "type": "string", "minLength": 1 } }, + "model_weights": { + "type": "array", + "items": { "$ref": "#/$defs/model_weight" }, + "description": "Per-model quota weights (input/cached-input/output multipliers). Built from this, estimates_by_model is computed." + }, + "default_model": { + "$ref": "#/$defs/slug", + "description": "The model the top-level estimate uses, when model_weights is non-empty and est_tokens_per_month is numeric." + }, "limits_published": { "type": "array", "items": { "$ref": "#/$defs/limit_entry" } @@ -386,6 +439,12 @@ "minLength": 1, "description": "How the estimate was derived. A numeric estimate must name an assumption profile (the validator enforces this; the dataset's profile is STANDARD, see docs/plan.md §2)." }, + "estimates_by_model": { + "type": "object", + "description": "Per-model token and USD estimates, computed by build.mjs from model_weights.", + "propertyNames": { "$ref": "#/$defs/slug" }, + "additionalProperties": { "$ref": "#/$defs/estimate_by_model" } + }, "source": { "type": "string", "minLength": 1 }, "checked": { "$ref": "#/$defs/iso_date" }, "confidence": { "$ref": "#/$defs/confidence" }, diff --git a/tools/build.mjs b/tools/build.mjs index ca9d632..63766c8 100644 --- a/tools/build.mjs +++ b/tools/build.mjs @@ -1,7 +1,8 @@ #!/usr/bin/env node // Build: recompute every usd{} block and blended_3to1 in data/pricing.json // from the native values and data/fx.json, then refresh the derived -// cheapest-provider ranking and the committed CSV exports' usd_* columns. +// cheapest-provider ranking, the committed CSV exports' usd_* columns, and +// per-model estimates in subscriptions[].estimates_by_model. // Hand-edited usd values are impossible: the validator re-derives them // (docs/fx.md). Usage: npm run build [-- --out ]. @@ -10,9 +11,11 @@ import { dirname, resolve } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import { toUsd, validateFx } from './fx.mjs'; +import { estimateForPlan, round4 } from './math.ts'; const fxFileUrl = new URL('../data/fx.json', import.meta.url); const pricingFileUrl = new URL('../data/pricing.json', import.meta.url); +const profileFileUrl = (name) => new URL(`../data/profiles/${name}.json`, import.meta.url); const rowsOf = (doc, key) => (Array.isArray(doc?.[key]) ? doc[key] : []); @@ -52,6 +55,66 @@ export function subscriptionUsd(row, fx) { return usd; } +/** + * Compute estimates_by_model for a subscription from its model_weights. + * Uses the STANDARD profile to compute per-model estimates. + * Returns a map of model slug → estimate block (or {status: "not_published"} if weights missing). + */ +export function estimatesByModel(row, profile) { + const result = {}; + const weights = Array.isArray(row?.model_weights) ? row.model_weights : []; + const included = new Set(Array.isArray(row?.models_included) ? row.models_included : []); + + for (const weight of weights) { + const modelSlug = weight.model; + if (!included.has(modelSlug)) continue; // Already validated, but skip if not in included + + // Compute conversions for this model's weights + let modelConversions = undefined; + if (weight.unit === 'credits') { + // Calculate credits per standard call for this specific model + const { input_tokens: i, cached_input_tokens: c, output_tokens: o } = profile.call; + modelConversions = { + credits_per_call: ((i - c) * weight.input + c * weight.cached_input + o * weight.output) / 10000, + source: weight.source, + }; + } + + // Build a plan input using this model's weights + const planInput = { + price_usd_per_month: row.price_month === 'unknown' || typeof row.price_month !== 'number' ? 'unknown' : row.price_month, + confidence: row.confidence || 'official_docs', + limits: Array.isArray(row?.limits_published) ? row.limits_published : [], + conversions: modelConversions, + }; + + const estimate = estimateForPlan(planInput, profile); + + if (estimate.estTokensPerMonth === 'unknown') { + result[modelSlug] = { status: 'not_published' }; + } else { + result[modelSlug] = { + tokens_per_5h: estimate.tokensPerWindow ?? undefined, + tokens_per_week: estimate.tokensPerWeek ?? undefined, + tokens_per_month: estimate.estTokensPerMonth, + usd_per_mtok_at_full_use: estimate.estUsdPerMtokAtFullUse === 'unknown' ? undefined : estimate.estUsdPerMtokAtFullUse, + binds: estimate.bindingWindow ?? undefined, + }; + // Remove undefined fields + Object.keys(result[modelSlug]).forEach((k) => result[modelSlug][k] === undefined && delete result[modelSlug][k]); + } + } + + // Mark models in models_included that don't have weights as "not_published" + for (const modelSlug of included) { + if (!result[modelSlug] && !weights.some((w) => w.model === modelSlug)) { + result[modelSlug] = { status: 'not_published' }; + } + } + + return Object.keys(result).length > 0 ? result : undefined; +} + /** Min blend wins; ties break on the smaller row id. */ function rankRows(rows) { const ranked = rows @@ -93,11 +156,12 @@ function rebuildDerived(doc) { /** * Recompute every derived number in `doc` from its native values and `fx`: - * the top-level fx block (a copy), each row's usd block, and the derived - * cheapest-provider ranking. Mutates and returns doc. Throws on a currency - * fx has no rate for — add the rate, never guess one (docs/fx.md). + * the top-level fx block (a copy), each row's usd block, the derived + * cheapest-provider ranking, and per-model estimates (estimates_by_model). + * Mutates and returns doc. Throws on a currency fx has no rate for — add the rate, + * never guess one (docs/fx.md). */ -export function buildDocument(doc, fx) { +export function buildDocument(doc, fx, profile) { doc.fx = { base: fx.base, date: fx.date, @@ -105,7 +169,16 @@ export function buildDocument(doc, fx) { rates: { ...fx.rates }, }; for (const row of rowsOf(doc, 'api_offers')) row.usd = offerUsd(row, fx); - for (const row of rowsOf(doc, 'subscriptions')) row.usd = subscriptionUsd(row, fx); + for (const row of rowsOf(doc, 'subscriptions')) { + row.usd = subscriptionUsd(row, fx); + // Compute per-model estimates if model_weights exist + if (Array.isArray(row.model_weights) && row.model_weights.length > 0 && profile) { + row.estimates_by_model = estimatesByModel(row, profile); + } else { + // Remove estimates_by_model if no weights + delete row.estimates_by_model; + } + } rebuildDerived(doc); return doc; } @@ -297,19 +370,22 @@ export function run(argv, { log = console.log, error = console.error } = {}) { let fx; let doc; + let profile; let originalText; try { fx = JSON.parse(readFileSync(fxFileUrl, 'utf-8')); validateFx(fx, 'data/fx.json'); // a 0 or non-finite rate would divide to a silent wrong usd originalText = readFileSync(pricingFileUrl, 'utf-8'); doc = JSON.parse(originalText); + // Load the STANDARD (agentic-coding-v1) profile for per-model estimates + profile = JSON.parse(readFileSync(profileFileUrl('agentic-coding-v1'), 'utf-8')); } catch (err) { - error(`cannot read inputs (need data/fx.json and data/pricing.json): ${err.message}`); + error(`cannot read inputs (need data/fx.json, data/pricing.json, and data/profiles/agentic-coding-v1.json): ${err.message}`); return 1; } try { - buildDocument(doc, fx); + buildDocument(doc, fx, profile); } catch (err) { error(`${err.message}`); return 1; diff --git a/tools/math.test.mjs b/tools/math.test.mjs index 3148ee8..8d9d75b 100644 --- a/tools/math.test.mjs +++ b/tools/math.test.mjs @@ -264,3 +264,33 @@ test('exact ties on the monthly candidate prefer the coarser window', () => { 'monthly' ); }); + +// --- per-model estimates (issue #71) --- + +test('Z.AI GLM-5.3 per-model estimate equals the current top-level estimate', () => { + const agentic = profile('agentic-coding-v1'); + const lite = pricing.subscriptions.find((r) => r.id === 'zai/lite'); + + expect(lite.default_model).toBe('glm-5.3'); + expect(lite.estimates_by_model).toBeDefined(); + expect(lite.estimates_by_model['glm-5.3']).toBeDefined(); + + const modelEst = lite.estimates_by_model['glm-5.3']; + expect(modelEst.tokens_per_month).toBe(lite.est_tokens_per_month); + expect(modelEst.usd_per_mtok_at_full_use).toBe(lite.est_usd_per_mtok_at_full_use); +}); + +test('Z.AI GLM-5.3-Flash yields more tokens per month than GLM-5.3 at lower cost', () => { + const lite = pricing.subscriptions.find((r) => r.id === 'zai/lite'); + const glm53 = lite.estimates_by_model['glm-5.3']; + const flash = lite.estimates_by_model['glm-5.3-flash']; + + expect(flash).toBeDefined(); + expect(flash.tokens_per_month).toBeGreaterThan(glm53.tokens_per_month); + expect(flash.usd_per_mtok_at_full_use).toBeLessThan(glm53.usd_per_mtok_at_full_use); + + // Flash multipliers are 2.3/0.56/8 vs 6.9/1.7/24, so Flash should be roughly 3x cheaper + const ratio = glm53.usd_per_mtok_at_full_use / flash.usd_per_mtok_at_full_use; + expect(ratio).toBeGreaterThan(2.5); + expect(ratio).toBeLessThan(3.5); +}); diff --git a/tools/validate.mjs b/tools/validate.mjs index e76c338..a2b3f75 100644 --- a/tools/validate.mjs +++ b/tools/validate.mjs @@ -240,6 +240,35 @@ function checkDocument(doc, file) { `or stating the vendor publishes tokens directly (${VENDOR_DIRECT_ASSUMPTIONS.join('; ')})`, }); }); + + // Check model_weights constraints + subs.forEach((row, i) => { + const weights = Array.isArray(row?.model_weights) ? row.model_weights : []; + const included = new Set(Array.isArray(row?.models_included) ? row.models_included : []); + + if (weights.length > 0) { + // If model_weights is non-empty and est_tokens_per_month is numeric, default_model must be set + const hasNumericEstimate = typeof row?.est_tokens_per_month === 'number'; + if (hasNumericEstimate && typeof row?.default_model !== 'string') { + errors.push({ + file, + path: `$.subscriptions[${i}].default_model`, + message: `default_model is required when model_weights is non-empty and est_tokens_per_month is numeric`, + }); + } + + // Every model in model_weights must be in models_included + weights.forEach((weight, j) => { + if (typeof weight?.model === 'string' && !included.has(weight.model)) { + errors.push({ + file, + path: `$.subscriptions[${i}].model_weights[${j}].model`, + message: `model '${weight.model}' is not in models_included`, + }); + } + }); + } + }); const fx = doc?.fx; if (fx !== null && typeof fx === 'object' && typeof fx.base === 'string' && fx.rates !== null && typeof fx.rates === 'object') { (Array.isArray(doc.api_offers) ? doc.api_offers : []).forEach((row, i) => { diff --git a/tools/validate.test.mjs b/tools/validate.test.mjs index 91de2e6..71f91fc 100644 --- a/tools/validate.test.mjs +++ b/tools/validate.test.mjs @@ -393,6 +393,48 @@ test('a derived key that is not a known slug fails', () => { expect(hit.message).toContain("derived key 'ghost-model' is not a known model_slug"); }); +test('a model_weight whose model is not in models_included fails', () => { + const doc = makeDoc(); + doc.subscriptions[0].model_weights = [ + { + model: 'ghost-model', + input: 1, + cached_input: 0.2, + output: 5, + unit: 'credits', + quote: 'test', + source: 'https://example.com', + checked: '2026-10-10', + }, + ]; + doc.subscriptions[0].default_model = 'test-model'; + const errors = errorsOf(doc); + const hit = errors.find((e) => e.path === '$.subscriptions[0].model_weights[0].model'); + expect(hit).toBeDefined(); + expect(hit.message).toContain("model 'ghost-model' is not in models_included"); +}); + +test('model_weights without default_model when estimate is numeric fails', () => { + const doc = makeDoc(); + doc.subscriptions[0].model_weights = [ + { + model: 'test-model', + input: 1, + cached_input: 0.2, + output: 5, + unit: 'credits', + quote: 'test', + source: 'https://example.com', + checked: '2026-10-10', + }, + ]; + // est_tokens_per_month is numeric by default + const errors = errorsOf(doc); + const hit = errors.find((e) => e.path === '$.subscriptions[0].default_model'); + expect(hit).toBeDefined(); + expect(hit.message).toContain('default_model is required'); +}); + test('a registry document that violates its schema is reported against the registry file', () => { const errors = validateDocuments([{ file: 'fixture.json', doc: makeDoc() }], undefined, { models: [{ ...fixtureRegistry.models[0], released: 'soon' }],