diff --git a/src-tauri/src/dashboard.rs b/src-tauri/src/dashboard.rs index b11f14e..b114239 100644 --- a/src-tauri/src/dashboard.rs +++ b/src-tauri/src/dashboard.rs @@ -590,6 +590,20 @@ fn models_dev_lookup(model_name: &str) -> Option<(String, ModelsDevCost)> { Some((key.clone(), *cost)) } +/// Strip a trailing derived-variant suffix ("-highspeed", "-free") from a +/// model id: plan endpoints expose e.g. `glm-5.2-highspeed`, which bills at +/// the base model's price. +fn strip_variant_suffix(model_name: &str) -> Option { + for suffix in ["-highspeed", "-free"] { + if let Some(base) = model_name.strip_suffix(suffix) { + if !base.is_empty() { + return Some(base.to_string()); + } + } + } + None +} + /// Strip a trailing context-size suffix ("-256k", "-128k", "-1m") from a model /// id: context variants like "k3-256k" bill at the base model's ("k3") price. /// Returns the stripped id (provider prefix preserved), or None when there is @@ -629,6 +643,42 @@ fn match_price(model_name: &str) -> (String, f64, f64, f64, bool) { result } +/// Suffix-match a model against the models.dev index, skipping zero-priced +/// (subscription-plan) listings so a paid official entry wins. Used as the +/// fallback when the exact hit resolves to a zero-cost plan entry such as +/// `zhipuai-coding-plan/glm-5.2` or `kimi-for-coding/kimi-for-coding`. +fn priced_suffix_lookup(model_name: &str) -> Option<(String, ModelsDevCost)> { + let bare = model_name.rsplit_once('/').map(|(_, b)| b).unwrap_or(model_name); + let bare_l = bare.to_ascii_lowercase(); + let mut matches: Vec<(&String, &ModelsDevCost)> = models_dev_cost_index() + .iter() + .filter(|(key, cost)| { + (cost.input > 0.0 || cost.output > 0.0) + && key + .rsplit_once('/') + .map(|(_, model)| model.ends_with(&bare_l)) + .unwrap_or(false) + }) + .collect(); + if matches.is_empty() { + return None; + } + matches.sort_by(|(a, _), (b, _)| { + provider_rank(a) + .cmp(&provider_rank(b)) + .then_with(|| a.cmp(b)) + }); + let (key, cost) = matches[0]; + Some((key.clone(), *cost)) +} + +/// Subscription-plan models without any priced counterpart in the snapshot +/// (e.g. the "Kimi For Coding" plan endpoint has no per-token price) bill at +/// the flagship model of the same family for cost estimation. +const PLAN_MODEL_FALLBACK: &[(&str, &str)] = &[ + ("kimi-for-coding", "moonshotai/kimi-k3"), +]; + fn match_price_inner(model_name: &str) -> (String, f64, f64, f64, bool) { let bare = match model_name.rsplit_once('/') { Some((_, b)) => b, @@ -640,11 +690,30 @@ fn match_price_inner(model_name: &str) -> (String, f64, f64, f64, bool) { return (id, c.cache_read, c.input, c.output, false); } // Zero-priced listing (subscription-plan entries such as - // kimi-for-coding/k3-256k): bill at the base model's list price. - if let Some(base) = strip_context_suffix(model_name) { - if let Some((base_id, base_c)) = models_dev_lookup(&base) { - if base_c.input > 0.0 || base_c.output > 0.0 { - return (base_id, base_c.cache_read, base_c.input, base_c.output, false); + // zhipuai-coding-plan/glm-5.2 or kimi-for-coding/kimi-for-coding): + // bill at a priced equivalent — the full id first, then derived + // variants (-highspeed / -free), then the context-size base, then the + // curated flagship fallback. + for base in [ + Some(model_name.to_string()), + strip_variant_suffix(model_name), + strip_context_suffix(model_name), + ] + .into_iter() + .flatten() + { + if let Some((bid, bc)) = priced_suffix_lookup(&base) { + if bc.input > 0.0 || bc.output > 0.0 { + return (bid, bc.cache_read, bc.input, bc.output, false); + } + } + } + let bare = model_name.rsplit_once('/').map(|(_, b)| b).unwrap_or(model_name); + let bare_l = bare.to_ascii_lowercase(); + for (plan, flagship) in PLAN_MODEL_FALLBACK { + if bare_l.contains(plan) { + if let Some((fid, fc)) = models_dev_lookup(flagship) { + return (fid, fc.cache_read, fc.input, fc.output, false); } } } @@ -1717,6 +1786,35 @@ mod pricing_tests { assert_eq!(strip_context_suffix("kimi-k2-thinking"), None); } + #[test] + fn subscription_plan_models_bill_at_priced_equivalent() { + // zhipuai-coding-plan/glm-5.2 is a zero-cost plan entry; the priced + // official zhipuai/glm-5.2 must win. + let (id, ch, input, output, est) = match_price("zhipuai-coding-plan/glm-5.2"); + assert!(!est); + assert_eq!(id, "zhipuai/glm-5.2"); + assert_eq!(input, 1.4); + assert_eq!(output, 4.4); + assert_eq!(ch, 0.26); + + // Kimi For Coding has no priced counterpart at all → curated flagship. + let (id, _, input, _, est) = match_price("kimi-code/kimi-for-coding"); + assert!(!est); + assert_eq!(id, "moonshotai/kimi-k3"); + assert_eq!(input, 3.0); + + // -highspeed variants strip back to the priced base model. + let (id, _, input, _, est) = match_price("zhipuai-coding-plan/glm-5.2-highspeed"); + assert!(!est); + assert_eq!(id, "zhipuai/glm-5.2"); + assert_eq!(input, 1.4); + assert_eq!( + strip_variant_suffix("glm-5.2-highspeed").as_deref(), + Some("glm-5.2") + ); + assert_eq!(strip_variant_suffix("glm-5.2"), None); + } + #[test] fn cache_write_price_preferred_when_present() { // glm-4.6 has cache_write: 0 → cache creation billed at 0, not input. diff --git a/src-tauri/src/services/coding_plan.rs b/src-tauri/src/services/coding_plan.rs index fd00607..9b63513 100644 --- a/src-tauri/src/services/coding_plan.rs +++ b/src-tauri/src/services/coding_plan.rs @@ -79,7 +79,20 @@ pub async fn query_kimi_coding(api_key: &str, timeout: Duration) -> Result Ok(UsageResult::ok(parse_kimi_coding(&body))), + Fetched::Body(body) => { + let tiers = parse_kimi_coding(&body); + if tiers.is_empty() { + // 响应里没有可解析的套餐档位(limits/usage 缺失或字段变了)。 + // 把原始响应(仅用量数字,无密钥)透出,方便对照接口结构修复。 + let preview = serde_json::to_string(&body) + .unwrap_or_else(|_| "".into()); + let trimmed: String = preview.chars().take(400).collect(); + return Ok(UsageResult::failure(format!( + "kimi usages 响应无套餐数据,原始返回: {trimmed}" + ))); + } + Ok(UsageResult::ok(tiers)) + } Fetched::Failed(err) => Ok(err), } } diff --git a/src/components/ProviderEdit.tsx b/src/components/ProviderEdit.tsx index a07f18f..dea07c5 100644 --- a/src/components/ProviderEdit.tsx +++ b/src/components/ProviderEdit.tsx @@ -699,6 +699,7 @@ function ModelMapping({ onModelChange({ ...m, capabilities: next }) } @@ -822,9 +823,13 @@ function JsonPreview({ function CapabilitiesCell({ capabilities, onChange, + nativeImage, }: { capabilities: string[]; onChange: (next: string[]) => void; + /** 模型本身是否原生支持图像输入(models.dev `image` 能力)。原生多模态 + * 模型无需 kimi-eyes 插件,提示不展示。 */ + nativeImage?: boolean; }) { const { t } = useTranslation(); @@ -838,13 +843,12 @@ function CapabilitiesCell({ return (
- {/* Only `thinking` is user-editable. The other capabilities - (always_thinking / image_in / video_in / tool_use) are still - auto-derived from models.dev via `capabilitiesFromRef` and saved - to config.toml — they just aren't exposed for manual editing. - To restore the full editor, drop the `.filter(...)` below and - re-add the custom-capabilities input (see git history). */} - {KNOWN_CAPABILITIES.filter((cap) => cap === "thinking").map((cap) => ( + {/* `thinking` 与 `image_in`(识图)可手动编辑;其余能力 + (always_thinking / video_in / tool_use) 仍由 models.dev 自动派生, + 保存时照常写入 config.toml。 */} + {KNOWN_CAPABILITIES.filter( + (cap) => cap === "thinking" || cap === "image_in", + ).map((cap) => (
); } diff --git a/src/components/UsageFooter.tsx b/src/components/UsageFooter.tsx index 8cf1753..61331dc 100644 --- a/src/components/UsageFooter.tsx +++ b/src/components/UsageFooter.tsx @@ -357,7 +357,9 @@ export function UsageFooter({ // success, or error/loading with last-good data (ghost). // Compact header already shows the primary entry; detail only adds value // when there are multiple tiers (e.g. 5h + weekly) or on error ghost. - if (data.length <= 1 && status === "success") return null; + // NOTE: single-tier plans (e.g. only five_hour) must still render — hiding + // them made kimi-for-coding look like it had no plan quota at all. + if (data.length === 0 && status === "success") return null; const ghost = status !== "success"; return (
= { capThinking: "Thinking", capAlwaysThinking: "Always Thinking", capImageIn: "Image Input", + capImageInHint: "Text models actually need the plugin-kimi-eyes:kimi-eyes plugin for image recognition", capVideoIn: "Video Input", capToolUse: "Tool Use", customCapabilities: "Other capabilities (comma-separated)", diff --git a/src/i18n/zh.ts b/src/i18n/zh.ts index 3e2a4e0..fd12421 100644 --- a/src/i18n/zh.ts +++ b/src/i18n/zh.ts @@ -161,6 +161,7 @@ export const zhTranslations = { capThinking: "思考", capAlwaysThinking: "始终思考", capImageIn: "图像输入", + capImageInHint: "文本推理模型实际需要搭配 plugin-kimi-eyes:kimi-eyes 插件才能识图", capVideoIn: "视频输入", capToolUse: "工具调用", customCapabilities: "其他能力(逗号分隔)", diff --git a/src/lib/models-dev-full.json b/src/lib/models-dev-full.json index 0e775ce..35e3cef 100644 --- a/src/lib/models-dev-full.json +++ b/src/lib/models-dev-full.json @@ -1,5 +1,5 @@ { - "last_updated": "2026-08-01", + "last_updated": "2026-08-02", "providers": { "zhipuai": { "id": "zhipuai", @@ -766,6 +766,20 @@ "tool_call": true, "structured_output": true }, + { + "id": "accounts/fireworks/models/deepseek-v4-flash-0731", + "name": "DeepSeek V4 Flash 0731", + "cost": { + "input": 0.14, + "output": 0.28, + "cache_read": 0.028 + }, + "context": 1000000, + "output_limit": 384000, + "reasoning": true, + "tool_call": true, + "structured_output": true + }, { "id": "accounts/fireworks/models/kimi-k2p7-code", "name": "Kimi K2.7 Code", @@ -1630,6 +1644,23 @@ "image": true, "video": true }, + { + "id": "gemini/gemini-3.5-flash-lite", + "name": "Gemini 3.5 Flash Lite", + "cost": { + "input": 0.3, + "output": 2.5, + "cache_read": 0.03, + "cache_write": 0.3 + }, + "context": 1048576, + "output_limit": 65536, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "image": true, + "video": true + }, { "id": "gemini/gemini-3-flash-preview", "name": "Gemini 3 Flash Preview", @@ -4720,6 +4751,21 @@ "tool_call": true, "structured_output": true }, + { + "id": "thinkingmachines/inkling-small", + "name": "Inkling Small", + "cost": { + "input": 0.5, + "output": 1.2, + "cache_read": 0.1 + }, + "context": 1048576, + "output_limit": 32768, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "image": true + }, { "id": "thinkingmachines/inkling", "name": "Inkling", @@ -4816,6 +4862,20 @@ "reasoning": true, "tool_call": true }, + { + "id": "deepseek-ai/DeepSeek-V4-Flash-0731", + "name": "DeepSeek V4 Flash 0731", + "cost": { + "input": 0.13, + "output": 0.26, + "cache_read": 0.028 + }, + "context": 1048576, + "output_limit": 1048576, + "reasoning": true, + "tool_call": true, + "structured_output": true + }, { "id": "deepseek-ai/DeepSeek-V3.1", "name": "DeepSeek V3.1", @@ -7573,7 +7633,7 @@ "tool_call": true }, { - "id": "glm-5.2-highspeed[1m]", + "id": "glm-5.2-highspeed", "name": "GLM-5.2 Highspeed", "cost": { "input": 0, @@ -46613,7 +46673,7 @@ "structured_output": true }, { - "id": "glm-5.2-highspeed[1m]", + "id": "glm-5.2-highspeed", "name": "GLM-5.2 Highspeed", "cost": { "input": 0, @@ -56446,6 +56506,133 @@ } ] }, + "modelis": { + "id": "modelis", + "name": "Modelis", + "models": [ + { + "id": "claude-sonnet-4-6", + "name": "Claude Sonnet 4.6", + "cost": { + "input": 3, + "output": 15 + }, + "context": 1000000, + "output_limit": 64000, + "reasoning": true, + "tool_call": true, + "image": true + }, + { + "id": "gemini-2.5-flash", + "name": "Gemini 2.5 Flash", + "cost": { + "input": 0.3, + "output": 2.5 + }, + "context": 1048576, + "output_limit": 65536, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "image": true, + "video": true + }, + { + "id": "claude-fable-5", + "name": "Claude Fable 5", + "cost": { + "input": 10, + "output": 50 + }, + "context": 1000000, + "output_limit": 128000, + "reasoning": true, + "tool_call": true, + "image": true + }, + { + "id": "deepseek-v4-flash", + "name": "DeepSeek V4 Flash", + "cost": { + "input": 0.0983, + "output": 0.1966 + }, + "context": 1000000, + "output_limit": 384000, + "reasoning": true, + "tool_call": true, + "structured_output": true + }, + { + "id": "claude-opus-4-8", + "name": "Claude Opus 4.8", + "cost": { + "input": 5, + "output": 25 + }, + "context": 1000000, + "output_limit": 128000, + "reasoning": true, + "tool_call": true, + "image": true + }, + { + "id": "deepseek-v4-pro", + "name": "DeepSeek V4 Pro", + "cost": { + "input": 0.435, + "output": 0.87 + }, + "context": 1000000, + "output_limit": 384000, + "reasoning": true, + "tool_call": true, + "structured_output": true + }, + { + "id": "gemini-2.5-pro", + "name": "Gemini 2.5 Pro", + "cost": { + "input": 1.25, + "output": 10 + }, + "context": 1048576, + "output_limit": 65536, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "image": true, + "video": true + }, + { + "id": "qwen/qwen3.7-plus", + "name": "Qwen3.7 Plus", + "cost": { + "input": 0.768, + "output": 3.072 + }, + "context": 1000000, + "output_limit": 64000, + "reasoning": true, + "tool_call": true, + "image": true, + "video": true + }, + { + "id": "qwen/qwen3.7-max", + "name": "Qwen3.7 Max", + "cost": { + "input": 3, + "output": 9 + }, + "context": 1000000, + "output_limit": 65536, + "reasoning": true, + "tool_call": true + } + ] + }, "subconscious": { "id": "subconscious", "name": "Subconscious", @@ -64671,13 +64858,14 @@ "id": "thinkingmachines/inkling-small", "name": "Inkling Small", "cost": { - "input": 0.58, - "output": 1.44, - "cache_read": 0.116 + "input": 0.5, + "output": 1.2, + "cache_read": 0.1 }, "context": 524288, "output_limit": 262144, "reasoning": true, + "tool_call": true, "image": true }, { @@ -64715,6 +64903,20 @@ "output_limit": 128000, "tool_call": true }, + { + "id": "~deepseek/deepseek-v4-flash-latest", + "name": "DeepSeek V4 Flash Latest", + "cost": { + "input": 0.09, + "output": 0.18, + "cache_read": 0.018 + }, + "context": 1048576, + "output_limit": 65536, + "reasoning": true, + "tool_call": true, + "structured_output": true + }, { "id": "perceptron/perceptron-mk1", "name": "Perceptron Mk1", @@ -64896,10 +65098,10 @@ "name": "Qwen3-Coder 30B-A3B Instruct", "cost": { "input": 0.07, - "output": 0.27 + "output": 0.28 }, "context": 262144, - "output_limit": 32768, + "output_limit": 262144, "tool_call": true, "structured_output": true }, @@ -66316,14 +66518,15 @@ "id": "deepseek/deepseek-v4-flash-0731", "name": "DeepSeek V4 Flash 0731", "cost": { - "input": 0.14, - "output": 0.28, - "cache_read": 0.0028 + "input": 0.09, + "output": 0.18, + "cache_read": 0.018 }, "context": 1048576, - "output_limit": 384000, + "output_limit": 65536, "reasoning": true, - "tool_call": true + "tool_call": true, + "structured_output": true }, { "id": "deepseek/deepseek-v3.2", @@ -67178,12 +67381,12 @@ "id": "z-ai/glm-5.2", "name": "GLM-5.2", "cost": { - "input": 1.12, - "output": 3.52, - "cache_read": 0.208 + "input": 0.4186, + "output": 1.3156, + "cache_read": 0.07774 }, "context": 1048576, - "output_limit": 128000, + "output_limit": 131072, "reasoning": true, "tool_call": true, "structured_output": true @@ -67348,9 +67551,9 @@ "id": "moonshotai/kimi-k2.6", "name": "Kimi K2.6", "cost": { - "input": 0.589, - "output": 2.48, - "cache_read": 0.0992 + "input": 0.6, + "output": 3.41, + "cache_read": 0.2 }, "context": 262144, "output_limit": 262144, @@ -67605,7 +67808,8 @@ "name": "GPT OSS 20B", "cost": { "input": 0.03, - "output": 0.14 + "output": 0.13, + "cache_read": 0.03 }, "context": 131072, "output_limit": 131072, diff --git a/src/lib/models-dev.json b/src/lib/models-dev.json index c632ad5..74aa2d1 100644 --- a/src/lib/models-dev.json +++ b/src/lib/models-dev.json @@ -1,5 +1,5 @@ { - "last_updated": "2026-08-01", + "last_updated": "2026-08-02", "zhipuai/glm-5": { "name": "GLM-5", "context": 204800, @@ -600,6 +600,18 @@ "cache_read": 0.145 } }, + "fireworks-ai/accounts/fireworks/models/deepseek-v4-flash-0731": { + "name": "DeepSeek V4 Flash 0731", + "context": 1000000, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "cost": { + "input": 0.14, + "output": 0.28, + "cache_read": 0.028 + } + }, "fireworks-ai/accounts/fireworks/models/kimi-k2p7-code": { "name": "Kimi K2.7 Code", "context": 262000, @@ -1320,6 +1332,21 @@ "cache_write": 0.3 } }, + "crossmodel/gemini/gemini-3.5-flash-lite": { + "name": "Gemini 3.5 Flash Lite", + "context": 1048576, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "image": true, + "video": true, + "cost": { + "input": 0.3, + "output": 2.5, + "cache_read": 0.03, + "cache_write": 0.3 + } + }, "crossmodel/gemini/gemini-3-flash-preview": { "name": "Gemini 3 Flash Preview", "context": 1048576, @@ -3884,6 +3911,19 @@ "cache_read": 0.12 } }, + "baseten/thinkingmachines/inkling-small": { + "name": "Inkling Small", + "context": 1048576, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "image": true, + "cost": { + "input": 0.5, + "output": 1.2, + "cache_read": 0.1 + } + }, "baseten/thinkingmachines/inkling": { "name": "Inkling", "context": 1048576, @@ -3966,6 +4006,18 @@ "output": 1.2 } }, + "baseten/deepseek-ai/DeepSeek-V4-Flash-0731": { + "name": "DeepSeek V4 Flash 0731", + "context": 1048576, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "cost": { + "input": 0.13, + "output": 0.26, + "cache_read": 0.028 + } + }, "baseten/deepseek-ai/DeepSeek-V3.1": { "name": "DeepSeek V3.1", "context": 164000, @@ -6220,7 +6272,7 @@ "cache_write": 0 } }, - "zhipuai-coding-plan/glm-5.2-highspeed[1m]": { + "zhipuai-coding-plan/glm-5.2-highspeed": { "name": "GLM-5.2 Highspeed", "context": 1000000, "reasoning": true, @@ -38091,7 +38143,7 @@ "cache_write": 0 } }, - "zai-coding-plan/glm-5.2-highspeed[1m]": { + "zai-coding-plan/glm-5.2-highspeed": { "name": "GLM-5.2 Highspeed", "context": 1000000, "reasoning": true, @@ -46335,6 +46387,109 @@ "output": 2.92 } }, + "modelis/claude-sonnet-4-6": { + "name": "Claude Sonnet 4.6", + "context": 1000000, + "reasoning": true, + "tool_call": true, + "image": true, + "cost": { + "input": 3, + "output": 15 + } + }, + "modelis/gemini-2.5-flash": { + "name": "Gemini 2.5 Flash", + "context": 1048576, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "image": true, + "video": true, + "cost": { + "input": 0.3, + "output": 2.5 + } + }, + "modelis/claude-fable-5": { + "name": "Claude Fable 5", + "context": 1000000, + "reasoning": true, + "tool_call": true, + "image": true, + "cost": { + "input": 10, + "output": 50 + } + }, + "modelis/deepseek-v4-flash": { + "name": "DeepSeek V4 Flash", + "context": 1000000, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "cost": { + "input": 0.0983, + "output": 0.1966 + } + }, + "modelis/claude-opus-4-8": { + "name": "Claude Opus 4.8", + "context": 1000000, + "reasoning": true, + "tool_call": true, + "image": true, + "cost": { + "input": 5, + "output": 25 + } + }, + "modelis/deepseek-v4-pro": { + "name": "DeepSeek V4 Pro", + "context": 1000000, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "cost": { + "input": 0.435, + "output": 0.87 + } + }, + "modelis/gemini-2.5-pro": { + "name": "Gemini 2.5 Pro", + "context": 1048576, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "image": true, + "video": true, + "cost": { + "input": 1.25, + "output": 10 + } + }, + "modelis/qwen/qwen3.7-plus": { + "name": "Qwen3.7 Plus", + "context": 1000000, + "reasoning": true, + "tool_call": true, + "image": true, + "video": true, + "cost": { + "input": 0.768, + "output": 3.072 + } + }, + "modelis/qwen/qwen3.7-max": { + "name": "Qwen3.7 Max", + "context": 1000000, + "reasoning": true, + "tool_call": true, + "cost": { + "input": 3, + "output": 9 + } + }, "subconscious/subconscious/glm-5.2": { "name": "GLM-5.2", "context": 1000000, @@ -53164,11 +53319,12 @@ "name": "Inkling Small", "context": 524288, "reasoning": true, + "tool_call": true, "image": true, "cost": { - "input": 0.58, - "output": 1.44, - "cache_read": 0.116 + "input": 0.5, + "output": 1.2, + "cache_read": 0.1 } }, "openrouter/thinkingmachines/inkling": { @@ -53200,6 +53356,18 @@ "output": 3 } }, + "openrouter/~deepseek/deepseek-v4-flash-latest": { + "name": "DeepSeek V4 Flash Latest", + "context": 1048576, + "reasoning": true, + "tool_call": true, + "structured_output": true, + "cost": { + "input": 0.09, + "output": 0.18, + "cache_read": 0.018 + } + }, "openrouter/perceptron/perceptron-mk1": { "name": "Perceptron Mk1", "context": 32768, @@ -53359,7 +53527,7 @@ "structured_output": true, "cost": { "input": 0.07, - "output": 0.27 + "output": 0.28 } }, "openrouter/qwen/qwen3.5-plus-02-15": { @@ -54560,10 +54728,11 @@ "context": 1048576, "reasoning": true, "tool_call": true, + "structured_output": true, "cost": { - "input": 0.14, - "output": 0.28, - "cache_read": 0.0028 + "input": 0.09, + "output": 0.18, + "cache_read": 0.018 } }, "openrouter/deepseek/deepseek-v3.2": { @@ -55297,9 +55466,9 @@ "tool_call": true, "structured_output": true, "cost": { - "input": 1.12, - "output": 3.52, - "cache_read": 0.208 + "input": 0.4186, + "output": 1.3156, + "cache_read": 0.07774 } }, "openrouter/z-ai/glm-4.6": { @@ -55442,9 +55611,9 @@ "structured_output": true, "image": true, "cost": { - "input": 0.589, - "output": 2.48, - "cache_read": 0.0992 + "input": 0.6, + "output": 3.41, + "cache_read": 0.2 } }, "openrouter/moonshotai/kimi-k2.7-code": { @@ -55657,7 +55826,8 @@ "structured_output": true, "cost": { "input": 0.03, - "output": 0.14 + "output": 0.13, + "cache_read": 0.03 } }, "openrouter/openai/gpt-oss-safeguard-20b": {