Problem
crates/tui/src/pricing.rs pricing_for_model returns None for everything except deepseek* and Xiaomi MiMo. 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.
The sidebar always renders a cost line even when no pricing exists — it shows cost: <$0.0001 (misleading "free") because format_cost_amount floors at <$0.0001.
Current state
crates/tui/src/pricing.rs:109-137 — pricing_for_model matches xiaomi/mimo* and contains("deepseek"), returns None otherwise.
crates/tui/src/pricing.rs:279-288 — format_cost_amount renders <$0.0001 for zero-cost, which looks like "free" rather than "no data".
- Cache telemetry is already normalized:
crates/tui/src/client.rs:1403-1410 maps OpenAI-style cached_tokens into Usage.prompt_cache_hit_tokens, so the math works for any provider once a table row exists.
- Catalog precedent:
known_context_window_for_model in crates/tui/src/models.rs:250-279 is the static curated-model match-table pattern to copy.
Proposed fix
- Change
ModelPricing.cny to Option<CurrencyPricing> (DeepSeek/MiMo keep Some, new USD-only rows use None).
- Extend
pricing_for_model_at with a static match table covering 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. Source prices from OpenRouter API; if unverifiable, omit the row.
- Add
pub fn has_pricing_for_model(model: &str) -> bool.
- Sidebar fallback: when
has_pricing_for_model is false AND session total is 0.0, render cost: n/a (no pricing data for <model>) instead of <$0.0001.
- CNY fallback: when
cost_currency is CNY but estimate has usd > 0.0 and cny == 0.0, display USD amount.
Acceptance criteria
Verification
cargo test -p codewhale-tui pricing
cargo test -p codewhale-tui cost
Problem
crates/tui/src/pricing.rspricing_for_model returnsNonefor everything exceptdeepseek*and Xiaomi MiMo. 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.The sidebar always renders a cost line even when no pricing exists — it shows
cost: <$0.0001(misleading "free") becauseformat_cost_amountfloors at<$0.0001.Current state
crates/tui/src/pricing.rs:109-137—pricing_for_modelmatchesxiaomi/mimo*andcontains("deepseek"), returnsNoneotherwise.crates/tui/src/pricing.rs:279-288—format_cost_amountrenders<$0.0001for zero-cost, which looks like "free" rather than "no data".crates/tui/src/client.rs:1403-1410maps OpenAI-stylecached_tokensintoUsage.prompt_cache_hit_tokens, so the math works for any provider once a table row exists.known_context_window_for_modelincrates/tui/src/models.rs:250-279is the static curated-model match-table pattern to copy.Proposed fix
ModelPricing.cnytoOption<CurrencyPricing>(DeepSeek/MiMo keepSome, new USD-only rows useNone).pricing_for_model_atwith a static match table covering 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. Source prices from OpenRouter API; if unverifiable, omit the row.pub fn has_pricing_for_model(model: &str) -> bool.has_pricing_for_modelis false AND session total is 0.0, rendercost: n/a (no pricing data for <model>)instead of<$0.0001.cost_currencyis CNY but estimate hasusd > 0.0andcny == 0.0, display USD amount.Acceptance criteria
pricing_for_modelreturnsSomefor at least:kimi-k2.6,z-ai/glm-5.1,qwen/qwen3.6-plus,trinity-large-thinking,gpt-5.5cost: n/a (no pricing data for <model>)for unpriced models with zero accrued costcost_currency = cnyand a USD-only model, cost line shows$not<¥0.0001Verification
cargo test -p codewhale-tui pricing
cargo test -p codewhale-tui cost