Skip to content

Commit dae9fcf

Browse files
author
cyk
committed
fix(translator): apply upstream router-for-me#1077 fix - separate functionDeclarations and googleSearch tools
1 parent b2a0830 commit dae9fcf

4 files changed

Lines changed: 55 additions & 43 deletions

File tree

go.mod

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,9 @@ require (
7171
github.com/tidwall/pretty v1.2.0 // indirect
7272
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
7373
github.com/ugorji/go/codec v1.2.12 // indirect
74-
<<<<<<< HEAD
7574
golang.org/x/arch v0.16.0 // indirect
7675
golang.org/x/sys v0.38.0 // indirect
77-
google.golang.org/protobuf v1.36.6 // indirect
78-
=======
79-
golang.org/x/arch v0.8.0 // indirect
80-
golang.org/x/sys v0.38.0 // indirect
8176
golang.org/x/text v0.31.0 // indirect
82-
google.golang.org/protobuf v1.34.1 // indirect
83-
>>>>>>> origin/main
77+
google.golang.org/protobuf v1.36.6 // indirect
8478
gopkg.in/ini.v1 v1.67.0 // indirect
8579
)

internal/translator/antigravity/openai/chat-completions/antigravity_openai_request.go

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,12 @@ func ConvertOpenAIRequestToAntigravity(modelName string, inputRawJSON []byte, _
324324
out, _ = sjson.SetRawBytes(out, "request.contents", buf.Bytes())
325325
}
326326

327-
// tools -> request.tools[0].functionDeclarations + request.tools[0].googleSearch passthrough
327+
// tools -> request.tools[].functionDeclarations + request.tools[].googleSearch passthrough
328328
tools := parsed.Get("tools")
329329
if tools.IsArray() && len(tools.Array()) > 0 {
330-
toolNode := []byte(`{}`)
331-
hasTool := false
330+
functionToolNode := []byte(`{}`)
332331
hasFunction := false
332+
googleSearchNodes := make([][]byte, 0)
333333
for _, t := range tools.Array() {
334334
if t.Get("type").String() == "function" {
335335
fn := t.Get("function")
@@ -368,31 +368,37 @@ func ConvertOpenAIRequestToAntigravity(modelName string, inputRawJSON []byte, _
368368
}
369369
fnRaw, _ = sjson.Delete(fnRaw, "strict")
370370
if !hasFunction {
371-
toolNode, _ = sjson.SetRawBytes(toolNode, "functionDeclarations", []byte("[]"))
371+
functionToolNode, _ = sjson.SetRawBytes(functionToolNode, "functionDeclarations", []byte("[]"))
372372
}
373-
tmp, errSet := sjson.SetRawBytes(toolNode, "functionDeclarations.-1", []byte(fnRaw))
373+
tmp, errSet := sjson.SetRawBytes(functionToolNode, "functionDeclarations.-1", []byte(fnRaw))
374374
if errSet != nil {
375375
log.Warnf("Failed to append tool declaration for '%s': %v", fn.Get("name").String(), errSet)
376376
continue
377377
}
378-
toolNode = tmp
378+
functionToolNode = tmp
379379
hasFunction = true
380-
hasTool = true
381380
}
382381
}
383382
if gs := t.Get("google_search"); gs.Exists() {
383+
googleToolNode := []byte(`{}`)
384384
var errSet error
385-
toolNode, errSet = sjson.SetRawBytes(toolNode, "googleSearch", []byte(gs.Raw))
385+
googleToolNode, errSet = sjson.SetRawBytes(googleToolNode, "googleSearch", []byte(gs.Raw))
386386
if errSet != nil {
387387
log.Warnf("Failed to set googleSearch tool: %v", errSet)
388388
continue
389389
}
390-
hasTool = true
390+
googleSearchNodes = append(googleSearchNodes, googleToolNode)
391391
}
392392
}
393-
if hasTool {
394-
out, _ = sjson.SetRawBytes(out, "request.tools", []byte("[]"))
395-
out, _ = sjson.SetRawBytes(out, "request.tools.0", toolNode)
393+
if hasFunction || len(googleSearchNodes) > 0 {
394+
toolsNode := []byte("[]")
395+
if hasFunction {
396+
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode)
397+
}
398+
for _, googleNode := range googleSearchNodes {
399+
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode)
400+
}
401+
out, _ = sjson.SetRawBytes(out, "request.tools", toolsNode)
396402
}
397403
}
398404

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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,12 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, inputRawJSON []byte, _ bo
283283
}
284284
}
285285

286-
// tools -> request.tools[0].functionDeclarations + request.tools[0].googleSearch passthrough
286+
// tools -> request.tools[].functionDeclarations + request.tools[].googleSearch passthrough
287287
tools := gjson.GetBytes(rawJSON, "tools")
288288
if tools.IsArray() && len(tools.Array()) > 0 {
289-
toolNode := []byte(`{}`)
290-
hasTool := false
289+
functionToolNode := []byte(`{}`)
291290
hasFunction := false
291+
googleSearchNodes := make([][]byte, 0)
292292
for _, t := range tools.Array() {
293293
if t.Get("type").String() == "function" {
294294
fn := t.Get("function")
@@ -327,31 +327,37 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, inputRawJSON []byte, _ bo
327327
}
328328
fnRaw, _ = sjson.Delete(fnRaw, "strict")
329329
if !hasFunction {
330-
toolNode, _ = sjson.SetRawBytes(toolNode, "functionDeclarations", []byte("[]"))
330+
functionToolNode, _ = sjson.SetRawBytes(functionToolNode, "functionDeclarations", []byte("[]"))
331331
}
332-
tmp, errSet := sjson.SetRawBytes(toolNode, "functionDeclarations.-1", []byte(fnRaw))
332+
tmp, errSet := sjson.SetRawBytes(functionToolNode, "functionDeclarations.-1", []byte(fnRaw))
333333
if errSet != nil {
334334
log.Warnf("Failed to append tool declaration for '%s': %v", fn.Get("name").String(), errSet)
335335
continue
336336
}
337-
toolNode = tmp
337+
functionToolNode = tmp
338338
hasFunction = true
339-
hasTool = true
340339
}
341340
}
342341
if gs := t.Get("google_search"); gs.Exists() {
342+
googleToolNode := []byte(`{}`)
343343
var errSet error
344-
toolNode, errSet = sjson.SetRawBytes(toolNode, "googleSearch", []byte(gs.Raw))
344+
googleToolNode, errSet = sjson.SetRawBytes(googleToolNode, "googleSearch", []byte(gs.Raw))
345345
if errSet != nil {
346346
log.Warnf("Failed to set googleSearch tool: %v", errSet)
347347
continue
348348
}
349-
hasTool = true
349+
googleSearchNodes = append(googleSearchNodes, googleToolNode)
350350
}
351351
}
352-
if hasTool {
353-
out, _ = sjson.SetRawBytes(out, "request.tools", []byte("[]"))
354-
out, _ = sjson.SetRawBytes(out, "request.tools.0", toolNode)
352+
if hasFunction || len(googleSearchNodes) > 0 {
353+
toolsNode := []byte("[]")
354+
if hasFunction {
355+
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode)
356+
}
357+
for _, googleNode := range googleSearchNodes {
358+
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode)
359+
}
360+
out, _ = sjson.SetRawBytes(out, "request.tools", toolsNode)
355361
}
356362
}
357363

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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,12 @@ func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
289289
}
290290
}
291291

292-
// tools -> tools[0].functionDeclarations + tools[0].googleSearch passthrough
292+
// tools -> tools[].functionDeclarations + tools[].googleSearch passthrough
293293
tools := gjson.GetBytes(rawJSON, "tools")
294294
if tools.IsArray() && len(tools.Array()) > 0 {
295-
toolNode := []byte(`{}`)
296-
hasTool := false
295+
functionToolNode := []byte(`{}`)
297296
hasFunction := false
297+
googleSearchNodes := make([][]byte, 0)
298298
for _, t := range tools.Array() {
299299
if t.Get("type").String() == "function" {
300300
fn := t.Get("function")
@@ -333,31 +333,37 @@ func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
333333
}
334334
fnRaw, _ = sjson.Delete(fnRaw, "strict")
335335
if !hasFunction {
336-
toolNode, _ = sjson.SetRawBytes(toolNode, "functionDeclarations", []byte("[]"))
336+
functionToolNode, _ = sjson.SetRawBytes(functionToolNode, "functionDeclarations", []byte("[]"))
337337
}
338-
tmp, errSet := sjson.SetRawBytes(toolNode, "functionDeclarations.-1", []byte(fnRaw))
338+
tmp, errSet := sjson.SetRawBytes(functionToolNode, "functionDeclarations.-1", []byte(fnRaw))
339339
if errSet != nil {
340340
log.Warnf("Failed to append tool declaration for '%s': %v", fn.Get("name").String(), errSet)
341341
continue
342342
}
343-
toolNode = tmp
343+
functionToolNode = tmp
344344
hasFunction = true
345-
hasTool = true
346345
}
347346
}
348347
if gs := t.Get("google_search"); gs.Exists() {
348+
googleToolNode := []byte(`{}`)
349349
var errSet error
350-
toolNode, errSet = sjson.SetRawBytes(toolNode, "googleSearch", []byte(gs.Raw))
350+
googleToolNode, errSet = sjson.SetRawBytes(googleToolNode, "googleSearch", []byte(gs.Raw))
351351
if errSet != nil {
352352
log.Warnf("Failed to set googleSearch tool: %v", errSet)
353353
continue
354354
}
355-
hasTool = true
355+
googleSearchNodes = append(googleSearchNodes, googleToolNode)
356356
}
357357
}
358-
if hasTool {
359-
out, _ = sjson.SetRawBytes(out, "tools", []byte("[]"))
360-
out, _ = sjson.SetRawBytes(out, "tools.0", toolNode)
358+
if hasFunction || len(googleSearchNodes) > 0 {
359+
toolsNode := []byte("[]")
360+
if hasFunction {
361+
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode)
362+
}
363+
for _, googleNode := range googleSearchNodes {
364+
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode)
365+
}
366+
out, _ = sjson.SetRawBytes(out, "tools", toolsNode)
361367
}
362368
}
363369

0 commit comments

Comments
 (0)