fix: revive cost tracking for non-DeepSeek models with an expanded pricing table#3201
fix: revive cost tracking for non-DeepSeek models with an expanded pricing table#3201mvanhorn wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
There was a problem hiding this comment.
Code Review
This pull request refactors the API cost estimation module to support USD-only models (such as those from OpenRouter) by making the CNY pricing field optional and implementing a fallback to USD display when CNY pricing is unavailable. It also adds pricing data for several new models and updates the TUI sidebar to handle unpriced models gracefully. The review feedback highlights a potential formatting bug in last_turn_cache_savings where USD savings might be incorrectly formatted with a CNY symbol, and suggests adding short aliases for the newly introduced Qwen, Gemma, and Tencent models to ensure pricing lookups succeed when short names are used.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| Some(match self.cost_currency { | ||
| crate::pricing::CostCurrency::Usd => estimate.usd, | ||
| crate::pricing::CostCurrency::Cny if estimate.cny == 0.0 && estimate.usd > 0.0 => { | ||
| estimate.usd | ||
| } | ||
| crate::pricing::CostCurrency::Cny => estimate.cny, | ||
| }) |
There was a problem hiding this comment.
When self.cost_currency is Cny, but the model is USD-only (meaning estimate.cny == 0.0 and estimate.usd > 0.0), returning estimate.usd directly can cause a formatting bug. If the app's active display currency has been resolved to Cny (due to previously accrued CNY costs in the session), format_cost_amount will format this returned USD value with the CNY symbol (¥), displaying an incorrect and misleading value (e.g., ¥0.34 instead of $0.34). Matching against self.cost_display_currency(self.cost_currency) ensures that we only return USD savings when the display currency is actually resolved to USD.
Some(match self.cost_display_currency(self.cost_currency) {
crate::pricing::CostCurrency::Usd => estimate.usd,
crate::pricing::CostCurrency::Cny => estimate.cny,
})| "qwen/qwen3.6-flash" => Some(usd_only_pricing(0.1875, 0.1875, 1.125)), | ||
| "qwen/qwen3.6-35b-a3b" => Some(usd_only_pricing(0.05, 0.15, 1.00)), | ||
| "qwen/qwen3.6-max-preview" => Some(usd_only_pricing(1.04, 1.04, 6.24)), | ||
| "qwen/qwen3.6-27b" => Some(usd_only_pricing(0.2885, 0.2885, 3.17)), | ||
| "qwen/qwen3.6-plus" => Some(usd_only_pricing(0.325, 0.325, 1.95)), | ||
| "qwen/qwen3.7-max" => Some(usd_only_pricing(0.25, 1.25, 3.75)), | ||
|
|
||
| "google/gemma-4-31b-it" => Some(usd_only_pricing(0.09, 0.12, 0.35)), | ||
| "google/gemma-4-26b-a4b-it" => Some(usd_only_pricing(0.06, 0.06, 0.33)), | ||
| "tencent/hy3-preview" => Some(usd_only_pricing(0.021, 0.063, 0.21)), |
There was a problem hiding this comment.
Several newly added models (Qwen, Google Gemma, and Tencent) are only matched using their full provider-prefixed names (e.g., "qwen/qwen3.6-flash"). They lack the short aliases (e.g., "qwen3.6-flash") that other models like Kimi, GLM, and Minimax have. If a user configures or runs these models using their short names, the pricing lookup will fail, resulting in no pricing data being displayed.
| "qwen/qwen3.6-flash" => Some(usd_only_pricing(0.1875, 0.1875, 1.125)), | |
| "qwen/qwen3.6-35b-a3b" => Some(usd_only_pricing(0.05, 0.15, 1.00)), | |
| "qwen/qwen3.6-max-preview" => Some(usd_only_pricing(1.04, 1.04, 6.24)), | |
| "qwen/qwen3.6-27b" => Some(usd_only_pricing(0.2885, 0.2885, 3.17)), | |
| "qwen/qwen3.6-plus" => Some(usd_only_pricing(0.325, 0.325, 1.95)), | |
| "qwen/qwen3.7-max" => Some(usd_only_pricing(0.25, 1.25, 3.75)), | |
| "google/gemma-4-31b-it" => Some(usd_only_pricing(0.09, 0.12, 0.35)), | |
| "google/gemma-4-26b-a4b-it" => Some(usd_only_pricing(0.06, 0.06, 0.33)), | |
| "tencent/hy3-preview" => Some(usd_only_pricing(0.021, 0.063, 0.21)), | |
| "qwen/qwen3.6-flash" | "qwen3.6-flash" => Some(usd_only_pricing(0.1875, 0.1875, 1.125)), | |
| "qwen/qwen3.6-35b-a3b" | "qwen3.6-35b-a3b" => Some(usd_only_pricing(0.05, 0.15, 1.00)), | |
| "qwen/qwen3.6-max-preview" | "qwen3.6-max-preview" => Some(usd_only_pricing(1.04, 1.04, 6.24)), | |
| "qwen/qwen3.6-27b" | "qwen3.6-27b" => Some(usd_only_pricing(0.2885, 0.2885, 3.17)), | |
| "qwen/qwen3.6-plus" | "qwen3.6-plus" => Some(usd_only_pricing(0.325, 0.325, 1.95)), | |
| "qwen/qwen3.7-max" | "qwen3.7-max" => Some(usd_only_pricing(0.25, 1.25, 3.75)), | |
| "google/gemma-4-31b-it" | "gemma-4-31b-it" => Some(usd_only_pricing(0.09, 0.12, 0.35)), | |
| "google/gemma-4-26b-a4b-it" | "gemma-4-26b-a4b-it" => Some(usd_only_pricing(0.06, 0.06, 0.33)), | |
| "tencent/hy3-preview" | "hy3-preview" => Some(usd_only_pricing(0.021, 0.063, 0.21)), |
Summary
crates/tui/src/pricing.rspricing_for_modelreturnsNonefor every model exceptdeepseek*and Xiaomi MiMo, so the turn/session cost line, cache-savings readout, and background cost accrual are all dead when running Kimi, Qwen, GLM, MiniMax, OpenAI, Arcee, or any OpenRouter-curated model. Worse, the sidebar always renders a cost line, andformat_cost_amountfloors at<$0.0001, so unpriced models showcost: <$0.0001which reads like "free" instead of "no data". The cache telemetry is already normalized for any provider (client.rs:1403-1410maps OpenAI-stylecached_tokensintoUsage.prompt_cache_hit_tokens), so the math works the moment a pricing-table row exists. The issue is maintainer-authored against the active v0.8.61 milestone with a numbered implementation plan, exact file:line references, acceptance criteria, and verification commands.Mirror the existing static curated-model match-table pattern from
known_context_window_for_model(models.rs:250-279). (1) ChangeModelPricing.cnytoOption<CurrencyPricing>so DeepSeek/MiMo keepSomeand new USD-only rows useNone. (2) Extendpricing_for_model_atwith a static match table for the curated catalog (kimi-k2.6,z-ai/glm-5.1,minimax/minimax-m3,qwen/qwen3.6-plus,trinity-large-thinking,gpt-5.5, etc.), sourcing prices from the OpenRouter API and omitting any row that cannot be verified. (3) Addpub fn has_pricing_for_model(model: &str) -> bool. (4) In the sidebar cost-line render site (sidebar.rs:2342-2357), whenhas_pricing_for_modelis false AND the session total is 0.0, rendercost: n/a (no pricing data for <model>)instead of<$0.0001. (5) In the cost-amount/currency path onapp(app.rs), whencost_currencyis CNY but the estimate hasusd > 0.0andcny == 0.0, display the USD amount instead of<¥0.0001. Keep all existing DeepSeek/MiMo behavior and tests intact.Testing
Tests for the pricing path were added/updated alongside the change. The Rust toolchain checks (
cargo fmt --all -- --check,cargo clippy --workspace --all-targets --all-features,cargo test --workspace --all-features) run in CI on this PR.Checklist
Fixes #3066