From 563825492e7356cad5398823525a61db6ddf2cd2 Mon Sep 17 00:00:00 2001 From: CaIon Date: Fri, 8 Aug 2025 13:47:39 +0800 Subject: [PATCH] feat: enhance request handling to support tool calls and improve stream options --- relay/channel/openai/adaptor.go | 2 +- relay/channel/openai/relay-openai.go | 3 +++ service/convert.go | 24 ++++++++++++++---------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/relay/channel/openai/adaptor.go b/relay/channel/openai/adaptor.go index c74dbc12..8f81ab8c 100644 --- a/relay/channel/openai/adaptor.go +++ b/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, } diff --git a/relay/channel/openai/relay-openai.go b/relay/channel/openai/relay-openai.go index 9ae0a200..b8e72273 100644 --- a/relay/channel/openai/relay-openai.go +++ b/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) diff --git a/service/convert.go b/service/convert.go index 967e4682..925feae9 100644 --- a/service/convert.go +++ b/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