refactor(translator): improve tools handling by separating functionDeclarations and googleSearch nodes
This commit is contained in:
Luis Pater
2026-01-24 05:51:11 +08:00
parent c32e2a8196
commit 0d6ecb0191
3 changed files with 54 additions and 36 deletions

View File

@@ -305,12 +305,12 @@ func ConvertOpenAIRequestToAntigravity(modelName string, inputRawJSON []byte, _
} }
} }
// tools -> request.tools[0].functionDeclarations + request.tools[0].googleSearch passthrough // tools -> request.tools[].functionDeclarations + request.tools[].googleSearch passthrough
tools := gjson.GetBytes(rawJSON, "tools") tools := gjson.GetBytes(rawJSON, "tools")
if tools.IsArray() && len(tools.Array()) > 0 { if tools.IsArray() && len(tools.Array()) > 0 {
toolNode := []byte(`{}`) functionToolNode := []byte(`{}`)
hasTool := false
hasFunction := false hasFunction := false
googleSearchNodes := make([][]byte, 0)
for _, t := range tools.Array() { for _, t := range tools.Array() {
if t.Get("type").String() == "function" { if t.Get("type").String() == "function" {
fn := t.Get("function") fn := t.Get("function")
@@ -349,31 +349,37 @@ func ConvertOpenAIRequestToAntigravity(modelName string, inputRawJSON []byte, _
} }
fnRaw, _ = sjson.Delete(fnRaw, "strict") fnRaw, _ = sjson.Delete(fnRaw, "strict")
if !hasFunction { if !hasFunction {
toolNode, _ = sjson.SetRawBytes(toolNode, "functionDeclarations", []byte("[]")) functionToolNode, _ = sjson.SetRawBytes(functionToolNode, "functionDeclarations", []byte("[]"))
} }
tmp, errSet := sjson.SetRawBytes(toolNode, "functionDeclarations.-1", []byte(fnRaw)) tmp, errSet := sjson.SetRawBytes(functionToolNode, "functionDeclarations.-1", []byte(fnRaw))
if errSet != nil { if errSet != nil {
log.Warnf("Failed to append tool declaration for '%s': %v", fn.Get("name").String(), errSet) log.Warnf("Failed to append tool declaration for '%s': %v", fn.Get("name").String(), errSet)
continue continue
} }
toolNode = tmp functionToolNode = tmp
hasFunction = true hasFunction = true
hasTool = true
} }
} }
if gs := t.Get("google_search"); gs.Exists() { if gs := t.Get("google_search"); gs.Exists() {
googleToolNode := []byte(`{}`)
var errSet error var errSet error
toolNode, errSet = sjson.SetRawBytes(toolNode, "googleSearch", []byte(gs.Raw)) googleToolNode, errSet = sjson.SetRawBytes(googleToolNode, "googleSearch", []byte(gs.Raw))
if errSet != nil { if errSet != nil {
log.Warnf("Failed to set googleSearch tool: %v", errSet) log.Warnf("Failed to set googleSearch tool: %v", errSet)
continue continue
} }
hasTool = true googleSearchNodes = append(googleSearchNodes, googleToolNode)
} }
} }
if hasTool { if hasFunction || len(googleSearchNodes) > 0 {
out, _ = sjson.SetRawBytes(out, "request.tools", []byte("[]")) toolsNode := []byte("[]")
out, _ = sjson.SetRawBytes(out, "request.tools.0", toolNode) if hasFunction {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode)
}
for _, googleNode := range googleSearchNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode)
}
out, _ = sjson.SetRawBytes(out, "request.tools", toolsNode)
} }
} }

View File

@@ -283,12 +283,12 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, inputRawJSON []byte, _ bo
} }
} }
// tools -> request.tools[0].functionDeclarations + request.tools[0].googleSearch passthrough // tools -> request.tools[].functionDeclarations + request.tools[].googleSearch passthrough
tools := gjson.GetBytes(rawJSON, "tools") tools := gjson.GetBytes(rawJSON, "tools")
if tools.IsArray() && len(tools.Array()) > 0 { if tools.IsArray() && len(tools.Array()) > 0 {
toolNode := []byte(`{}`) functionToolNode := []byte(`{}`)
hasTool := false
hasFunction := false hasFunction := false
googleSearchNodes := make([][]byte, 0)
for _, t := range tools.Array() { for _, t := range tools.Array() {
if t.Get("type").String() == "function" { if t.Get("type").String() == "function" {
fn := t.Get("function") fn := t.Get("function")
@@ -327,31 +327,37 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, inputRawJSON []byte, _ bo
} }
fnRaw, _ = sjson.Delete(fnRaw, "strict") fnRaw, _ = sjson.Delete(fnRaw, "strict")
if !hasFunction { if !hasFunction {
toolNode, _ = sjson.SetRawBytes(toolNode, "functionDeclarations", []byte("[]")) functionToolNode, _ = sjson.SetRawBytes(functionToolNode, "functionDeclarations", []byte("[]"))
} }
tmp, errSet := sjson.SetRawBytes(toolNode, "functionDeclarations.-1", []byte(fnRaw)) tmp, errSet := sjson.SetRawBytes(functionToolNode, "functionDeclarations.-1", []byte(fnRaw))
if errSet != nil { if errSet != nil {
log.Warnf("Failed to append tool declaration for '%s': %v", fn.Get("name").String(), errSet) log.Warnf("Failed to append tool declaration for '%s': %v", fn.Get("name").String(), errSet)
continue continue
} }
toolNode = tmp functionToolNode = tmp
hasFunction = true hasFunction = true
hasTool = true
} }
} }
if gs := t.Get("google_search"); gs.Exists() { if gs := t.Get("google_search"); gs.Exists() {
googleToolNode := []byte(`{}`)
var errSet error var errSet error
toolNode, errSet = sjson.SetRawBytes(toolNode, "googleSearch", []byte(gs.Raw)) googleToolNode, errSet = sjson.SetRawBytes(googleToolNode, "googleSearch", []byte(gs.Raw))
if errSet != nil { if errSet != nil {
log.Warnf("Failed to set googleSearch tool: %v", errSet) log.Warnf("Failed to set googleSearch tool: %v", errSet)
continue continue
} }
hasTool = true googleSearchNodes = append(googleSearchNodes, googleToolNode)
} }
} }
if hasTool { if hasFunction || len(googleSearchNodes) > 0 {
out, _ = sjson.SetRawBytes(out, "request.tools", []byte("[]")) toolsNode := []byte("[]")
out, _ = sjson.SetRawBytes(out, "request.tools.0", toolNode) if hasFunction {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode)
}
for _, googleNode := range googleSearchNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode)
}
out, _ = sjson.SetRawBytes(out, "request.tools", toolsNode)
} }
} }

View File

@@ -289,12 +289,12 @@ func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
} }
} }
// tools -> tools[0].functionDeclarations + tools[0].googleSearch passthrough // tools -> tools[].functionDeclarations + tools[].googleSearch passthrough
tools := gjson.GetBytes(rawJSON, "tools") tools := gjson.GetBytes(rawJSON, "tools")
if tools.IsArray() && len(tools.Array()) > 0 { if tools.IsArray() && len(tools.Array()) > 0 {
toolNode := []byte(`{}`) functionToolNode := []byte(`{}`)
hasTool := false
hasFunction := false hasFunction := false
googleSearchNodes := make([][]byte, 0)
for _, t := range tools.Array() { for _, t := range tools.Array() {
if t.Get("type").String() == "function" { if t.Get("type").String() == "function" {
fn := t.Get("function") fn := t.Get("function")
@@ -333,31 +333,37 @@ func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
} }
fnRaw, _ = sjson.Delete(fnRaw, "strict") fnRaw, _ = sjson.Delete(fnRaw, "strict")
if !hasFunction { if !hasFunction {
toolNode, _ = sjson.SetRawBytes(toolNode, "functionDeclarations", []byte("[]")) functionToolNode, _ = sjson.SetRawBytes(functionToolNode, "functionDeclarations", []byte("[]"))
} }
tmp, errSet := sjson.SetRawBytes(toolNode, "functionDeclarations.-1", []byte(fnRaw)) tmp, errSet := sjson.SetRawBytes(functionToolNode, "functionDeclarations.-1", []byte(fnRaw))
if errSet != nil { if errSet != nil {
log.Warnf("Failed to append tool declaration for '%s': %v", fn.Get("name").String(), errSet) log.Warnf("Failed to append tool declaration for '%s': %v", fn.Get("name").String(), errSet)
continue continue
} }
toolNode = tmp functionToolNode = tmp
hasFunction = true hasFunction = true
hasTool = true
} }
} }
if gs := t.Get("google_search"); gs.Exists() { if gs := t.Get("google_search"); gs.Exists() {
googleToolNode := []byte(`{}`)
var errSet error var errSet error
toolNode, errSet = sjson.SetRawBytes(toolNode, "googleSearch", []byte(gs.Raw)) googleToolNode, errSet = sjson.SetRawBytes(googleToolNode, "googleSearch", []byte(gs.Raw))
if errSet != nil { if errSet != nil {
log.Warnf("Failed to set googleSearch tool: %v", errSet) log.Warnf("Failed to set googleSearch tool: %v", errSet)
continue continue
} }
hasTool = true googleSearchNodes = append(googleSearchNodes, googleToolNode)
} }
} }
if hasTool { if hasFunction || len(googleSearchNodes) > 0 {
out, _ = sjson.SetRawBytes(out, "tools", []byte("[]")) toolsNode := []byte("[]")
out, _ = sjson.SetRawBytes(out, "tools.0", toolNode) if hasFunction {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode)
}
for _, googleNode := range googleSearchNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode)
}
out, _ = sjson.SetRawBytes(out, "tools", toolsNode)
} }
} }