feat: publish sanitized custom.97 source

This commit is contained in:
cneicy committed 2026-10-27 20:43:39 +08:00
1 parent 8e6ed0317b
commit 86c0276156
1022 files changed
+69903 -19207

No files matched your search

+54
View File
@@ -1,7 +1,10 @@
package service
import (
"slices"
"github.com/QuantumNous/new-api/model"
relaycommon "github.com/QuantumNous/new-api/relay/common"
"github.com/QuantumNous/new-api/relaykit/dto"
)
@@ -23,6 +26,57 @@ func effectiveBillingUsage(usage *dto.Usage) *dto.Usage {
return usage
}
type claudeCacheReadAdjustment struct {
Rule string `json:"rule"`
Model string `json:"model"`
OriginalInputTokens int `json:"original_input_tokens"`
InputTokens int `json:"input_tokens"`
CacheReadTokens int `json:"cache_read_tokens"`
Status string `json:"status"`
}
// normalizeClaudeCacheReadUsage runs once after canonical upstream usage is
// selected. Only the billing copy changes; downstream responses and the
// original upstream snapshot retain their protocol values.
func normalizeClaudeCacheReadUsage(info *relaycommon.RelayInfo, usage *dto.Usage) (*dto.Usage, *claudeCacheReadAdjustment) {
if info == nil || info.ChannelMeta == nil || usage == nil ||
usage.UsageSemantic != dto.BillingUsageSemanticAnthropic ||
usage.BillingUsage == nil || usage.BillingUsage.Estimated || usage.BillingUsage.ClaudeUsage == nil {
return usage, nil
}
upstreamModel := info.GetUpstreamModelName()
if info.ResponseModel != nil && info.ResponseModel.UpstreamModel != "" {
// Some handlers replace UpstreamModelName with the response model.
// Match the name sent upstream, never the provider's response declaration.
upstreamModel = info.ResponseModel.UpstreamModel
}
if !slices.Contains(info.ChannelOtherSettings.ClaudeInputIncludesCacheReadModels, upstreamModel) {
return usage, nil
}
cached := usage.PromptTokensDetails.CachedTokens
adjustment := &claudeCacheReadAdjustment{
Rule: "claude_input_includes_cache_read_models", Model: upstreamModel,
OriginalInputTokens: usage.PromptTokens, InputTokens: usage.PromptTokens,
CacheReadTokens: cached, Status: "invalid_usage",
}
if usage.PromptTokens < 0 || cached < 0 || cached > usage.PromptTokens ||
usage.CompletionTokens < 0 || usage.InputTokens < cached || usage.TotalTokens < cached {
return usage, adjustment
}
if cached == 0 {
return usage, nil
}
adjusted := *usage
adjusted.PromptTokens -= cached
adjusted.InputTokens -= cached
adjusted.TotalTokens -= cached
adjusted.BillingUsage = dto.CloneBillingUsage(usage.BillingUsage)
adjusted.BillingUsage.ClaudeUsage.InputTokens = adjusted.PromptTokens
adjustment.InputTokens = adjusted.PromptTokens
adjustment.Status = "applied"
return &adjusted, adjustment
}
func usageBillingPathForLog(isLocalCountTokens bool, usage *dto.Usage) string {
effectiveUsage, ok := usageFromBillingUsage(usage)
if !ok {