fix(billing): 补上 glm-5.3 / glm-5.3-flash 兜底价,避免被 glm-5 子串匹配抢走

This commit is contained in:
spin6lock
2026-08-31 19:51:50 +08:00
parent 0678b24d58
commit c74a4f521c
3 changed files with 56 additions and 5 deletions
+23 -3
View File
@@ -538,7 +538,20 @@ func (s *BillingService) initFallbackPricing() {
// Source: https://docs.z.ai/guides/overview/pricing (USD per 1M tokens)
// 注意:CacheReadPricePerToken 即"缓存命中"价格,CacheCreationPricePerToken 留空(智谱未公开写入价,按 0 处理)。
// GLM-4.6 与 GLM-4.5 在 z.ai 国际版上定价一致;GLM-4.5 国内按 ¥0.8/¥2,汇率换算后约 $0.112/$0.28,与国际版 $0.6/$2.2 不同,本分支采用国际版 USD 口径与现有 Claude/GPT 一致。
// GLM-5.2 与 GLM-5.1 在 z.ai 上同价。
// GLM-5.3 / GLM-5.2 与 GLM-5.1 在 z.ai 上同价。
// GLM-5.3-Flash 列表价 $0.15/$0.50(2026-09-09 前五折促销,此处按列表价,与其它模型口径一致)。
s.fallbackPrices["glm-5.3-flash"] = &ModelPricing{
InputPricePerToken: 0.15e-6, // $0.15 per MTok
OutputPricePerToken: 0.5e-6, // $0.50 per MTok
CacheReadPricePerToken: 0.03e-6,
SupportsCacheBreakdown: false,
}
s.fallbackPrices["glm-5.3"] = &ModelPricing{
InputPricePerToken: 1.4e-6, // $1.40 per MTok
OutputPricePerToken: 4.4e-6, // $4.40 per MTok
CacheReadPricePerToken: 0.26e-6,
SupportsCacheBreakdown: false,
}
s.fallbackPrices["glm-5.2"] = &ModelPricing{
InputPricePerToken: 1.4e-6, // $1.40 per MTok
OutputPricePerToken: 4.4e-6, // $4.40 per MTok
@@ -870,9 +883,16 @@ func (s *BillingService) getFallbackPricing(model string) *ModelPricing {
// 匹配策略:长 key 优先(具体模型 → 系列 / 厂商),未知型号不回退以避免误计价。
// 与 DeepSeek 一样采用"白名单"语义:未在本表命中的国产模型 alias 一律不返回兜底价。
// 智谱 GLM(z.ai 公开 SKU:glm-5.2 / glm-5.1 / glm-5 / glm-5-turbo / glm-4.7 / glm-4.6 / glm-4.5 等)
// 智谱 GLM(z.ai 公开 SKU:glm-5.3 / glm-5.3-flash / glm-5.2 / glm-5.1 / glm-5 / glm-5-turbo / glm-4.7 / glm-4.6 / glm-4.5 等)
// 匹配顺序:先判别最高 tier,再依次降级。
// 注意:带小数点的型号必须排在裸 "glm-5" 之前,否则会被 strings.Contains 抢走。
// 注意:带小数点的型号必须排在裸 "glm-5" 之前,否则会被 strings.Contains 抢走;
// glm-5.3-flash 必须排在 glm-5.3 之前(前者包含后者子串)。
if strings.Contains(modelLower, "glm-5.3-flash") || strings.Contains(modelLower, "glm-5.3flash") {
return s.fallbackPrices["glm-5.3-flash"]
}
if strings.Contains(modelLower, "glm-5.3") {
return s.fallbackPrices["glm-5.3"]
}
if strings.Contains(modelLower, "glm-5.2") {
return s.fallbackPrices["glm-5.2"]
}
@@ -532,6 +532,20 @@ func TestGetFallbackPricing_FamilyMatching(t *testing.T) {
},
// ---- 智谱 GLM(z.ai USD 口径)----
{
name: "glm 5.3 flagship",
model: "glm-5.3",
expectedInput: 1.4e-6,
expectedOutput: floatPtr(4.4e-6),
expectedCacheRead: floatPtr(0.26e-6),
},
{
name: "glm 5.3 flash",
model: "glm-5.3-flash",
expectedInput: 0.15e-6,
expectedOutput: floatPtr(0.5e-6),
expectedCacheRead: floatPtr(0.03e-6),
},
{
name: "glm 5.2 flagship",
model: "glm-5.2",
@@ -622,7 +636,21 @@ func TestGetFallbackPricing_FamilyMatching(t *testing.T) {
expectedInput: 0.1e-6,
expectedOutput: floatPtr(0.1e-6),
},
// 关键:5.1 / 5.2 必须先于 5 匹配(避免被 glm-5 抢走)
// 关键:5.1 / 5.2 / 5.3 必须先于 5 匹配(避免被 glm-5 抢走)
{
name: "glm 5.3-flash vs glm 5.3 ordering (verbatim 5.3-flash)",
model: "glm-5.3-flash",
expectedInput: 0.15e-6, // = glm-5.3-flash 价格(不是 glm-5.3 的 1.4e-6,更不是 glm-5 的 1e-6)
expectedOutput: floatPtr(0.5e-6),
expectedCacheRead: floatPtr(0.03e-6),
},
{
name: "glm 5.3 vs glm 5 ordering (verbatim 5.3)",
model: "glm-5.3",
expectedInput: 1.4e-6, // = glm-5.3 价格(不是 glm-5 的 1e-6)
expectedOutput: floatPtr(4.4e-6),
expectedCacheRead: floatPtr(0.26e-6),
},
{
name: "glm 5.1 vs glm 5 ordering (verbatim 5.1)",
model: "glm-5.1",
@@ -90,7 +90,10 @@ const antigravityModels = [
const zhipuModels = [
'glm-4', 'glm-4v', 'glm-4-plus', 'glm-4-0520',
'glm-4-air', 'glm-4-airx', 'glm-4-long', 'glm-4-flash',
'glm-4v-plus', 'glm-4.5', 'glm-4.6',
'glm-4v-plus', 'glm-4.5', 'glm-4.5-x', 'glm-4.5-air', 'glm-4.5-flash',
'glm-4.6', 'glm-4.7', 'glm-4.7-flash', 'glm-4.7-flashx',
'glm-5', 'glm-5-turbo', 'glm-5.1', 'glm-5.2',
'glm-5.3', 'glm-5.3-flash',
'glm-3-turbo', 'glm-4-alltools',
'chatglm_turbo', 'chatglm_pro', 'chatglm_std', 'chatglm_lite',
'cogview-3', 'cogvideo'