From b05cfd9f846d871a235a0009e77b3ea8a294a411 Mon Sep 17 00:00:00 2001 From: hkfires <10558748+hkfires@users.noreply.github.com> Date: Sat, 22 Nov 2025 13:03:50 +0800 Subject: [PATCH] fix(translator): include empty text chunks in responses --- .../chat-completions/antigravity_openai_response.go | 12 ------------ .../chat-completions/gemini-cli_openai_response.go | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/internal/translator/antigravity/openai/chat-completions/antigravity_openai_response.go b/internal/translator/antigravity/openai/chat-completions/antigravity_openai_response.go index cd6f4043..c70daaf2 100644 --- a/internal/translator/antigravity/openai/chat-completions/antigravity_openai_response.go +++ b/internal/translator/antigravity/openai/chat-completions/antigravity_openai_response.go @@ -98,7 +98,6 @@ func ConvertAntigravityResponseToOpenAI(_ context.Context, _ string, originalReq // Process the main content part of the response. partsResult := gjson.GetBytes(rawJSON, "response.candidates.0.content.parts") hasFunctionCall := false - hasValidContent := false if partsResult.IsArray() { partResults := partsResult.Array() for i := 0; i < len(partResults); i++ { @@ -119,10 +118,6 @@ func ConvertAntigravityResponseToOpenAI(_ context.Context, _ string, originalReq if partTextResult.Exists() { textContent := partTextResult.String() - // Skip empty text content to avoid generating unnecessary chunks - if textContent == "" { - continue - } // Handle text content, distinguishing between regular content and reasoning/thoughts. if partResult.Get("thought").Bool() { @@ -131,7 +126,6 @@ func ConvertAntigravityResponseToOpenAI(_ context.Context, _ string, originalReq template, _ = sjson.Set(template, "choices.0.delta.content", textContent) } template, _ = sjson.Set(template, "choices.0.delta.role", "assistant") - hasValidContent = true } else if functionCallResult.Exists() { // Handle function call content. hasFunctionCall = true @@ -191,12 +185,6 @@ func ConvertAntigravityResponseToOpenAI(_ context.Context, _ string, originalReq template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls") } - // Only return a chunk if there's actual content or a finish reason - finishReason := gjson.GetBytes(rawJSON, "response.candidates.0.finishReason") - if !hasValidContent && !finishReason.Exists() { - return []string{} - } - return []string{template} } diff --git a/internal/translator/gemini-cli/openai/chat-completions/gemini-cli_openai_response.go b/internal/translator/gemini-cli/openai/chat-completions/gemini-cli_openai_response.go index 86699c7e..73df7a7c 100644 --- a/internal/translator/gemini-cli/openai/chat-completions/gemini-cli_openai_response.go +++ b/internal/translator/gemini-cli/openai/chat-completions/gemini-cli_openai_response.go @@ -98,7 +98,6 @@ 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 - hasValidContent := false if partsResult.IsArray() { partResults := partsResult.Array() for i := 0; i < len(partResults); i++ { @@ -119,10 +118,6 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ if partTextResult.Exists() { textContent := partTextResult.String() - // Skip empty text content to avoid generating unnecessary chunks - if textContent == "" { - continue - } // Handle text content, distinguishing between regular content and reasoning/thoughts. if partResult.Get("thought").Bool() { @@ -131,7 +126,6 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ template, _ = sjson.Set(template, "choices.0.delta.content", textContent) } template, _ = sjson.Set(template, "choices.0.delta.role", "assistant") - hasValidContent = true } else if functionCallResult.Exists() { // Handle function call content. hasFunctionCall = true @@ -191,12 +185,6 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls") } - // Only return a chunk if there's actual content or a finish reason - finishReason := gjson.GetBytes(rawJSON, "response.candidates.0.finishReason") - if !hasValidContent && !finishReason.Exists() { - return []string{} - } - return []string{template} }