mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-01 12:22:09 +08:00
Update default models and pricing across presets
Bump default model names project-wide: gpt-5.4 -> gpt-5.5,
gemini-3.x -> gemini-3.5-flash, glm-5 -> glm-5.1, and
grok-code-fast-1 -> grok-build-0.1 across all provider presets
(claude, codex, gemini, hermes, openclaw, opencode, universal),
Gemini config, and stream check defaults.
Pricing:
- Seed gemini-3.5-flash, gemini-3.1-flash-lite, step-3.5-flash-2603,
doubao-seed-2.0-code, mimo-v2.5(/pro), qwen3-coder-480b, grok-build-0.1.
- Correct deepseek-v4-flash/pro, glm-5/5.1, grok pricing.
- Add repair_current_model_pricing: idempotent pass that fixes only
rows still equal to the outdated built-in values, preserving any
user-customized prices (seed uses INSERT OR IGNORE and cannot update
existing rows).
Fixes from review:
- opencode: drop duplicate gemini-3.5-flash variant (unreachable via
.find), keep the entry with the full minimal/low/medium/high set.
- Align stale display names/costs to gemini-3.5-flash (hermes, openclaw,
opencode); openclaw cost -> {1.5, 9, 0.15} to match seed.
- i18n (zh/en/ja/zh-TW): refresh OMO category tooltips for new model
names; fix writing tooltip to Kimi K2.5 to match its recommended.
Update tests accordingly and add a regression test asserting unique
model ids in the Google opencode preset variants.
This commit is contained in:
@@ -1485,6 +1485,15 @@ impl Database {
|
||||
("gpt-4.1", "GPT-4.1", "2", "8", "0.50", "0"),
|
||||
("gpt-4.1-mini", "GPT-4.1 Mini", "0.40", "1.60", "0.10", "0"),
|
||||
("gpt-4.1-nano", "GPT-4.1 Nano", "0.10", "0.40", "0.025", "0"),
|
||||
// Gemini 3.5 系列
|
||||
(
|
||||
"gemini-3.5-flash",
|
||||
"Gemini 3.5 Flash",
|
||||
"1.50",
|
||||
"9.00",
|
||||
"0.15",
|
||||
"0",
|
||||
),
|
||||
// Gemini 3.1 系列
|
||||
(
|
||||
"gemini-3.1-pro-preview",
|
||||
@@ -1494,6 +1503,14 @@ impl Database {
|
||||
"0.20",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"gemini-3.1-flash-lite",
|
||||
"Gemini 3.1 Flash Lite",
|
||||
"0.25",
|
||||
"1.50",
|
||||
"0.025",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"gemini-3.1-flash-lite-preview",
|
||||
"Gemini 3.1 Flash Lite Preview",
|
||||
@@ -1562,6 +1579,14 @@ impl Database {
|
||||
"0.02",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"step-3.5-flash-2603",
|
||||
"Step 3.5 Flash 2603",
|
||||
"0.10",
|
||||
"0.30",
|
||||
"0.02",
|
||||
"0",
|
||||
),
|
||||
// ====== 国产模型 (USD/1M tokens) ======
|
||||
// Doubao (字节跳动)
|
||||
(
|
||||
@@ -1588,6 +1613,14 @@ impl Database {
|
||||
"0",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"doubao-seed-2-0-code-preview-latest",
|
||||
"Doubao Seed 2.0 Code Preview",
|
||||
"0.47",
|
||||
"2.37",
|
||||
"0",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"doubao-seed-2-0-lite",
|
||||
"Doubao Seed 2.0 Lite",
|
||||
@@ -1644,15 +1677,15 @@ impl Database {
|
||||
"DeepSeek V4 Flash",
|
||||
"0.14",
|
||||
"0.28",
|
||||
"0.028",
|
||||
"0.0028",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"deepseek-v4-pro",
|
||||
"DeepSeek V4 Pro",
|
||||
"1.68",
|
||||
"3.36",
|
||||
"0.14",
|
||||
"0.435",
|
||||
"0.87",
|
||||
"0.003625",
|
||||
"0",
|
||||
),
|
||||
// Kimi (月之暗面)
|
||||
@@ -1714,8 +1747,8 @@ impl Database {
|
||||
// GLM (智谱)
|
||||
("glm-4.7", "GLM-4.7", "0.39", "1.75", "0.04", "0"),
|
||||
("glm-4.6", "GLM-4.6", "0.28", "1.11", "0.03", "0"),
|
||||
("glm-5", "GLM-5", "0.72", "2.30", "0", "0"),
|
||||
("glm-5.1", "GLM-5.1", "0.95", "3.15", "0", "0"),
|
||||
("glm-5", "GLM-5", "1", "3.2", "0.2", "0"),
|
||||
("glm-5.1", "GLM-5.1", "1.4", "4.4", "0.26", "0"),
|
||||
// MiMo (小米)
|
||||
(
|
||||
"mimo-v2-flash",
|
||||
@@ -1726,6 +1759,8 @@ impl Database {
|
||||
"0",
|
||||
),
|
||||
("mimo-v2-pro", "MiMo V2 Pro", "1", "3", "0", "0"),
|
||||
("mimo-v2.5", "MiMo V2.5", "0.09", "0.29", "0.009", "0"),
|
||||
("mimo-v2.5-pro", "MiMo V2.5 Pro", "1", "3", "0", "0"),
|
||||
// Qwen 系列 (阿里巴巴)
|
||||
("qwen3.6-plus", "Qwen3.6 Plus", "0.325", "1.95", "0", "0"),
|
||||
("qwen3.5-plus", "Qwen3.5 Plus", "0.26", "1.56", "0", "0"),
|
||||
@@ -1746,6 +1781,22 @@ impl Database {
|
||||
"0",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"qwen3-coder-480b",
|
||||
"Qwen3 Coder 480B",
|
||||
"0.65",
|
||||
"3.25",
|
||||
"0",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"qwen3-coder-480b-a35b-instruct",
|
||||
"Qwen3 Coder 480B-A35B Instruct",
|
||||
"0.65",
|
||||
"3.25",
|
||||
"0",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"qwen3-coder-flash",
|
||||
"Qwen3 Coder Flash",
|
||||
@@ -1801,12 +1852,13 @@ impl Database {
|
||||
("grok-4", "Grok 4", "3", "15", "0.75", "0"),
|
||||
(
|
||||
"grok-code-fast-1",
|
||||
"Grok Code Fast",
|
||||
"Grok Build 0.1 (Code Fast Alias)",
|
||||
"1",
|
||||
"2",
|
||||
"0.20",
|
||||
"1.50",
|
||||
"0.02",
|
||||
"0",
|
||||
),
|
||||
("grok-build-0.1", "Grok Build 0.1", "1", "2", "0.20", "0"),
|
||||
("grok-3", "Grok 3", "3", "15", "0.75", "0"),
|
||||
("grok-3-mini", "Grok 3 Mini", "0.25", "0.50", "0.075", "0"),
|
||||
// Mistral 系列
|
||||
@@ -1898,6 +1950,96 @@ impl Database {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn repair_current_model_pricing(conn: &Connection) -> Result<(), AppError> {
|
||||
let pricing_fixes = [
|
||||
(
|
||||
"deepseek-v4-flash",
|
||||
"DeepSeek V4 Flash",
|
||||
"0.14",
|
||||
"0.28",
|
||||
"0.0028",
|
||||
"0",
|
||||
"0.14",
|
||||
"0.28",
|
||||
"0.028",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"deepseek-v4-pro",
|
||||
"DeepSeek V4 Pro",
|
||||
"0.435",
|
||||
"0.87",
|
||||
"0.003625",
|
||||
"0",
|
||||
"1.68",
|
||||
"3.36",
|
||||
"0.14",
|
||||
"0",
|
||||
),
|
||||
(
|
||||
"glm-5", "GLM-5", "1", "3.2", "0.2", "0", "0.72", "2.30", "0", "0",
|
||||
),
|
||||
(
|
||||
"glm-5.1", "GLM-5.1", "1.4", "4.4", "0.26", "0", "0.95", "3.15", "0", "0",
|
||||
),
|
||||
(
|
||||
"grok-code-fast-1",
|
||||
"Grok Build 0.1 (Code Fast Alias)",
|
||||
"1",
|
||||
"2",
|
||||
"0.20",
|
||||
"0",
|
||||
"0.20",
|
||||
"1.50",
|
||||
"0.02",
|
||||
"0",
|
||||
),
|
||||
];
|
||||
|
||||
for (
|
||||
model_id,
|
||||
display_name,
|
||||
input,
|
||||
output,
|
||||
cache_read,
|
||||
cache_creation,
|
||||
old_input,
|
||||
old_output,
|
||||
old_cache_read,
|
||||
old_cache_creation,
|
||||
) in pricing_fixes
|
||||
{
|
||||
conn.execute(
|
||||
"UPDATE model_pricing SET
|
||||
display_name = ?2,
|
||||
input_cost_per_million = ?3,
|
||||
output_cost_per_million = ?4,
|
||||
cache_read_cost_per_million = ?5,
|
||||
cache_creation_cost_per_million = ?6
|
||||
WHERE model_id = ?1
|
||||
AND input_cost_per_million = ?7
|
||||
AND output_cost_per_million = ?8
|
||||
AND cache_read_cost_per_million = ?9
|
||||
AND cache_creation_cost_per_million = ?10",
|
||||
rusqlite::params![
|
||||
model_id,
|
||||
display_name,
|
||||
input,
|
||||
output,
|
||||
cache_read,
|
||||
cache_creation,
|
||||
old_input,
|
||||
old_output,
|
||||
old_cache_read,
|
||||
old_cache_creation
|
||||
],
|
||||
)
|
||||
.map_err(|e| AppError::Database(format!("修复模型 {model_id} 定价失败: {e}")))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 确保模型定价表具备默认数据
|
||||
pub fn ensure_model_pricing_seeded(&self) -> Result<(), AppError> {
|
||||
let conn = lock_conn!(self.conn);
|
||||
@@ -1905,8 +2047,9 @@ impl Database {
|
||||
}
|
||||
|
||||
fn ensure_model_pricing_seeded_on_conn(conn: &Connection) -> Result<(), AppError> {
|
||||
// 每次启动都执行 INSERT OR IGNORE,增量追加新模型,已有数据不覆盖
|
||||
Self::seed_model_pricing(conn)
|
||||
// 每次启动都执行 INSERT OR IGNORE,增量追加新模型;仅修复仍等于旧内置值的定价。
|
||||
Self::seed_model_pricing(conn)?;
|
||||
Self::repair_current_model_pricing(conn)
|
||||
}
|
||||
|
||||
// --- 辅助方法 ---
|
||||
|
||||
@@ -662,6 +662,66 @@ fn schema_model_pricing_is_seeded_on_init() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_pricing_seed_repairs_known_outdated_builtin_prices() {
|
||||
let db = Database::memory().expect("create memory db");
|
||||
|
||||
{
|
||||
let conn = db.conn.lock().expect("lock conn");
|
||||
conn.execute(
|
||||
"UPDATE model_pricing
|
||||
SET input_cost_per_million = '1.68',
|
||||
output_cost_per_million = '3.36',
|
||||
cache_read_cost_per_million = '0.14',
|
||||
cache_creation_cost_per_million = '0'
|
||||
WHERE model_id = 'deepseek-v4-pro'",
|
||||
[],
|
||||
)
|
||||
.expect("restore old DeepSeek price");
|
||||
conn.execute(
|
||||
"UPDATE model_pricing
|
||||
SET input_cost_per_million = '9',
|
||||
output_cost_per_million = '9',
|
||||
cache_read_cost_per_million = '9',
|
||||
cache_creation_cost_per_million = '0'
|
||||
WHERE model_id = 'glm-5.1'",
|
||||
[],
|
||||
)
|
||||
.expect("set custom GLM price");
|
||||
}
|
||||
|
||||
db.ensure_model_pricing_seeded()
|
||||
.expect("ensure pricing seeded");
|
||||
|
||||
let conn = db.conn.lock().expect("lock conn");
|
||||
let deepseek: (String, String, String) = conn
|
||||
.query_row(
|
||||
"SELECT input_cost_per_million, output_cost_per_million, cache_read_cost_per_million
|
||||
FROM model_pricing WHERE model_id = 'deepseek-v4-pro'",
|
||||
[],
|
||||
|row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)),
|
||||
)
|
||||
.expect("query DeepSeek price");
|
||||
assert_eq!(
|
||||
deepseek,
|
||||
(
|
||||
"0.435".to_string(),
|
||||
"0.87".to_string(),
|
||||
"0.003625".to_string()
|
||||
)
|
||||
);
|
||||
|
||||
let glm: (String, String, String) = conn
|
||||
.query_row(
|
||||
"SELECT input_cost_per_million, output_cost_per_million, cache_read_cost_per_million
|
||||
FROM model_pricing WHERE model_id = 'glm-5.1'",
|
||||
[],
|
||||
|row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)),
|
||||
)
|
||||
.expect("query GLM price");
|
||||
assert_eq!(glm, ("9".to_string(), "9".to_string(), "9".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_incremental_auto_vacuum_rebuilds_existing_file_db() {
|
||||
let temp = NamedTempFile::new().expect("create temp db file");
|
||||
|
||||
Reference in New Issue
Block a user