mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-11-01 08:28:34 +00:00
删除 GPT/Gemini 系列写死的阶梯规则,阶梯一律由目录数据驱动: - 解析层折算 LiteLLM 的 *_above_XXXk_tokens 绝对价字段为阈值+倍率 (阈值取自字段名,倍率 = above/基础价,cache 侧跟随输入倍率, xAI 按 provider 用达到即进高档语义);显式 long_context_* 字段 按"字段存在"优先,显式 threshold=0 或 multiplier=1 可关闭阶梯 - 删除 OpenAI 272K 常量与 applyModelSpecificPricingPolicy 的长上下文 强补分支、fallbackPrices/静态兜底条目的 LongContext 字段、Gemini 旧 边际规则全链路(CalculateCostWithLongContext / RecordUsageWithLongContext / 阶梯表 marginal 基准);保留 fastRatio 与 GPT-5.6 cache_write 1.25x 防御分支、grok 静态兜底阶梯 - 渠道配置定价区间时完全以渠道区间为准,不再叠加目录阶梯 - 长上下文倍率 ≤0 在应用点按 1 计,防止显式字段残缺把分项乘 0 免费 - 目录重载时对比新旧数据,原有阶梯丢失打 WARN 哨兵告警 行为变化:Gemini 由边际 2x(仅 /v1beta、全模型)改为整单换档(数据 驱动、仅带 above_200k 的 pro 系),渠道平价之上叠加目录阶梯;Claude sonnet-4/4.5 随目录数据获得 200K 整单阶梯(与官方定价一致);模型广场 官方参考价列与实付列同源展示目录阶梯。
58 lines
1.8 KiB
Go
58 lines
1.8 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// TokenCostRequest 通用网关 token 计费请求。
|
|
type TokenCostRequest struct {
|
|
Ctx context.Context
|
|
Model string
|
|
Group *Group
|
|
Tokens UsageTokens
|
|
RateMultiplier float64
|
|
PricingAt time.Time
|
|
ServiceTier string
|
|
Resolver *ModelPricingResolver
|
|
// Resolved 为调用方预先解析的定价(Resolver.Resolve 的结果),nil 表示未解析。
|
|
Resolved *ResolvedPricing
|
|
}
|
|
|
|
// CalculateTokenCostForRequest 按通用网关的路径选择计算 token 费用:
|
|
// 1. 分组/渠道显式定价,或有解析器与分组 → 统一计费
|
|
// (区间、分组卡、目录长上下文阶梯均在其中,阶梯由目录数据驱动);
|
|
// 2. 否则按模型目录直接计费。
|
|
//
|
|
// 模型广场的阶梯表查询与网关使用同一入口,保证展示与扣费同源。
|
|
func (s *BillingService) CalculateTokenCostForRequest(req TokenCostRequest) (*CostBreakdown, error) {
|
|
resolved := req.Resolved
|
|
if resolved != nil && (resolved.Source == PricingSourceGroup || resolved.Source == PricingSourceChannel) {
|
|
return s.CalculateCostUnified(s.tokenCostInput(req, resolved))
|
|
}
|
|
if req.Resolver != nil && req.Group != nil {
|
|
return s.CalculateCostUnified(s.tokenCostInput(req, resolved))
|
|
}
|
|
return s.CalculateCost(req.Model, req.Tokens, req.RateMultiplier)
|
|
}
|
|
|
|
func (s *BillingService) tokenCostInput(req TokenCostRequest, resolved *ResolvedPricing) CostInput {
|
|
input := CostInput{
|
|
Ctx: req.Ctx,
|
|
Model: req.Model,
|
|
Group: req.Group,
|
|
Tokens: req.Tokens,
|
|
RequestCount: 1,
|
|
RateMultiplier: req.RateMultiplier,
|
|
PricingAt: req.PricingAt,
|
|
ServiceTier: req.ServiceTier,
|
|
Resolver: req.Resolver,
|
|
Resolved: resolved,
|
|
}
|
|
if req.Group != nil {
|
|
gid := req.Group.ID
|
|
input.GroupID = &gid
|
|
}
|
|
return input
|
|
}
|