fix: add cost nil guard to Anthropic/Antigravity RecordUsage paths
- Apply same nil-pointer protection as OpenAI path - Remove unused accessToken/proxyURL params from checkAccountCredits
This commit is contained in:
@@ -23,7 +23,7 @@ const (
|
|||||||
// 缓存 TTL 不足时会自动从 Google loadCodeAssist API 刷新。
|
// 缓存 TTL 不足时会自动从 Google loadCodeAssist API 刷新。
|
||||||
// 返回 true 表示积分可用。
|
// 返回 true 表示积分可用。
|
||||||
func (s *AntigravityGatewayService) checkAccountCredits(
|
func (s *AntigravityGatewayService) checkAccountCredits(
|
||||||
ctx context.Context, account *Account, accessToken, proxyURL string,
|
ctx context.Context, account *Account,
|
||||||
) bool {
|
) bool {
|
||||||
if account == nil || account.ID == 0 {
|
if account == nil || account.ID == 0 {
|
||||||
return false
|
return false
|
||||||
@@ -241,7 +241,7 @@ func (s *AntigravityGatewayService) attemptCreditsOveragesRetry(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check actual credits balance before attempting retry
|
// Check actual credits balance before attempting retry
|
||||||
if !s.checkAccountCredits(p.ctx, p.account, p.accessToken, p.proxyURL) {
|
if !s.checkAccountCredits(p.ctx, p.account) {
|
||||||
s.setCreditsExhausted(p.ctx, p.account)
|
s.setCreditsExhausted(p.ctx, p.account)
|
||||||
modelKey := resolveCreditsOveragesModelKey(p.ctx, p.account, modelName, p.requestedModel)
|
modelKey := resolveCreditsOveragesModelKey(p.ctx, p.account, modelName, p.requestedModel)
|
||||||
logger.LegacyPrintf("service.antigravity_gateway", "%s credit_overages_no_credits model=%s account=%d (skipping credits retry)",
|
logger.LegacyPrintf("service.antigravity_gateway", "%s credit_overages_no_credits model=%s account=%d (skipping credits retry)",
|
||||||
|
|||||||
@@ -558,7 +558,7 @@ func (s *AntigravityGatewayService) antigravityRetryLoop(p antigravityRetryLoopP
|
|||||||
p.account.IsOveragesEnabled() && !p.account.isCreditsExhausted() &&
|
p.account.IsOveragesEnabled() && !p.account.isCreditsExhausted() &&
|
||||||
p.account.isModelRateLimitedWithContext(p.ctx, p.requestedModel) {
|
p.account.isModelRateLimitedWithContext(p.ctx, p.requestedModel) {
|
||||||
// Check actual credits balance before injection
|
// Check actual credits balance before injection
|
||||||
if !s.checkAccountCredits(p.ctx, p.account, p.accessToken, p.proxyURL) {
|
if !s.checkAccountCredits(p.ctx, p.account) {
|
||||||
// No credits available - mark as exhausted and skip injection
|
// No credits available - mark as exhausted and skip injection
|
||||||
s.setCreditsExhausted(p.ctx, p.account)
|
s.setCreditsExhausted(p.ctx, p.account)
|
||||||
logger.LegacyPrintf("service.antigravity_gateway", "%s pre_check: no_credits_available account=%d (skipping credits injection)",
|
logger.LegacyPrintf("service.antigravity_gateway", "%s pre_check: no_credits_available account=%d (skipping credits injection)",
|
||||||
|
|||||||
@@ -7842,13 +7842,6 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu
|
|||||||
CacheCreation5mTokens: result.Usage.CacheCreation5mTokens,
|
CacheCreation5mTokens: result.Usage.CacheCreation5mTokens,
|
||||||
CacheCreation1hTokens: result.Usage.CacheCreation1hTokens,
|
CacheCreation1hTokens: result.Usage.CacheCreation1hTokens,
|
||||||
ImageOutputTokens: result.Usage.ImageOutputTokens,
|
ImageOutputTokens: result.Usage.ImageOutputTokens,
|
||||||
InputCost: cost.InputCost,
|
|
||||||
OutputCost: cost.OutputCost,
|
|
||||||
ImageOutputCost: cost.ImageOutputCost,
|
|
||||||
CacheCreationCost: cost.CacheCreationCost,
|
|
||||||
CacheReadCost: cost.CacheReadCost,
|
|
||||||
TotalCost: cost.TotalCost,
|
|
||||||
ActualCost: cost.ActualCost,
|
|
||||||
RateMultiplier: multiplier,
|
RateMultiplier: multiplier,
|
||||||
AccountRateMultiplier: &accountRateMultiplier,
|
AccountRateMultiplier: &accountRateMultiplier,
|
||||||
BillingType: billingType,
|
BillingType: billingType,
|
||||||
@@ -7863,6 +7856,15 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu
|
|||||||
ModelMappingChain: optionalTrimmedStringPtr(input.ModelMappingChain),
|
ModelMappingChain: optionalTrimmedStringPtr(input.ModelMappingChain),
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
}
|
}
|
||||||
|
if cost != nil {
|
||||||
|
usageLog.InputCost = cost.InputCost
|
||||||
|
usageLog.OutputCost = cost.OutputCost
|
||||||
|
usageLog.ImageOutputCost = cost.ImageOutputCost
|
||||||
|
usageLog.CacheCreationCost = cost.CacheCreationCost
|
||||||
|
usageLog.CacheReadCost = cost.CacheReadCost
|
||||||
|
usageLog.TotalCost = cost.TotalCost
|
||||||
|
usageLog.ActualCost = cost.ActualCost
|
||||||
|
}
|
||||||
|
|
||||||
// 设置计费模式
|
// 设置计费模式
|
||||||
if result.MediaType != "image" && result.MediaType != "video" && result.MediaType != "prompt" {
|
if result.MediaType != "image" && result.MediaType != "video" && result.MediaType != "prompt" {
|
||||||
@@ -8085,13 +8087,6 @@ func (s *GatewayService) RecordUsageWithLongContext(ctx context.Context, input *
|
|||||||
CacheCreation5mTokens: result.Usage.CacheCreation5mTokens,
|
CacheCreation5mTokens: result.Usage.CacheCreation5mTokens,
|
||||||
CacheCreation1hTokens: result.Usage.CacheCreation1hTokens,
|
CacheCreation1hTokens: result.Usage.CacheCreation1hTokens,
|
||||||
ImageOutputTokens: result.Usage.ImageOutputTokens,
|
ImageOutputTokens: result.Usage.ImageOutputTokens,
|
||||||
InputCost: cost.InputCost,
|
|
||||||
OutputCost: cost.OutputCost,
|
|
||||||
ImageOutputCost: cost.ImageOutputCost,
|
|
||||||
CacheCreationCost: cost.CacheCreationCost,
|
|
||||||
CacheReadCost: cost.CacheReadCost,
|
|
||||||
TotalCost: cost.TotalCost,
|
|
||||||
ActualCost: cost.ActualCost,
|
|
||||||
RateMultiplier: multiplier,
|
RateMultiplier: multiplier,
|
||||||
AccountRateMultiplier: &accountRateMultiplier,
|
AccountRateMultiplier: &accountRateMultiplier,
|
||||||
BillingType: billingType,
|
BillingType: billingType,
|
||||||
@@ -8105,6 +8100,15 @@ func (s *GatewayService) RecordUsageWithLongContext(ctx context.Context, input *
|
|||||||
ModelMappingChain: optionalTrimmedStringPtr(input.ModelMappingChain),
|
ModelMappingChain: optionalTrimmedStringPtr(input.ModelMappingChain),
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
}
|
}
|
||||||
|
if cost != nil {
|
||||||
|
usageLog.InputCost = cost.InputCost
|
||||||
|
usageLog.OutputCost = cost.OutputCost
|
||||||
|
usageLog.ImageOutputCost = cost.ImageOutputCost
|
||||||
|
usageLog.CacheCreationCost = cost.CacheCreationCost
|
||||||
|
usageLog.CacheReadCost = cost.CacheReadCost
|
||||||
|
usageLog.TotalCost = cost.TotalCost
|
||||||
|
usageLog.ActualCost = cost.ActualCost
|
||||||
|
}
|
||||||
|
|
||||||
// 设置计费模式
|
// 设置计费模式
|
||||||
if result.ImageCount > 0 {
|
if result.ImageCount > 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user