From 35581103ed7d9a946c3f107ec5eecb9623bbbf52 Mon Sep 17 00:00:00 2001 From: KimiSwitch Dev Date: Wed, 16 Sep 2026 14:14:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(usage):=20plan:kimi=5Fcoding=20=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=20kimi-code=200.43.1=20quota=20=E7=94=A8=E9=87=8F?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 服务端 api.kimi.com/coding/v1/usages 已由绝对 used/limit 行切换为 quota 模型(usages.limit_5h/limit_7d/limit_month_total/limit_month_code, 条目为 used_ratio 0-1 比率 + reset_time),见上游 #3787。 - parse_kimi_coding 优先解析新结构,旧 limits/usage 结构保留为回退 - used_ratio >1 时按已是百分数处理(防御) - 新 tier id month_code + 前端 planLabel/i18n 中英文案 - 新增 3 个测试:四窗口解析 / 比率防御 / 空窗口回退旧结构 --- src-tauri/src/services/coding_plan.rs | 104 +++++++++- src/i18n/en.ts | 1 + src/i18n/zh.ts | 1 + src/lib/models-dev-full.json | 269 +++++++++++++++++--------- src/lib/models-dev.json | 229 ++++++++++++++-------- src/lib/usage-display.ts | 9 +- 6 files changed, 428 insertions(+), 185 deletions(-) diff --git a/src-tauri/src/services/coding_plan.rs b/src-tauri/src/services/coding_plan.rs index e6f2c46..d8e5aad 100644 --- a/src-tauri/src/services/coding_plan.rs +++ b/src-tauri/src/services/coding_plan.rs @@ -16,11 +16,13 @@ use super::usage_types::{UsageData, UsageResult}; use std::time::Duration; // 套餐类 tier id 的唯一来源:所有套餐供应商(Kimi/智谱/MiniMax/OpenCode Go 及 -// 未来新增)都只用这三个 id。前端 src/lib/usage-display.ts 的 planLabel() 依赖 +// 未来新增)都只用这四个 id。前端 src/lib/usage-display.ts 的 planLabel() 依赖 // 此约定做本地化映射——新增 tier id 时必须同步加映射。 const TIER_FIVE_HOUR: &str = "five_hour"; const TIER_WEEKLY_LIMIT: &str = "weekly_limit"; const TIER_MONTHLY_LIMIT: &str = "monthly_limit"; +/// Kimi quota 模型的月度代码窗口(kimi-code #3787 后 `limit_month_code`)。 +const TIER_MONTH_CODE: &str = "month_code"; /// 套餐条目的统一构造:按百分比表示用量。 fn percent_tier(name: &str, used_percent: f64, resets_at: Option) -> UsageData { @@ -70,8 +72,12 @@ fn parse_f64(value: &serde_json::Value) -> Option { // GET {base_url}/usages // 默认 https://api.kimi.com/coding/v1/usages // global: https://api.kimi.ai/coding/v1/usages -// Response: { limits: [{ detail: { limit, remaining, resetTime } }], -// usage: { limit, remaining, resetTime } } +// Response(kimi-code #3787 / 0.43.1 起服务端切换为 quota 模型): +// { usages: { limit_5h, limit_7d, limit_month_total, limit_month_code: +// { used_ratio: 0-1, reset_time?: ISO 8601 } }, +// boosterWallet, goods_version } +// 旧结构(兼容保留): { limits: [{ detail: { limit, remaining, resetTime } }], +// usage: { limit, remaining, resetTime } } /// 由 base_url 拼接 usages 查询 URL;base_url 为空/空白时回退大陆默认。 /// 纯函数,便于单测。 @@ -95,8 +101,9 @@ pub async fn query_kimi_coding( Fetched::Body(body) => { let tiers = parse_kimi_coding(&body); if tiers.is_empty() { - // 响应里没有可解析的套餐档位(limits/usage 缺失或字段变了)。 - // 把原始响应(仅用量数字,无密钥)透出,方便对照接口结构修复。 + // 响应里没有可解析的套餐档位(quota/usages 与旧 limits/usage + // 均缺失或字段变了)。把原始响应(仅用量数字,无密钥)透出, + // 方便对照接口结构修复。 let preview = serde_json::to_string(&body) .unwrap_or_else(|_| "".into()); let trimmed: String = preview.chars().take(400).collect(); @@ -111,6 +118,11 @@ pub async fn query_kimi_coding( } fn parse_kimi_coding(body: &serde_json::Value) -> Vec { + // 新 quota 模型(kimi-code #3787 / 0.43.1 起服务端下发):优先解析。 + if let Some(tiers) = parse_kimi_quota(body) { + return tiers; + } + let mut tiers = Vec::new(); // 5 小时窗口限额(优先显示) @@ -130,6 +142,30 @@ fn parse_kimi_coding(body: &serde_json::Value) -> Vec { tiers } +/// 解析 quota 模型的 `usages` 窗口映射(`limit_5h` / `limit_7d` / +/// `limit_month_total` / `limit_month_code`)。全部窗口缺失或无可解析 +/// 条目时返回 None,让调用方回退旧结构。 +fn parse_kimi_quota(body: &serde_json::Value) -> Option> { + let usages = body.get("usages")?; + let mut tiers = Vec::new(); + for (key, tier) in [ + ("limit_5h", TIER_FIVE_HOUR), + ("limit_7d", TIER_WEEKLY_LIMIT), + ("limit_month_total", TIER_MONTHLY_LIMIT), + ("limit_month_code", TIER_MONTH_CODE), + ] { + let Some(entry) = usages.get(key) else { continue }; + let Some(ratio) = entry.get("used_ratio").and_then(parse_f64) else { + continue; + }; + // used_ratio 规范为 0-1 比率;>1 时视为已是百分数,原样使用。 + let used_percent = if ratio <= 1.0 { ratio * 100.0 } else { ratio }; + let resets_at = entry.get("reset_time").and_then(extract_reset_time); + tiers.push(percent_tier(tier, used_percent, resets_at)); + } + if tiers.is_empty() { None } else { Some(tiers) } +} + fn kimi_limit_tier(name: &str, detail: &serde_json::Value) -> UsageData { let limit = detail.get("limit").and_then(parse_f64).unwrap_or(1.0); let remaining = detail.get("remaining").and_then(parse_f64).unwrap_or(0.0); @@ -459,6 +495,64 @@ mod tests { ); } + #[test] + fn kimi_coding_quota_model_four_windows() { + // kimi-code #3787 / 0.43.1 起服务端下发的 quota 模型:used_ratio 为 + // 0-1 比率,reset_time 为 ISO 8601 字符串。 + let body = json!({ + "goods_version": 3, + "usages": { + "limit_5h": { "used_ratio": 0.6, "reset_time": "2026-09-15T17:00:00Z" }, + "limit_7d": { "used_ratio": 0.25 }, + "limit_month_total": { "used_ratio": 0.1, "reset_time": "2026-10-01T00:00:00Z" }, + "limit_month_code": { "used_ratio": 0.88 } + }, + "boosterWallet": { "balance": 0 } + }); + let tiers = parse_kimi_coding(&body); + assert_eq!(tiers.len(), 4); + assert_eq!(tiers[0].plan_name.as_deref(), Some("five_hour")); + assert_eq!(tiers[0].used, Some(60.0)); + assert_eq!(tiers[0].remaining, Some(40.0)); + assert_eq!(tiers[0].total, Some(100.0)); + assert_eq!( + tiers[0].resets_at.as_deref(), + Some("2026-09-15T17:00:00Z") + ); + assert_eq!(tiers[1].plan_name.as_deref(), Some("weekly_limit")); + assert_eq!(tiers[1].used, Some(25.0)); + assert!(tiers[1].resets_at.is_none()); + assert_eq!(tiers[2].plan_name.as_deref(), Some("monthly_limit")); + assert_eq!(tiers[2].used, Some(10.0)); + assert_eq!(tiers[3].plan_name.as_deref(), Some("month_code")); + assert_eq!(tiers[3].used, Some(88.0)); + assert_eq!(tiers[3].remaining, Some(12.0)); + } + + #[test] + fn kimi_coding_quota_ratio_above_one_is_percent() { + // 防御:>1 的 used_ratio 视为已是百分数,不再乘 100。 + let body = json!({ + "usages": { "limit_5h": { "used_ratio": 42.0 } } + }); + let tiers = parse_kimi_coding(&body); + assert_eq!(tiers.len(), 1); + assert_eq!(tiers[0].used, Some(42.0)); + } + + #[test] + fn kimi_coding_quota_missing_windows_falls_back_to_legacy() { + // usages 存在但没有任何可解析条目 → 回退旧结构解析。 + let body = json!({ + "usages": { "limit_5h": {} }, + "usage": { "limit": 1000, "remaining": 900, "resetTime": "2026-08-01T00:00:00Z" } + }); + let tiers = parse_kimi_coding(&body); + assert_eq!(tiers.len(), 1); + assert_eq!(tiers[0].plan_name.as_deref(), Some("weekly_limit")); + assert_eq!(tiers[0].used, Some(10.0)); + } + #[test] fn kimi_coding_reset_time_seconds_vs_millis() { // 秒级时间戳自动 ×1000 diff --git a/src/i18n/en.ts b/src/i18n/en.ts index c77f335..b10f579 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -449,6 +449,7 @@ export const enTranslations: Record = { usageTierDaily: "Daily", usageTierWeekly: "Weekly", usageTierMonthly: "Monthly", + usageTierMonthCode: "Monthly (code)", usageErrNoKey: "No API key configured", usageErrDisabled: "Usage query is disabled in the config panel", usageErrLoginExpired: "Kimi Code login expired and auto-refresh failed; run `kimi login` again", diff --git a/src/i18n/zh.ts b/src/i18n/zh.ts index 280b6e9..5ffc936 100644 --- a/src/i18n/zh.ts +++ b/src/i18n/zh.ts @@ -443,6 +443,7 @@ export const zhTranslations = { usageTierDaily: "每日", usageTierWeekly: "7天", usageTierMonthly: "30天", + usageTierMonthCode: "30天(代码)", usageErrNoKey: "未配置 API Key", usageErrDisabled: "用量查询已在配置面板中停用", usageErrLoginExpired: "Kimi Code 登录已过期且自动续期失败,请重新运行 `kimi login`", diff --git a/src/lib/models-dev-full.json b/src/lib/models-dev-full.json index 1fefea9..378a523 100644 --- a/src/lib/models-dev-full.json +++ b/src/lib/models-dev-full.json @@ -1,5 +1,5 @@ { - "last_updated": "2026-09-13", + "last_updated": "2026-09-14", "providers": { "subconscious": { "id": "subconscious", @@ -16470,6 +16470,20 @@ "output_limit": 32768, "image": true }, + { + "id": "alibaba/deepseek-v4.1-flash", + "name": "DeepSeek V4.1 Flash (Alibaba Cloud)", + "cost": { + "input": 0.3, + "output": 1.2, + "cache_read": 0.03 + }, + "context": 1000000, + "output_limit": 393216, + "reasoning": true, + "tool_call": true, + "image": true + }, { "id": "alibaba/qwen-coder-plus", "name": "Qwen Coder Plus (Alibaba Cloud)", @@ -16730,7 +16744,7 @@ "id": "scx-ai-gp/glm-5.2", "name": "GLM-5.2 (SCX.ai)", "cost": { - "input": 0.8, + "input": 0.88, "output": 2.55, "cache_read": 0.16 }, @@ -18921,6 +18935,17 @@ "reasoning": true, "tool_call": true }, + { + "id": "consensusprotocol/deepseek-v4.1-flash", + "name": "DeepSeek V4.1 Flash (Consensus Protocol)", + "cost": { + "input": 0.2, + "output": 0.6, + "cache_read": 0.005 + }, + "context": 1048576, + "output_limit": 384000 + }, { "id": "consensusprotocol/glm-5.3-flash", "name": "GLM-5.3 Flash (Consensus Protocol)", @@ -38111,9 +38136,9 @@ "id": "gemma-4-26b-a4b-it", "name": "Gemma 4 26B A4B IT", "cost": { - "input": 0.102, - "output": 0.356, - "cache_read": 0.051 + "input": 0.1, + "output": 0.374, + "cache_read": 0.05 }, "context": 256000, "output_limit": 25600, @@ -38129,7 +38154,7 @@ "output": 4.311648, "cache_read": 0.047907 }, - "context": 1048576, + "context": 1000000, "output_limit": 262144, "reasoning": true, "tool_call": true, @@ -38195,9 +38220,9 @@ "id": "minimax-m2.7", "name": "MiniMax-M2.7", "cost": { - "input": 0.396, - "output": 1.464, - "cache_read": 0.198 + "input": 0.462, + "output": 1.728, + "cache_read": 0.231 }, "context": 262100, "output_limit": 6553, @@ -38265,7 +38290,7 @@ "cost": { "input": 0.2, "output": 0.4, - "cache_read": 0.04 + "cache_write": 0.04 }, "context": 1000000, "output_limit": 384000, @@ -38281,7 +38306,7 @@ "output": 4.3552, "cache_read": 0.206872 }, - "context": 262000, + "context": 256000, "output_limit": 16000, "reasoning": true, "tool_call": true, @@ -38305,12 +38330,12 @@ "id": "deepseek-v4.1-flash", "name": "DeepSeek V4.1 Flash", "cost": { - "input": 0.3, - "output": 1.2, - "cache_read": 0.03 + "input": 0.32664, + "output": 1.30656, + "cache_read": 0.032664 }, - "context": 1048576, - "output_limit": 26214, + "context": 1000000, + "output_limit": 13107, "reasoning": true, "tool_call": true, "structured_output": true, @@ -38425,9 +38450,9 @@ "id": "glm-5", "name": "GLM-5", "cost": { - "input": 0.86, - "output": 2.752, - "cache_read": 0.43 + "input": 0.94, + "output": 3.008, + "cache_read": 0.47 }, "context": 202752, "output_limit": 20275, @@ -38452,9 +38477,9 @@ "id": "kimi-k2.5", "name": "Kimi K2.5", "cost": { - "input": 0.5584, - "output": 2.935, - "cache_read": 0.2792 + "input": 0.5344, + "output": 2.815, + "cache_read": 0.2672 }, "context": 262144, "output_limit": 26214, @@ -38467,7 +38492,7 @@ "name": "GLM-5.1", "cost": { "input": 1.318, - "output": 4.308, + "output": 4.268, "cache_read": 0.659 }, "context": 202750, @@ -38496,7 +38521,7 @@ "cost": { "input": 2.4, "output": 4.8, - "cache_read": 0.2 + "cache_write": 0.2 }, "context": 1000000, "output_limit": 384000, @@ -38508,9 +38533,9 @@ "id": "gpt-oss-120b", "name": "GPT OSS 120B", "cost": { - "input": 0.168, - "output": 0.66, - "cache_read": 0.084 + "input": 0.178, + "output": 0.68, + "cache_read": 0.089 }, "context": 128072, "output_limit": 13107, @@ -65693,6 +65718,21 @@ "tool_call": true, "structured_output": true }, + { + "id": "Qwen/Qwen3.8-Flash", + "name": "Qwen3.8 Flash", + "cost": { + "input": 0.113, + "output": 0.382, + "cache_read": 0.0141 + }, + "context": 1000000, + "output_limit": 131072, + "tool_call": true, + "structured_output": true, + "image": true, + "video": true + }, { "id": "Qwen/Qwen3-VL-235B-A22B-Instruct", "name": "Qwen3 VL 235B A22B Instruct", @@ -66211,8 +66251,8 @@ "input": 0.2275, "output": 0.91 }, - "context": 131072, - "output_limit": 8192, + "context": 40960, + "output_limit": 16384, "reasoning": true, "tool_call": true, "structured_output": true @@ -66976,12 +67016,12 @@ "id": "~deepseek/deepseek-v4-flash-latest", "name": "DeepSeek: DeepSeek V4 Flash Latest", "cost": { - "input": 0.0352, - "output": 0.1056, - "cache_read": 0.00112 + "input": 0.04, + "output": 0.1, + "cache_read": 0.01 }, "context": 1048576, - "output_limit": 131072, + "output_limit": 393216, "reasoning": true, "tool_call": true, "structured_output": true @@ -67591,7 +67631,7 @@ "output": 0.45 }, "context": 262144, - "output_limit": 16384, + "output_limit": 235929, "reasoning": true, "tool_call": true, "structured_output": true @@ -67641,8 +67681,8 @@ "output": 2.2, "cache_read": 0.1 }, - "context": 256000, - "output_limit": 32768, + "context": 202800, + "output_limit": 182520, "reasoning": true, "tool_call": true, "structured_output": true @@ -68842,7 +68882,8 @@ "name": "MoonshotAI: Kimi Latest", "cost": { "input": 2.1, - "output": 10.95 + "output": 10.95, + "cache_read": 0.23 }, "context": 1048576, "output_limit": 943718, @@ -70605,12 +70646,12 @@ "id": "~z-ai/glm-latest", "name": "Z.ai: GLM Latest", "cost": { - "input": 0.936, - "output": 3.168, - "cache_read": 0.1872 + "input": 0.92, + "output": 3.1372, + "cache_read": 0.184 }, - "context": 262144, - "output_limit": 235929, + "context": 1048576, + "output_limit": 943718, "reasoning": true, "tool_call": true, "structured_output": true @@ -70718,7 +70759,8 @@ "name": "Inference.net: Schematron V2 Small", "cost": { "input": 0.05, - "output": 0.23 + "output": 0.23, + "cache_read": 0.05 }, "context": 128000, "output_limit": 4096, @@ -70729,7 +70771,8 @@ "name": "Inference.net: Schematron V2 Turbo", "cost": { "input": 0.03, - "output": 0.15 + "output": 0.15, + "cache_read": 0.03 }, "context": 128000, "output_limit": 8192, @@ -70997,8 +71040,8 @@ "output": 4.4, "cache_read": 0.26 }, - "context": 202752, - "output_limit": 182476, + "context": 1048576, + "output_limit": 131072, "reasoning": true, "tool_call": true, "structured_output": true @@ -71095,8 +71138,8 @@ "output": 4.4, "cache_read": 0.26 }, - "context": 1048576, - "output_limit": 131072, + "context": 1048575, + "output_limit": 943717, "reasoning": true, "tool_call": true, "structured_output": true @@ -81488,11 +81531,11 @@ "id": "qwen/qwen3-14b", "name": "Qwen3 14B", "cost": { - "input": 0.2275, - "output": 0.91 + "input": 0.12, + "output": 0.24 }, "context": 131072, - "output_limit": 8192, + "output_limit": 16384, "reasoning": true, "tool_call": true, "structured_output": true @@ -82261,12 +82304,12 @@ "id": "~deepseek/deepseek-v4-flash-latest", "name": "DeepSeek V4 Flash Latest", "cost": { - "input": 0.0352, - "output": 0.1056, - "cache_read": 0.00112 + "input": 0.04, + "output": 0.1, + "cache_read": 0.01 }, "context": 1310720, - "output_limit": 131072, + "output_limit": 393216, "reasoning": true, "tool_call": true, "structured_output": true @@ -82859,11 +82902,11 @@ "id": "nvidia/nemotron-3-super-120b-a12b", "name": "Nemotron 3 Super 120B A12B", "cost": { - "input": 0.085, - "output": 0.4 + "input": 0.08, + "output": 0.45 }, "context": 262144, - "output_limit": 16384, + "output_limit": 235929, "reasoning": true, "tool_call": true, "structured_output": true @@ -82909,12 +82952,12 @@ "id": "nvidia/nemotron-3-ultra-550b-a55b", "name": "Nemotron 3 Ultra 550B A55B", "cost": { - "input": 0.625, - "output": 3.125, - "cache_read": 0.1875 + "input": 0.6, + "output": 2.4, + "cache_read": 0.12 }, "context": 262144, - "output_limit": 32768, + "output_limit": 182520, "reasoning": true, "tool_call": true, "structured_output": true @@ -84157,7 +84200,8 @@ "name": "Kimi Latest", "cost": { "input": 2.1, - "output": 10.95 + "output": 10.95, + "cache_read": 0.23 }, "context": 1048576, "output_limit": 943718, @@ -84224,9 +84268,9 @@ "id": "deepseek/deepseek-v4-pro-0813", "name": "DeepSeek V4 Pro 0813", "cost": { - "input": 0.57948, - "output": 1.73844, - "cache_read": 0.019316 + "input": 0.9834, + "output": 2.9502, + "cache_read": 0.03278 }, "context": 1048576, "output_limit": 384000, @@ -84238,9 +84282,9 @@ "id": "deepseek/deepseek-v4-flash-0731", "name": "DeepSeek V4 Flash 0731", "cost": { - "input": 0.04, - "output": 0.08, - "cache_read": 0.008 + "input": 0.06, + "output": 0.12, + "cache_read": 0.012 }, "context": 1310720, "output_limit": 943718, @@ -84252,9 +84296,9 @@ "id": "deepseek/deepseek-v4-flash", "name": "DeepSeek V4 Flash", "cost": { - "input": 0.04788, - "output": 0.09576, - "cache_read": 0.009576 + "input": 0.08554, + "output": 0.17108, + "cache_read": 0.017108 }, "context": 1048576, "output_limit": 384000, @@ -85829,12 +85873,12 @@ "id": "~z-ai/glm-latest", "name": "GLM Latest", "cost": { - "input": 0.936, - "output": 3.168, - "cache_read": 0.1872 + "input": 0.92, + "output": 3.1372, + "cache_read": 0.184 }, "context": 1310720, - "output_limit": 235929, + "output_limit": 943718, "reasoning": true, "tool_call": true, "structured_output": true @@ -85942,7 +85986,8 @@ "name": "Schematron V2 Small", "cost": { "input": 0.05, - "output": 0.23 + "output": 0.23, + "cache_read": 0.05 }, "context": 128000, "output_limit": 4096, @@ -85953,7 +85998,8 @@ "name": "Schematron V2 Turbo", "cost": { "input": 0.03, - "output": 0.15 + "output": 0.15, + "cache_read": 0.03 }, "context": 128000, "output_limit": 8192, @@ -86062,9 +86108,9 @@ "id": "tencent/hy3", "name": "Hy3", "cost": { - "input": 0.0825, - "output": 0.33, - "cache_read": 0.020625 + "input": 0.132, + "output": 0.528, + "cache_read": 0.033 }, "context": 262144, "input_limit": 192000, @@ -86217,12 +86263,12 @@ "id": "z-ai/glm-5.2", "name": "GLM-5.2", "cost": { - "input": 0.6, - "output": 2, - "cache_read": 0.15 + "input": 0.6832, + "output": 2.1472, + "cache_read": 0.12688 }, "context": 1048576, - "output_limit": 182476, + "output_limit": 131072, "reasoning": true, "tool_call": true, "structured_output": true @@ -86231,9 +86277,9 @@ "id": "z-ai/glm-5.3-flash", "name": "GLM-5.3-Flash", "cost": { - "input": 0.075, - "output": 0.25, - "cache_read": 0.015 + "input": 0.15, + "output": 0.5, + "cache_read": 0.03 }, "context": 1310720, "output_limit": 131072, @@ -86315,12 +86361,12 @@ "id": "z-ai/glm-5.3", "name": "GLM-5.3", "cost": { - "input": 1.092, - "output": 3.432, - "cache_read": 0.2028 + "input": 1.4, + "output": 4.4, + "cache_read": 0.26 }, "context": 1310720, - "output_limit": 131072, + "output_limit": 943717, "reasoning": true, "tool_call": true, "structured_output": true @@ -102924,8 +102970,9 @@ "id": "qwen/deepseek-v4-pro-0813", "name": "DeepSeek V4 Pro 0813 (Alibaba)", "cost": { - "input": 0.5808, - "output": 1.7424 + "input": 0.66, + "output": 1.98, + "cache_read": 0.066 }, "context": 1000000, "output_limit": 384000, @@ -102937,8 +102984,9 @@ "id": "qwen/deepseek-v4-flash-0731", "name": "DeepSeek V4 Flash 0731 (Alibaba)", "cost": { - "input": 0.176, - "output": 0.528 + "input": 0.22, + "output": 0.66, + "cache_read": 0.022 }, "context": 1000000, "output_limit": 384000, @@ -103080,6 +103128,21 @@ "output_limit": 8192, "reasoning": true }, + { + "id": "qwen/deepseek-v4.1-flash", + "name": "DeepSeek V4.1 Flash (Alibaba)", + "cost": { + "input": 0.15, + "output": 0.6, + "cache_read": 0.015 + }, + "context": 1000000, + "output_limit": 384000, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "image": true + }, { "id": "qwen/qwen3-coder-next", "name": "Qwen3 Coder Next", @@ -104143,6 +104206,20 @@ "reasoning": true, "tool_call": true }, + { + "id": "tensorx/deepseek/deepseek-v4.1-flash", + "name": "DeepSeek V4.1 Flash (TensorX)", + "cost": { + "input": 0.5, + "output": 1.5, + "cache_read": 0.125 + }, + "context": 1048576, + "output_limit": 384000, + "reasoning": true, + "tool_call": true, + "image": true + }, { "id": "tensorx/moonshotai/kimi-k2.5", "name": "Kimi K2.5 (TensorX)", diff --git a/src/lib/models-dev.json b/src/lib/models-dev.json index 47182aa..f28bf6b 100644 --- a/src/lib/models-dev.json +++ b/src/lib/models-dev.json @@ -1,5 +1,5 @@ { - "last_updated": "2026-09-13", + "last_updated": "2026-09-14", "subconscious/subconscious/glm-5.2": { "name": "GLM-5.2", "context": 1000000, @@ -13257,6 +13257,18 @@ "cache_write": 0.25 } }, + "llmgateway-providers/alibaba/deepseek-v4.1-flash": { + "name": "DeepSeek V4.1 Flash (Alibaba Cloud)", + "context": 1000000, + "reasoning": true, + "tool_call": true, + "image": true, + "cost": { + "input": 0.3, + "output": 1.2, + "cache_read": 0.03 + } + }, "llmgateway-providers/alibaba/qwen-coder-plus": { "name": "Qwen Coder Plus (Alibaba Cloud)", "context": 131072, @@ -13482,7 +13494,7 @@ "reasoning": true, "tool_call": true, "cost": { - "input": 0.8, + "input": 0.88, "output": 2.55, "cache_read": 0.16 } @@ -15353,6 +15365,15 @@ "cache_read": 0.01 } }, + "llmgateway-providers/consensusprotocol/deepseek-v4.1-flash": { + "name": "DeepSeek V4.1 Flash (Consensus Protocol)", + "context": 1048576, + "cost": { + "input": 0.2, + "output": 0.6, + "cache_read": 0.005 + } + }, "llmgateway-providers/consensusprotocol/glm-5.3-flash": { "name": "GLM-5.3 Flash (Consensus Protocol)", "context": 1048576, @@ -31345,14 +31366,14 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.102, - "output": 0.356, - "cache_read": 0.051 + "input": 0.1, + "output": 0.374, + "cache_read": 0.05 } }, "hyper/deepseek-v4-pro-0813": { "name": "DeepSeek V4 Pro 0813", - "context": 1048576, + "context": 1000000, "reasoning": true, "tool_call": true, "structured_output": true, @@ -31416,9 +31437,9 @@ "reasoning": true, "tool_call": true, "cost": { - "input": 0.396, - "output": 1.464, - "cache_read": 0.198 + "input": 0.462, + "output": 1.728, + "cache_read": 0.231 } }, "hyper/kimi-k2.6": { @@ -31477,12 +31498,12 @@ "cost": { "input": 0.2, "output": 0.4, - "cache_read": 0.04 + "cache_write": 0.04 } }, "hyper/kimi-k2.7-code": { "name": "Kimi K2.7 Code", - "context": 262000, + "context": 256000, "reasoning": true, "tool_call": true, "structured_output": true, @@ -31506,15 +31527,15 @@ }, "hyper/deepseek-v4.1-flash": { "name": "DeepSeek V4.1 Flash", - "context": 1048576, + "context": 1000000, "reasoning": true, "tool_call": true, "structured_output": true, "image": true, "cost": { - "input": 0.3, - "output": 1.2, - "cache_read": 0.03 + "input": 0.32664, + "output": 1.30656, + "cache_read": 0.032664 } }, "hyper/qwen3.7-flash": { @@ -31613,9 +31634,9 @@ "reasoning": true, "tool_call": true, "cost": { - "input": 0.86, - "output": 2.752, - "cache_read": 0.43 + "input": 0.94, + "output": 3.008, + "cache_read": 0.47 } }, "hyper/qwen3.8-max": { @@ -31637,9 +31658,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.5584, - "output": 2.935, - "cache_read": 0.2792 + "input": 0.5344, + "output": 2.815, + "cache_read": 0.2672 } }, "hyper/glm-5.1": { @@ -31650,7 +31671,7 @@ "structured_output": true, "cost": { "input": 1.318, - "output": 4.308, + "output": 4.268, "cache_read": 0.659 } }, @@ -31675,7 +31696,7 @@ "cost": { "input": 2.4, "output": 4.8, - "cache_read": 0.2 + "cache_write": 0.2 } }, "hyper/gpt-oss-120b": { @@ -31685,9 +31706,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.168, - "output": 0.66, - "cache_read": 0.084 + "input": 0.178, + "output": 0.68, + "cache_read": 0.089 } }, "hyper/glm-5.3": { @@ -54422,6 +54443,19 @@ "output": 0.55 } }, + "deepinfra/Qwen/Qwen3.8-Flash": { + "name": "Qwen3.8 Flash", + "context": 1000000, + "tool_call": true, + "structured_output": true, + "image": true, + "video": true, + "cost": { + "input": 0.113, + "output": 0.382, + "cache_read": 0.0141 + } + }, "deepinfra/Qwen/Qwen3-VL-235B-A22B-Instruct": { "name": "Qwen3 VL 235B A22B Instruct", "context": 262144, @@ -54852,7 +54886,7 @@ }, "kilo/qwen/qwen3-14b": { "name": "Qwen: Qwen3 14B", - "context": 131072, + "context": 40960, "reasoning": true, "tool_call": true, "structured_output": true, @@ -55512,9 +55546,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.0352, - "output": 0.1056, - "cache_read": 0.00112 + "input": 0.04, + "output": 0.1, + "cache_read": 0.01 } }, "kilo/dots-studio/dots-3-note-preview:free": { @@ -56067,7 +56101,7 @@ }, "kilo/nvidia/nemotron-3-ultra-550b-a55b": { "name": "Nemotron 3 Ultra 550B A55B", - "context": 256000, + "context": 202800, "reasoning": true, "tool_call": true, "structured_output": true, @@ -57115,7 +57149,8 @@ "video": true, "cost": { "input": 2.1, - "output": 10.95 + "output": 10.95, + "cache_read": 0.23 } }, "kilo/ibm-granite/granite-4.2-8b": { @@ -58592,14 +58627,14 @@ }, "kilo/~z-ai/glm-latest": { "name": "Z.ai: GLM Latest", - "context": 262144, + "context": 1048576, "reasoning": true, "tool_call": true, "structured_output": true, "cost": { - "input": 0.936, - "output": 3.168, - "cache_read": 0.1872 + "input": 0.92, + "output": 3.1372, + "cache_read": 0.184 } }, "kilo/moonshotai/kimi-k2-0905": { @@ -58692,7 +58727,8 @@ "structured_output": true, "cost": { "input": 0.05, - "output": 0.23 + "output": 0.23, + "cache_read": 0.05 } }, "kilo/inference-net/schematron-v2-turbo": { @@ -58701,7 +58737,8 @@ "structured_output": true, "cost": { "input": 0.03, - "output": 0.15 + "output": 0.15, + "cache_read": 0.03 } }, "kilo/cohere/north-mini-code:free": { @@ -58919,7 +58956,7 @@ }, "kilo/z-ai/glm-5.2": { "name": "GLM-5.2", - "context": 202752, + "context": 1048576, "reasoning": true, "tool_call": true, "structured_output": true, @@ -59003,7 +59040,7 @@ }, "kilo/z-ai/glm-5.3": { "name": "GLM-5.3", - "context": 1048576, + "context": 1048575, "reasoning": true, "tool_call": true, "structured_output": true, @@ -67739,8 +67776,8 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.2275, - "output": 0.91 + "input": 0.12, + "output": 0.24 } }, "openrouter/qwen/qwen3.6-plus": { @@ -68399,9 +68436,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.0352, - "output": 0.1056, - "cache_read": 0.00112 + "input": 0.04, + "output": 0.1, + "cache_read": 0.01 } }, "openrouter/dots-studio/dots-3-note-preview:free": { @@ -68906,8 +68943,8 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.085, - "output": 0.4 + "input": 0.08, + "output": 0.45 } }, "openrouter/nvidia/nemotron-3-ultra-550b-a55b:free": { @@ -68948,9 +68985,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.625, - "output": 3.125, - "cache_read": 0.1875 + "input": 0.6, + "output": 2.4, + "cache_read": 0.12 } }, "openrouter/nvidia/nemotron-3-nano-30b-a3b": { @@ -70028,7 +70065,8 @@ "video": true, "cost": { "input": 2.1, - "output": 10.95 + "output": 10.95, + "cache_read": 0.23 } }, "openrouter/ibm-granite/granite-4.2-8b": { @@ -70083,9 +70121,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.57948, - "output": 1.73844, - "cache_read": 0.019316 + "input": 0.9834, + "output": 2.9502, + "cache_read": 0.03278 } }, "openrouter/deepseek/deepseek-v4-flash-0731": { @@ -70095,9 +70133,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.04, - "output": 0.08, - "cache_read": 0.008 + "input": 0.06, + "output": 0.12, + "cache_read": 0.012 } }, "openrouter/deepseek/deepseek-v4-flash": { @@ -70107,9 +70145,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.04788, - "output": 0.09576, - "cache_read": 0.009576 + "input": 0.08554, + "output": 0.17108, + "cache_read": 0.017108 } }, "openrouter/deepseek/deepseek-v4.1-flash": { @@ -71428,9 +71466,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.936, - "output": 3.168, - "cache_read": 0.1872 + "input": 0.92, + "output": 3.1372, + "cache_read": 0.184 } }, "openrouter/moonshotai/kimi-k2-0905": { @@ -71523,7 +71561,8 @@ "structured_output": true, "cost": { "input": 0.05, - "output": 0.23 + "output": 0.23, + "cache_read": 0.05 } }, "openrouter/inference-net/schematron-v2-turbo": { @@ -71532,7 +71571,8 @@ "structured_output": true, "cost": { "input": 0.03, - "output": 0.15 + "output": 0.15, + "cache_read": 0.03 } }, "openrouter/cohere/north-mini-code:free": { @@ -71625,9 +71665,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.0825, - "output": 0.33, - "cache_read": 0.020625 + "input": 0.132, + "output": 0.528, + "cache_read": 0.033 } }, "openrouter/tencent/hy4-preview": { @@ -71755,9 +71795,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.6, - "output": 2, - "cache_read": 0.15 + "input": 0.6832, + "output": 2.1472, + "cache_read": 0.12688 } }, "openrouter/z-ai/glm-5.3-flash": { @@ -71769,9 +71809,9 @@ "image": true, "video": true, "cost": { - "input": 0.075, - "output": 0.25, - "cache_read": 0.015 + "input": 0.15, + "output": 0.5, + "cache_read": 0.03 } }, "openrouter/z-ai/glm-4.5": { @@ -71839,9 +71879,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 1.092, - "output": 3.432, - "cache_read": 0.2028 + "input": 1.4, + "output": 4.4, + "cache_read": 0.26 } }, "openrouter/z-ai/glm-5v-turbo": { @@ -85559,8 +85599,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.5808, - "output": 1.7424 + "input": 0.66, + "output": 1.98, + "cache_read": 0.066 } }, "edenai/qwen/deepseek-v4-flash-0731": { @@ -85570,8 +85611,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 0.176, - "output": 0.528 + "input": 0.22, + "output": 0.66, + "cache_read": 0.022 } }, "edenai/qwen/qwen3-coder-plus": { @@ -85688,6 +85730,19 @@ "output": 2.4 } }, + "edenai/qwen/deepseek-v4.1-flash": { + "name": "DeepSeek V4.1 Flash (Alibaba)", + "context": 1000000, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "image": true, + "cost": { + "input": 0.15, + "output": 0.6, + "cache_read": 0.015 + } + }, "edenai/qwen/qwen3-coder-next": { "name": "Qwen3 Coder Next", "context": 262144, @@ -86603,6 +86658,18 @@ "cache_read": 0.0625 } }, + "edenai/tensorx/deepseek/deepseek-v4.1-flash": { + "name": "DeepSeek V4.1 Flash (TensorX)", + "context": 1048576, + "reasoning": true, + "tool_call": true, + "image": true, + "cost": { + "input": 0.5, + "output": 1.5, + "cache_read": 0.125 + } + }, "edenai/tensorx/moonshotai/kimi-k2.5": { "name": "Kimi K2.5 (TensorX)", "context": 262144, diff --git a/src/lib/usage-display.ts b/src/lib/usage-display.ts index ac05ad8..81ac2e9 100644 --- a/src/lib/usage-display.ts +++ b/src/lib/usage-display.ts @@ -11,9 +11,10 @@ type TranslateFn = ( * * Coverage note: ALL plan-type (套餐) queries flow through * src-tauri/src/services/coding_plan.rs::percent_tier, whose names come only - * from TIER_FIVE_HOUR / TIER_WEEKLY_LIMIT / TIER_MONTHLY_LIMIT — so this - * mapping covers every current and future plan provider automatically. If a - * new tier id is ever added there, add a case here too. + * from TIER_FIVE_HOUR / TIER_WEEKLY_LIMIT / TIER_MONTHLY_LIMIT / + * TIER_MONTH_CODE — so this mapping covers every current and future plan + * provider automatically. If a new tier id is ever added there, add a case + * here too. */ export function planLabel(name: string, t: TranslateFn): string { switch (name) { @@ -25,6 +26,8 @@ export function planLabel(name: string, t: TranslateFn): string { return t("usageTierWeekly"); case "monthly_limit": return t("usageTierMonthly"); + case "month_code": + return t("usageTierMonthCode"); default: return name; }