Browse Source

feat: enhance request handling to support tool calls and improve stream options

CaIon 5 months ago
parent
commit
563825492e
3 changed files with 18 additions and 11 deletions
  1. 1 1
      relay/channel/openai/adaptor.go
  2. 3 0
      relay/channel/openai/relay-openai.go
  3. 14 10
      service/convert.go

+ 1 - 1
relay/channel/openai/adaptor.go

@@ -67,7 +67,7 @@ func (a *Adaptor) ConvertClaudeRequest(c *gin.Context, info *relaycommon.RelayIn
 	if err != nil {
 		return nil, err
 	}
-	if info.SupportStreamOptions {
+	if info.SupportStreamOptions && info.IsStream {
 		aiRequest.StreamOptions = &dto.StreamOptions{
 			IncludeUsage: true,
 		}

+ 3 - 0
relay/channel/openai/relay-openai.go

@@ -180,6 +180,9 @@ func OpenaiHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respo
 	if err != nil {
 		return nil, types.NewOpenAIError(err, types.ErrorCodeReadResponseBodyFailed, http.StatusInternalServerError)
 	}
+	if common.DebugEnabled {
+		println("upstream response body:", string(responseBody))
+	}
 	err = common.Unmarshal(responseBody, &simpleResponse)
 	if err != nil {
 		return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)

+ 14 - 10
service/convert.go

@@ -401,22 +401,26 @@ func ResponseOpenAI2Claude(openAIResponse *dto.OpenAITextResponse, info *relayco
 	}
 	for _, choice := range openAIResponse.Choices {
 		stopReason = stopReasonOpenAI2Claude(choice.FinishReason)
-		claudeContent := dto.ClaudeMediaMessage{}
 		if choice.FinishReason == "tool_calls" {
-			claudeContent.Type = "tool_use"
-			claudeContent.Id = choice.Message.ToolCallId
-			claudeContent.Name = choice.Message.ParseToolCalls()[0].Function.Name
-			var mapParams map[string]interface{}
-			if err := json.Unmarshal([]byte(choice.Message.ParseToolCalls()[0].Function.Arguments), &mapParams); err == nil {
-				claudeContent.Input = mapParams
-			} else {
-				claudeContent.Input = choice.Message.ParseToolCalls()[0].Function.Arguments
+			for _, toolUse := range choice.Message.ParseToolCalls() {
+				claudeContent := dto.ClaudeMediaMessage{}
+				claudeContent.Type = "tool_use"
+				claudeContent.Id = toolUse.ID
+				claudeContent.Name = toolUse.Function.Name
+				var mapParams map[string]interface{}
+				if err := common.Unmarshal([]byte(toolUse.Function.Arguments), &mapParams); err == nil {
+					claudeContent.Input = mapParams
+				} else {
+					claudeContent.Input = toolUse.Function.Arguments
+				}
+				contents = append(contents, claudeContent)
 			}
 		} else {
+			claudeContent := dto.ClaudeMediaMessage{}
 			claudeContent.Type = "text"
 			claudeContent.SetText(choice.Message.StringContent())
+			contents = append(contents, claudeContent)
 		}
-		contents = append(contents, claudeContent)
 	}
 	claudeResponse.Content = contents
 	claudeResponse.StopReason = stopReason