|
|
@@ -437,8 +437,10 @@ func StreamResponseClaude2OpenAI(reqMode int, claudeResponse *dto.ClaudeResponse
|
|
|
}
|
|
|
} else {
|
|
|
if claudeResponse.Type == "message_start" {
|
|
|
- response.Id = claudeResponse.Message.Id
|
|
|
- response.Model = claudeResponse.Message.Model
|
|
|
+ if claudeResponse.Message != nil {
|
|
|
+ response.Id = claudeResponse.Message.Id
|
|
|
+ response.Model = claudeResponse.Message.Model
|
|
|
+ }
|
|
|
//claudeUsage = &claudeResponse.Message.Usage
|
|
|
choice.Delta.SetContentString("")
|
|
|
choice.Delta.Role = "assistant"
|
|
|
@@ -589,35 +591,49 @@ type ClaudeResponseInfo struct {
|
|
|
}
|
|
|
|
|
|
func FormatClaudeResponseInfo(requestMode int, claudeResponse *dto.ClaudeResponse, oaiResponse *dto.ChatCompletionsStreamResponse, claudeInfo *ClaudeResponseInfo) bool {
|
|
|
+ if claudeInfo == nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if claudeInfo.Usage == nil {
|
|
|
+ claudeInfo.Usage = &dto.Usage{}
|
|
|
+ }
|
|
|
if requestMode == RequestModeCompletion {
|
|
|
claudeInfo.ResponseText.WriteString(claudeResponse.Completion)
|
|
|
} else {
|
|
|
if claudeResponse.Type == "message_start" {
|
|
|
- claudeInfo.ResponseId = claudeResponse.Message.Id
|
|
|
- claudeInfo.Model = claudeResponse.Message.Model
|
|
|
+ if claudeResponse.Message != nil {
|
|
|
+ claudeInfo.ResponseId = claudeResponse.Message.Id
|
|
|
+ claudeInfo.Model = claudeResponse.Message.Model
|
|
|
+ }
|
|
|
|
|
|
// message_start, 获取usage
|
|
|
- claudeInfo.Usage.PromptTokens = claudeResponse.Message.Usage.InputTokens
|
|
|
- claudeInfo.Usage.PromptTokensDetails.CachedTokens = claudeResponse.Message.Usage.CacheReadInputTokens
|
|
|
- claudeInfo.Usage.PromptTokensDetails.CachedCreationTokens = claudeResponse.Message.Usage.CacheCreationInputTokens
|
|
|
- claudeInfo.Usage.ClaudeCacheCreation5mTokens = claudeResponse.Message.Usage.GetCacheCreation5mTokens()
|
|
|
- claudeInfo.Usage.ClaudeCacheCreation1hTokens = claudeResponse.Message.Usage.GetCacheCreation1hTokens()
|
|
|
- claudeInfo.Usage.CompletionTokens = claudeResponse.Message.Usage.OutputTokens
|
|
|
- } else if claudeResponse.Type == "content_block_delta" {
|
|
|
- if claudeResponse.Delta.Text != nil {
|
|
|
- claudeInfo.ResponseText.WriteString(*claudeResponse.Delta.Text)
|
|
|
+ if claudeResponse.Message != nil && claudeResponse.Message.Usage != nil {
|
|
|
+ claudeInfo.Usage.PromptTokens = claudeResponse.Message.Usage.InputTokens
|
|
|
+ claudeInfo.Usage.PromptTokensDetails.CachedTokens = claudeResponse.Message.Usage.CacheReadInputTokens
|
|
|
+ claudeInfo.Usage.PromptTokensDetails.CachedCreationTokens = claudeResponse.Message.Usage.CacheCreationInputTokens
|
|
|
+ claudeInfo.Usage.ClaudeCacheCreation5mTokens = claudeResponse.Message.Usage.GetCacheCreation5mTokens()
|
|
|
+ claudeInfo.Usage.ClaudeCacheCreation1hTokens = claudeResponse.Message.Usage.GetCacheCreation1hTokens()
|
|
|
+ claudeInfo.Usage.CompletionTokens = claudeResponse.Message.Usage.OutputTokens
|
|
|
}
|
|
|
- if claudeResponse.Delta.Thinking != nil {
|
|
|
- claudeInfo.ResponseText.WriteString(*claudeResponse.Delta.Thinking)
|
|
|
+ } else if claudeResponse.Type == "content_block_delta" {
|
|
|
+ if claudeResponse.Delta != nil {
|
|
|
+ if claudeResponse.Delta.Text != nil {
|
|
|
+ claudeInfo.ResponseText.WriteString(*claudeResponse.Delta.Text)
|
|
|
+ }
|
|
|
+ if claudeResponse.Delta.Thinking != nil {
|
|
|
+ claudeInfo.ResponseText.WriteString(*claudeResponse.Delta.Thinking)
|
|
|
+ }
|
|
|
}
|
|
|
} else if claudeResponse.Type == "message_delta" {
|
|
|
// 最终的usage获取
|
|
|
- if claudeResponse.Usage.InputTokens > 0 {
|
|
|
- // 不叠加,只取最新的
|
|
|
- claudeInfo.Usage.PromptTokens = claudeResponse.Usage.InputTokens
|
|
|
+ if claudeResponse.Usage != nil {
|
|
|
+ if claudeResponse.Usage.InputTokens > 0 {
|
|
|
+ // 不叠加,只取最新的
|
|
|
+ claudeInfo.Usage.PromptTokens = claudeResponse.Usage.InputTokens
|
|
|
+ }
|
|
|
+ claudeInfo.Usage.CompletionTokens = claudeResponse.Usage.OutputTokens
|
|
|
+ claudeInfo.Usage.TotalTokens = claudeInfo.Usage.PromptTokens + claudeInfo.Usage.CompletionTokens
|
|
|
}
|
|
|
- claudeInfo.Usage.CompletionTokens = claudeResponse.Usage.OutputTokens
|
|
|
- claudeInfo.Usage.TotalTokens = claudeInfo.Usage.PromptTokens + claudeInfo.Usage.CompletionTokens
|
|
|
|
|
|
// 判断是否完整
|
|
|
claudeInfo.Done = true
|
|
|
@@ -657,7 +673,9 @@ func HandleStreamResponseData(c *gin.Context, info *relaycommon.RelayInfo, claud
|
|
|
} else {
|
|
|
if claudeResponse.Type == "message_start" {
|
|
|
// message_start, 获取usage
|
|
|
- info.UpstreamModelName = claudeResponse.Message.Model
|
|
|
+ if claudeResponse.Message != nil {
|
|
|
+ info.UpstreamModelName = claudeResponse.Message.Model
|
|
|
+ }
|
|
|
} else if claudeResponse.Type == "content_block_delta" {
|
|
|
} else if claudeResponse.Type == "message_delta" {
|
|
|
}
|
|
|
@@ -745,13 +763,18 @@ func HandleClaudeResponseData(c *gin.Context, info *relaycommon.RelayInfo, claud
|
|
|
if requestMode == RequestModeCompletion {
|
|
|
claudeInfo.Usage = service.ResponseText2Usage(c, claudeResponse.Completion, info.UpstreamModelName, info.GetEstimatePromptTokens())
|
|
|
} else {
|
|
|
- claudeInfo.Usage.PromptTokens = claudeResponse.Usage.InputTokens
|
|
|
- claudeInfo.Usage.CompletionTokens = claudeResponse.Usage.OutputTokens
|
|
|
- claudeInfo.Usage.TotalTokens = claudeResponse.Usage.InputTokens + claudeResponse.Usage.OutputTokens
|
|
|
- claudeInfo.Usage.PromptTokensDetails.CachedTokens = claudeResponse.Usage.CacheReadInputTokens
|
|
|
- claudeInfo.Usage.PromptTokensDetails.CachedCreationTokens = claudeResponse.Usage.CacheCreationInputTokens
|
|
|
- claudeInfo.Usage.ClaudeCacheCreation5mTokens = claudeResponse.Usage.GetCacheCreation5mTokens()
|
|
|
- claudeInfo.Usage.ClaudeCacheCreation1hTokens = claudeResponse.Usage.GetCacheCreation1hTokens()
|
|
|
+ if claudeInfo.Usage == nil {
|
|
|
+ claudeInfo.Usage = &dto.Usage{}
|
|
|
+ }
|
|
|
+ if claudeResponse.Usage != nil {
|
|
|
+ claudeInfo.Usage.PromptTokens = claudeResponse.Usage.InputTokens
|
|
|
+ claudeInfo.Usage.CompletionTokens = claudeResponse.Usage.OutputTokens
|
|
|
+ claudeInfo.Usage.TotalTokens = claudeResponse.Usage.InputTokens + claudeResponse.Usage.OutputTokens
|
|
|
+ claudeInfo.Usage.PromptTokensDetails.CachedTokens = claudeResponse.Usage.CacheReadInputTokens
|
|
|
+ claudeInfo.Usage.PromptTokensDetails.CachedCreationTokens = claudeResponse.Usage.CacheCreationInputTokens
|
|
|
+ claudeInfo.Usage.ClaudeCacheCreation5mTokens = claudeResponse.Usage.GetCacheCreation5mTokens()
|
|
|
+ claudeInfo.Usage.ClaudeCacheCreation1hTokens = claudeResponse.Usage.GetCacheCreation1hTokens()
|
|
|
+ }
|
|
|
}
|
|
|
var responseData []byte
|
|
|
switch info.RelayFormat {
|
|
|
@@ -766,7 +789,7 @@ func HandleClaudeResponseData(c *gin.Context, info *relaycommon.RelayInfo, claud
|
|
|
responseData = data
|
|
|
}
|
|
|
|
|
|
- if claudeResponse.Usage.ServerToolUse != nil && claudeResponse.Usage.ServerToolUse.WebSearchRequests > 0 {
|
|
|
+ if claudeResponse.Usage != nil && claudeResponse.Usage.ServerToolUse != nil && claudeResponse.Usage.ServerToolUse.WebSearchRequests > 0 {
|
|
|
c.Set("claude_web_search_requests", claudeResponse.Usage.ServerToolUse.WebSearchRequests)
|
|
|
}
|
|
|
|