Skip to content

Commit 0d89a22

Browse files
committed
feat: add handling for function call finish reasons in OpenAI response conversion
1 parent 9319602 commit 0d89a22

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

internal/translator/gemini-cli/openai/chat-completions/cli_openai_response.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ
9797

9898
// Process the main content part of the response.
9999
partsResult := gjson.GetBytes(rawJSON, "response.candidates.0.content.parts")
100+
hasFunctionCall := false
100101
if partsResult.IsArray() {
101102
partResults := partsResult.Array()
102103
for i := 0; i < len(partResults); i++ {
@@ -118,6 +119,7 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ
118119
template, _ = sjson.Set(template, "choices.0.delta.role", "assistant")
119120
} else if functionCallResult.Exists() {
120121
// Handle function call content.
122+
hasFunctionCall = true
121123
toolCallsResult := gjson.Get(template, "choices.0.delta.tool_calls")
122124
functionCallIndex := (*param).(*convertCliResponseToOpenAIChatParams).FunctionIndex
123125
(*param).(*convertCliResponseToOpenAIChatParams).FunctionIndex++
@@ -169,6 +171,11 @@ func ConvertCliResponseToOpenAI(_ context.Context, _ string, originalRequestRawJ
169171
}
170172
}
171173

174+
if hasFunctionCall {
175+
template, _ = sjson.Set(template, "choices.0.finish_reason", "tool_calls")
176+
template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls")
177+
}
178+
172179
return []string{template}
173180
}
174181

internal/translator/gemini/openai/chat-completions/gemini_openai_response.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ func ConvertGeminiResponseToOpenAI(_ context.Context, _ string, originalRequestR
100100

101101
// Process the main content part of the response.
102102
partsResult := gjson.GetBytes(rawJSON, "candidates.0.content.parts")
103+
hasFunctionCall := false
103104
if partsResult.IsArray() {
104105
partResults := partsResult.Array()
105106
for i := 0; i < len(partResults); i++ {
@@ -121,6 +122,7 @@ func ConvertGeminiResponseToOpenAI(_ context.Context, _ string, originalRequestR
121122
template, _ = sjson.Set(template, "choices.0.delta.role", "assistant")
122123
} else if functionCallResult.Exists() {
123124
// Handle function call content.
125+
hasFunctionCall = true
124126
toolCallsResult := gjson.Get(template, "choices.0.delta.tool_calls")
125127
functionCallIndex := (*param).(*convertGeminiResponseToOpenAIChatParams).FunctionIndex
126128
(*param).(*convertGeminiResponseToOpenAIChatParams).FunctionIndex++
@@ -172,6 +174,11 @@ func ConvertGeminiResponseToOpenAI(_ context.Context, _ string, originalRequestR
172174
}
173175
}
174176

177+
if hasFunctionCall {
178+
template, _ = sjson.Set(template, "choices.0.finish_reason", "tool_calls")
179+
template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls")
180+
}
181+
175182
return []string{template}
176183
}
177184

@@ -231,6 +238,7 @@ func ConvertGeminiResponseToOpenAINonStream(_ context.Context, _ string, origina
231238

232239
// Process the main content part of the response.
233240
partsResult := gjson.GetBytes(rawJSON, "candidates.0.content.parts")
241+
hasFunctionCall := false
234242
if partsResult.IsArray() {
235243
partsResults := partsResult.Array()
236244
for i := 0; i < len(partsResults); i++ {
@@ -252,6 +260,7 @@ func ConvertGeminiResponseToOpenAINonStream(_ context.Context, _ string, origina
252260
template, _ = sjson.Set(template, "choices.0.message.role", "assistant")
253261
} else if functionCallResult.Exists() {
254262
// Append function call content to the tool_calls array.
263+
hasFunctionCall = true
255264
toolCallsResult := gjson.Get(template, "choices.0.message.tool_calls")
256265
if !toolCallsResult.Exists() || !toolCallsResult.IsArray() {
257266
template, _ = sjson.SetRaw(template, "choices.0.message.tool_calls", `[]`)
@@ -297,5 +306,10 @@ func ConvertGeminiResponseToOpenAINonStream(_ context.Context, _ string, origina
297306
}
298307
}
299308

309+
if hasFunctionCall {
310+
template, _ = sjson.Set(template, "choices.0.finish_reason", "tool_calls")
311+
template, _ = sjson.Set(template, "choices.0.native_finish_reason", "tool_calls")
312+
}
313+
300314
return template
301315
}

0 commit comments

Comments
 (0)