From 683ec0bef41cb0c8364dbd53e621707fca2d9eac Mon Sep 17 00:00:00 2001 From: Hunter B Date: Mon, 1 Jun 2026 02:38:45 -0700 Subject: [PATCH] fix(pricing): keep adjusted DeepSeek V4-Pro rates --- crates/tui/src/pricing.rs | 65 ++++++++++++++------------------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/crates/tui/src/pricing.rs b/crates/tui/src/pricing.rs index 2cb77451..18f75af2 100644 --- a/crates/tui/src/pricing.rs +++ b/crates/tui/src/pricing.rs @@ -2,7 +2,9 @@ //! //! Pricing based on DeepSeek's published rates (per million tokens). -use chrono::{DateTime, TimeZone, Utc}; +#[cfg(test)] +use chrono::TimeZone; +use chrono::{DateTime, Utc}; use crate::models::Usage; @@ -103,18 +105,12 @@ struct ModelPricing { cny: CurrencyPricing, } -fn v4_pro_discount_ends_at() -> DateTime { - Utc.with_ymd_and_hms(2026, 5, 31, 15, 59, 0) - .single() - .expect("valid DeepSeek V4 Pro discount end timestamp") -} - /// Look up pricing for a model name. fn pricing_for_model(model: &str) -> Option { pricing_for_model_at(model, Utc::now()) } -fn pricing_for_model_at(model: &str, now: DateTime) -> Option { +fn pricing_for_model_at(model: &str, _now: DateTime) -> Option { let lower = model.to_lowercase(); if lower.starts_with("deepseek-ai/") { // NVIDIA NIM-hosted DeepSeek uses NVIDIA's catalog/account terms, not @@ -125,32 +121,19 @@ fn pricing_for_model_at(model: &str, now: DateTime) -> Option return None; } if lower.contains("v4-pro") || lower.contains("v4pro") { - if now <= v4_pro_discount_ends_at() { - // DeepSeek lists these as a limited-time 75% discount through - // 2026-05-31 15:59 UTC. - return Some(ModelPricing { - usd: CurrencyPricing { - input_cache_hit_per_million: 0.003625, - input_cache_miss_per_million: 0.435, - output_per_million: 0.87, - }, - cny: CurrencyPricing { - input_cache_hit_per_million: 0.025, - input_cache_miss_per_million: 3.0, - output_per_million: 6.0, - }, - }); - } + // DeepSeek's pricing page says the V4-Pro promotional 75% discount + // becomes the official one-quarter base price after 2026-05-31 15:59 + // UTC. Keep using the adjusted rate after that cutoff (#2489). Some(ModelPricing { usd: CurrencyPricing { - input_cache_hit_per_million: 0.0145, - input_cache_miss_per_million: 1.74, - output_per_million: 3.48, + input_cache_hit_per_million: 0.003625, + input_cache_miss_per_million: 0.435, + output_per_million: 0.87, }, cny: CurrencyPricing { - input_cache_hit_per_million: 0.1, - input_cache_miss_per_million: 12.0, - output_per_million: 24.0, + input_cache_hit_per_million: 0.025, + input_cache_miss_per_million: 3.0, + output_per_million: 6.0, }, }) } else { @@ -316,24 +299,22 @@ mod tests { } #[test] - fn v4_pro_returns_to_base_rates_after_discount_expiry() { - let after_expiry = Utc - .with_ymd_and_hms(2026, 5, 31, 16, 0, 0) - .single() - .unwrap(); + fn v4_pro_keeps_adjusted_rates_after_discount_window() { + let after_expiry = Utc.with_ymd_and_hms(2026, 6, 1, 0, 0, 0).single().unwrap(); let pricing = pricing_for_model_at("deepseek-v4-pro", after_expiry).unwrap(); - assert_eq!(pricing.usd.input_cache_hit_per_million, 0.0145); - assert_eq!(pricing.usd.input_cache_miss_per_million, 1.74); - assert_eq!(pricing.usd.output_per_million, 3.48); - assert_eq!(pricing.cny.input_cache_hit_per_million, 0.1); - assert_eq!(pricing.cny.input_cache_miss_per_million, 12.0); - assert_eq!(pricing.cny.output_per_million, 24.0); + assert_eq!(pricing.usd.input_cache_hit_per_million, 0.003625); + assert_eq!(pricing.usd.input_cache_miss_per_million, 0.435); + assert_eq!(pricing.usd.output_per_million, 0.87); + assert_eq!(pricing.cny.input_cache_hit_per_million, 0.025); + assert_eq!(pricing.cny.input_cache_miss_per_million, 3.0); + assert_eq!(pricing.cny.output_per_million, 6.0); } #[test] fn v4_pro_discount_still_applies_just_before_old_may5_expiry() { - // Regression for #267: extension to 2026-05-31 15:59 UTC. + // Regression for #267 and #2489: the adjusted V4-Pro pricing should + // not drift back to the original higher launch rates. let after_old_expiry = Utc.with_ymd_and_hms(2026, 5, 6, 0, 0, 0).single().unwrap(); let pricing = pricing_for_model_at("deepseek-v4-pro", after_old_expiry).unwrap();