Skip to content

feat(prices): price DeepSeek, at its peak rate - #319

Merged
yuanhao merged 2 commits into
mainfrom
feat/deepseek-prices
Oct 16, 2026
Merged

yuanhao merged 2 commits into
mainfrom
feat/deepseek-prices

Conversation

@yuanhao

@yuanhao yuanhao commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

What

The bundled price snapshot gains DeepSeek: deepseek-flash, deepseek-v4-pro, and the legacy deepseek-v4-flash (served by V4.1 Flash, billed as Flash). Pricing stays opt-in (prices::enable_bundled()).

Rates per million tokens, from DeepSeek's pricing page, read from its raw markup, not a summary:

Model Input (cache miss) Cache hit Output
deepseek-flash, deepseek-v4-flash $0.30 $0.006 $1.20
deepseek-v4-pro $1.32 $0.044 $3.96

DeepSeek has no cache-write charge, so cache_write = input, under the existing cache_write_at_input allowance.

Why the peak rate

DeepSeek bills half of these off-peak, which is every hour except 01:00–04:00 and 06:00–10:00 UTC on weekdays (about 79% of the week). A CostConfig has no time of day, so the snapshot carries the peak rate as an upper bound:

  • costs are over-stated off-peak and never under-stated;
  • a Budget stops early rather than late.

docs/concepts/pricing.md shows how to install the off-peak rates as an override for anyone who'd rather count those.

Keeping it honest

  • tests/price_audit.rs now records DeepSeek's differences from models.dev instead of skipping them, and asserts them both ways:
    • DeepSeek's input, output and cache_read must be exactly twice models.dev's, which lists the off-peak rates. If models.dev starts listing the peak rate, or the ratio changes, that is drift.
    • models.dev's separate reasoning rate must equal its output rate, recorded as FLAT_RATE_GAPS with the figures pinned.
    • Positive controls: an entry at the off-peak rate is drift, and a missing reasoning gap is drift.
  • The checked-in models.dev slice is refreshed: V4 Pro's old figures there were wrong, and deepseek-v4-flash is added.
  • A live models.dev fetch (enable_live) skips DeepSeek's models as priced by time of day, so its off-peak rates never replace the bundled peak ones. The skip is reported in skipped, without the warning meant for unmappable data, and the live audit asserts it stays skipped.

Tests

  • Tests that used DeepSeek as "an unpriced model" (price_override_test, two in model.rs, the CostConfig doc example) now use Mistral.
  • price_fetch_test counts are updated for the refreshed slice.
  • Locally:
    • cargo test --all-features passes;
    • the live price audit passes, with DeepSeek's 12 fields checked as peak = 2 × off-peak and 0 drift;
    • clippy -D warnings, rustdoc and fmt are clean;
    • the live DeepSeek smoke now runs its cost check, 6/6 (it was "n/a" before).

🤖 Generated with Claude Code

https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG

yuanhao and others added 2 commits October 16, 2026 15:01
deepseek-flash, deepseek-v4-pro and the legacy deepseek-v4-flash (billed
as Flash), from DeepSeek's pricing page (read from its raw markup). DeepSeek
bills half its peak rate off-peak (all hours but 01:00-04:00 and
06:00-10:00 UTC on weekdays); a CostConfig has no time of day, so the
snapshot carries the peak rate: an upper bound, so a Budget stops early
rather than late. Off-peak rates can be installed as an override.

- price_audit: DeepSeek's rates must be exactly twice models.dev's
  (which lists the off-peak ones), and models.dev's `reasoning` rate must
  equal its output rate (recorded gaps); positive controls for both. The
  live models.dev fixture slice is refreshed (V4 Pro's old figures were
  wrong; deepseek-v4-flash added).
- The models.dev mapping skips DeepSeek (time-of-day pricing), so a live
  fetch never replaces the peak rate with the off-peak one; the live audit
  asserts it stays skipped.
- Tests that used DeepSeek as "an unpriced model" use Mistral instead.

The live smoke on DeepSeek now runs its cost check: 6/6.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG
…eak recipe, the example's literals

- A models.dev price cache written before this change still held
  DeepSeek's off-peak rates and was installed as-is (fresh for a day,
  stale offline for a week): cached models.dev tables now drop the
  time-of-day providers too. Test seeds such a cache (fresh and stale;
  a non-models.dev source keeps what it lists); it fails without the fix.
- pricing.md's off-peak override recipe states cache_write (without it
  install_override warned) and covers all three models.
- examples/llm_compaction_live.rs read DeepSeek's rates from literals and
  said a crate-level price would be wrong; it uses the snapshot now.
- TIME_OF_DAY_PRICED no longer sits between map_models_dev_cost and its
  doc comment.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG
@yuanhao
yuanhao merged commit 019b45f into main Oct 16, 2026
16 checks passed
@yuanhao
yuanhao deleted the feat/deepseek-prices branch October 16, 2026 13:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant