@@ -555,6 +555,35 @@ type ClaudeResponseInfo struct {
555555 Done bool
556556}
557557
558+ func cacheCreationTokensForOpenAIUsage (usage * dto.Usage ) int {
559+ if usage == nil {
560+ return 0
561+ }
562+ splitCacheCreationTokens := usage .ClaudeCacheCreation5mTokens + usage .ClaudeCacheCreation1hTokens
563+ if splitCacheCreationTokens == 0 {
564+ return usage .PromptTokensDetails .CachedCreationTokens
565+ }
566+ if usage .PromptTokensDetails .CachedCreationTokens > splitCacheCreationTokens {
567+ return usage .PromptTokensDetails .CachedCreationTokens
568+ }
569+ return splitCacheCreationTokens
570+ }
571+
572+ func buildOpenAIStyleUsageFromClaudeUsage (usage * dto.Usage ) dto.Usage {
573+ if usage == nil {
574+ return dto.Usage {}
575+ }
576+ clone := * usage
577+ cacheCreationTokens := cacheCreationTokensForOpenAIUsage (usage )
578+ totalInputTokens := usage .PromptTokens + usage .PromptTokensDetails .CachedTokens + cacheCreationTokens
579+ clone .PromptTokens = totalInputTokens
580+ clone .InputTokens = totalInputTokens
581+ clone .TotalTokens = totalInputTokens + usage .CompletionTokens
582+ clone .UsageSemantic = "openai"
583+ clone .UsageSource = "anthropic"
584+ return clone
585+ }
586+
558587func buildMessageDeltaPatchUsage (claudeResponse * dto.ClaudeResponse , claudeInfo * ClaudeResponseInfo ) * dto.ClaudeUsage {
559588 usage := & dto.ClaudeUsage {}
560589 if claudeResponse != nil && claudeResponse .Usage != nil {
@@ -643,6 +672,7 @@ func FormatClaudeResponseInfo(claudeResponse *dto.ClaudeResponse, oaiResponse *d
643672 // message_start, 获取usage
644673 if claudeResponse .Message != nil && claudeResponse .Message .Usage != nil {
645674 claudeInfo .Usage .PromptTokens = claudeResponse .Message .Usage .InputTokens
675+ claudeInfo .Usage .UsageSemantic = "anthropic"
646676 claudeInfo .Usage .PromptTokensDetails .CachedTokens = claudeResponse .Message .Usage .CacheReadInputTokens
647677 claudeInfo .Usage .PromptTokensDetails .CachedCreationTokens = claudeResponse .Message .Usage .CacheCreationInputTokens
648678 claudeInfo .Usage .ClaudeCacheCreation5mTokens = claudeResponse .Message .Usage .GetCacheCreation5mTokens ()
@@ -661,6 +691,7 @@ func FormatClaudeResponseInfo(claudeResponse *dto.ClaudeResponse, oaiResponse *d
661691 } else if claudeResponse .Type == "message_delta" {
662692 // 最终的usage获取
663693 if claudeResponse .Usage != nil {
694+ claudeInfo .Usage .UsageSemantic = "anthropic"
664695 if claudeResponse .Usage .InputTokens > 0 {
665696 // 不叠加,只取最新的
666697 claudeInfo .Usage .PromptTokens = claudeResponse .Usage .InputTokens
@@ -754,12 +785,16 @@ func HandleStreamFinalResponse(c *gin.Context, info *relaycommon.RelayInfo, clau
754785 }
755786 claudeInfo .Usage = service .ResponseText2Usage (c , claudeInfo .ResponseText .String (), info .UpstreamModelName , claudeInfo .Usage .PromptTokens )
756787 }
788+ if claudeInfo .Usage != nil {
789+ claudeInfo .Usage .UsageSemantic = "anthropic"
790+ }
757791
758792 if info .RelayFormat == types .RelayFormatClaude {
759793 //
760794 } else if info .RelayFormat == types .RelayFormatOpenAI {
761795 if info .ShouldIncludeUsage {
762- response := helper .GenerateFinalUsageResponse (claudeInfo .ResponseId , claudeInfo .Created , info .UpstreamModelName , * claudeInfo .Usage )
796+ openAIUsage := buildOpenAIStyleUsageFromClaudeUsage (claudeInfo .Usage )
797+ response := helper .GenerateFinalUsageResponse (claudeInfo .ResponseId , claudeInfo .Created , info .UpstreamModelName , openAIUsage )
763798 err := helper .ObjectData (c , response )
764799 if err != nil {
765800 common .SysLog ("send final response failed: " + err .Error ())
@@ -810,6 +845,7 @@ func HandleClaudeResponseData(c *gin.Context, info *relaycommon.RelayInfo, claud
810845 claudeInfo .Usage .PromptTokens = claudeResponse .Usage .InputTokens
811846 claudeInfo .Usage .CompletionTokens = claudeResponse .Usage .OutputTokens
812847 claudeInfo .Usage .TotalTokens = claudeResponse .Usage .InputTokens + claudeResponse .Usage .OutputTokens
848+ claudeInfo .Usage .UsageSemantic = "anthropic"
813849 claudeInfo .Usage .PromptTokensDetails .CachedTokens = claudeResponse .Usage .CacheReadInputTokens
814850 claudeInfo .Usage .PromptTokensDetails .CachedCreationTokens = claudeResponse .Usage .CacheCreationInputTokens
815851 claudeInfo .Usage .ClaudeCacheCreation5mTokens = claudeResponse .Usage .GetCacheCreation5mTokens ()
@@ -819,7 +855,7 @@ func HandleClaudeResponseData(c *gin.Context, info *relaycommon.RelayInfo, claud
819855 switch info .RelayFormat {
820856 case types .RelayFormatOpenAI :
821857 openaiResponse := ResponseClaude2OpenAI (& claudeResponse )
822- openaiResponse .Usage = * claudeInfo .Usage
858+ openaiResponse .Usage = buildOpenAIStyleUsageFromClaudeUsage ( claudeInfo .Usage )
823859 responseData , err = json .Marshal (openaiResponse )
824860 if err != nil {
825861 return types .NewError (err , types .ErrorCodeBadResponseBody )
0 commit comments