diff --git a/internal/translator/gemini-cli/openai/chat-completions/cli_openai_response.go b/internal/translator/gemini-cli/openai/chat-completions/cli_openai_response.go index 15f528cc..72d0f089 100644 --- a/internal/translator/gemini-cli/openai/chat-completions/cli_openai_response.go +++ b/internal/translator/gemini-cli/openai/chat-completions/cli_openai_response.go @@ -97,6 +97,7 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ // Process the main content part of the response. partsResult := gjson.GetBytes(rawJSON, "response.candidates.0.content.parts") + hasFunctionCall := false if partsResult.IsArray() { partResults := partsResult.Array() for i := 0; i < len(partResults); i++ { @@ -118,6 +119,7 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ template, _ = sjson.Set(template, "choices.0.delta.role", "assistant") } else if functionCallResult.Exists() { // Handle function call content. + hasFunctionCall = true toolCallsResult := gjson.Get(template, "choices.0.delta.tool_calls") functionCallIndex := (*param).(*convertCliResponseToOpenAIChatParams).FunctionIndex (*param).(*convertCliResponseToOpenAIChatParams).FunctionIndex++ @@ -169,6 +171,11 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ } } + if hasFunctionCall { + template, _ = sjson.Set(template, "choices.0.finish_reason", "tool_calls") + template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls") + } + return []string{template} } diff --git a/internal/translator/gemini/openai/chat-completions/gemini_openai_response.go b/internal/translator/gemini/openai/chat-completions/gemini_openai_response.go index 5f1161af..4ce7f005 100644 --- a/internal/translator/gemini/openai/chat-completions/gemini_openai_response.go +++ b/internal/translator/gemini/openai/chat-completions/gemini_openai_response.go @@ -100,6 +100,7 @@ func ConvertGeminiResponseToOpenAI(_ context.Context, _ string, originalRequestR // Process the main content part of the response. partsResult := gjson.GetBytes(rawJSON, "candidates.0.content.parts") + hasFunctionCall := false if partsResult.IsArray() { partResults := partsResult.Array() for i := 0; i < len(partResults); i++ { @@ -121,6 +122,7 @@ func ConvertGeminiResponseToOpenAI(_ context.Context, _ string, originalRequestR template, _ = sjson.Set(template, "choices.0.delta.role", "assistant") } else if functionCallResult.Exists() { // Handle function call content. + hasFunctionCall = true toolCallsResult := gjson.Get(template, "choices.0.delta.tool_calls") functionCallIndex := (*param).(*convertGeminiResponseToOpenAIChatParams).FunctionIndex (*param).(*convertGeminiResponseToOpenAIChatParams).FunctionIndex++ @@ -172,6 +174,11 @@ func ConvertGeminiResponseToOpenAI(_ context.Context, _ string, originalRequestR } } + if hasFunctionCall { + template, _ = sjson.Set(template, "choices.0.finish_reason", "tool_calls") + template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls") + } + return []string{template} } @@ -231,6 +238,7 @@ func ConvertGeminiResponseToOpenAINonStream(_ context.Context, _ string, origina // Process the main content part of the response. partsResult := gjson.GetBytes(rawJSON, "candidates.0.content.parts") + hasFunctionCall := false if partsResult.IsArray() { partsResults := partsResult.Array() for i := 0; i < len(partsResults); i++ { @@ -252,6 +260,7 @@ func ConvertGeminiResponseToOpenAINonStream(_ context.Context, _ string, origina template, _ = sjson.Set(template, "choices.0.message.role", "assistant") } else if functionCallResult.Exists() { // Append function call content to the tool_calls array. + hasFunctionCall = true toolCallsResult := gjson.Get(template, "choices.0.message.tool_calls") if !toolCallsResult.Exists() || !toolCallsResult.IsArray() { template, _ = sjson.SetRaw(template, "choices.0.message.tool_calls", `[]`) @@ -297,5 +306,10 @@ func ConvertGeminiResponseToOpenAINonStream(_ context.Context, _ string, origina } } + if hasFunctionCall { + template, _ = sjson.Set(template, "choices.0.finish_reason", "tool_calls") + template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls") + } + return template }