Merge pull request #825 from FizzlyCode/fix/setup-token-real-utilization
fix: Setup Token 账号使用真实 utilization 值替代状态估算
This commit is contained in:
@@ -903,15 +903,30 @@ func (s *AccountUsageService) estimateSetupTokenUsage(account *Account) *UsageIn
|
|||||||
remaining = 0
|
remaining = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据状态估算使用率 (百分比形式,100 = 100%)
|
// 优先使用响应头中存储的真实 utilization 值(0-1 小数,转为 0-100 百分比)
|
||||||
var utilization float64
|
var utilization float64
|
||||||
switch account.SessionWindowStatus {
|
var found bool
|
||||||
case "rejected":
|
if stored, ok := account.Extra["session_window_utilization"]; ok {
|
||||||
utilization = 100.0
|
switch v := stored.(type) {
|
||||||
case "allowed_warning":
|
case float64:
|
||||||
utilization = 80.0
|
utilization = v * 100
|
||||||
default:
|
found = true
|
||||||
utilization = 0.0
|
case json.Number:
|
||||||
|
if f, err := v.Float64(); err == nil {
|
||||||
|
utilization = f * 100
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有存储的 utilization,回退到状态估算
|
||||||
|
if !found {
|
||||||
|
switch account.SessionWindowStatus {
|
||||||
|
case "rejected":
|
||||||
|
utilization = 100.0
|
||||||
|
case "allowed_warning":
|
||||||
|
utilization = 80.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info.FiveHour = &UsageProgress{
|
info.FiveHour = &UsageProgress{
|
||||||
|
|||||||
@@ -970,12 +970,27 @@ func (s *RateLimitService) UpdateSessionWindow(ctx context.Context, account *Acc
|
|||||||
windowStart = &start
|
windowStart = &start
|
||||||
windowEnd = &end
|
windowEnd = &end
|
||||||
slog.Info("account_session_window_initialized", "account_id", account.ID, "window_start", start, "window_end", end, "status", status)
|
slog.Info("account_session_window_initialized", "account_id", account.ID, "window_start", start, "window_end", end, "status", status)
|
||||||
|
// 窗口重置时清除旧的 utilization,避免残留上个窗口的数据
|
||||||
|
_ = s.accountRepo.UpdateExtra(ctx, account.ID, map[string]any{
|
||||||
|
"session_window_utilization": nil,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.accountRepo.UpdateSessionWindow(ctx, account.ID, windowStart, windowEnd, status); err != nil {
|
if err := s.accountRepo.UpdateSessionWindow(ctx, account.ID, windowStart, windowEnd, status); err != nil {
|
||||||
slog.Warn("session_window_update_failed", "account_id", account.ID, "error", err)
|
slog.Warn("session_window_update_failed", "account_id", account.ID, "error", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 存储真实的 utilization 值(0-1 小数),供 estimateSetupTokenUsage 使用
|
||||||
|
if utilStr := headers.Get("anthropic-ratelimit-unified-5h-utilization"); utilStr != "" {
|
||||||
|
if util, err := strconv.ParseFloat(utilStr, 64); err == nil {
|
||||||
|
if err := s.accountRepo.UpdateExtra(ctx, account.ID, map[string]any{
|
||||||
|
"session_window_utilization": util,
|
||||||
|
}); err != nil {
|
||||||
|
slog.Warn("session_window_utilization_update_failed", "account_id", account.ID, "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 如果状态为allowed且之前有限流,说明窗口已重置,清除限流状态
|
// 如果状态为allowed且之前有限流,说明窗口已重置,清除限流状态
|
||||||
if status == "allowed" && account.IsRateLimited() {
|
if status == "allowed" && account.IsRateLimited() {
|
||||||
if err := s.ClearRateLimit(ctx, account.ID); err != nil {
|
if err := s.ClearRateLimit(ctx, account.ID); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user