Merge pull request #1317 from yinkev/feat/gemini-tools-passthrough

feat(translator): add code_execution and url_context tool passthrough
This commit is contained in:
Luis Pater
2026-01-30 23:46:44 +08:00
committed by GitHub
3 changed files with 90 additions and 6 deletions

View File

@@ -305,12 +305,14 @@ func ConvertOpenAIRequestToAntigravity(modelName string, inputRawJSON []byte, _
} }
} }
// tools -> request.tools[].functionDeclarations + request.tools[].googleSearch passthrough // tools -> request.tools[].functionDeclarations + request.tools[].googleSearch/codeExecution/urlContext 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 {
functionToolNode := []byte(`{}`) functionToolNode := []byte(`{}`)
hasFunction := false hasFunction := false
googleSearchNodes := make([][]byte, 0) googleSearchNodes := make([][]byte, 0)
codeExecutionNodes := make([][]byte, 0)
urlContextNodes := 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")
@@ -370,8 +372,28 @@ func ConvertOpenAIRequestToAntigravity(modelName string, inputRawJSON []byte, _
} }
googleSearchNodes = append(googleSearchNodes, googleToolNode) googleSearchNodes = append(googleSearchNodes, googleToolNode)
} }
if ce := t.Get("code_execution"); ce.Exists() {
codeToolNode := []byte(`{}`)
var errSet error
codeToolNode, errSet = sjson.SetRawBytes(codeToolNode, "codeExecution", []byte(ce.Raw))
if errSet != nil {
log.Warnf("Failed to set codeExecution tool: %v", errSet)
continue
} }
if hasFunction || len(googleSearchNodes) > 0 { codeExecutionNodes = append(codeExecutionNodes, codeToolNode)
}
if uc := t.Get("url_context"); uc.Exists() {
urlToolNode := []byte(`{}`)
var errSet error
urlToolNode, errSet = sjson.SetRawBytes(urlToolNode, "urlContext", []byte(uc.Raw))
if errSet != nil {
log.Warnf("Failed to set urlContext tool: %v", errSet)
continue
}
urlContextNodes = append(urlContextNodes, urlToolNode)
}
}
if hasFunction || len(googleSearchNodes) > 0 || len(codeExecutionNodes) > 0 || len(urlContextNodes) > 0 {
toolsNode := []byte("[]") toolsNode := []byte("[]")
if hasFunction { if hasFunction {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode) toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode)
@@ -379,6 +401,12 @@ func ConvertOpenAIRequestToAntigravity(modelName string, inputRawJSON []byte, _
for _, googleNode := range googleSearchNodes { for _, googleNode := range googleSearchNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode) toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode)
} }
for _, codeNode := range codeExecutionNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", codeNode)
}
for _, urlNode := range urlContextNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", urlNode)
}
out, _ = sjson.SetRawBytes(out, "request.tools", toolsNode) out, _ = sjson.SetRawBytes(out, "request.tools", toolsNode)
} }
} }

View File

@@ -283,12 +283,14 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, inputRawJSON []byte, _ bo
} }
} }
// tools -> request.tools[].functionDeclarations + request.tools[].googleSearch passthrough // tools -> request.tools[].functionDeclarations + request.tools[].googleSearch/codeExecution/urlContext 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 {
functionToolNode := []byte(`{}`) functionToolNode := []byte(`{}`)
hasFunction := false hasFunction := false
googleSearchNodes := make([][]byte, 0) googleSearchNodes := make([][]byte, 0)
codeExecutionNodes := make([][]byte, 0)
urlContextNodes := 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")
@@ -348,8 +350,28 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, inputRawJSON []byte, _ bo
} }
googleSearchNodes = append(googleSearchNodes, googleToolNode) googleSearchNodes = append(googleSearchNodes, googleToolNode)
} }
if ce := t.Get("code_execution"); ce.Exists() {
codeToolNode := []byte(`{}`)
var errSet error
codeToolNode, errSet = sjson.SetRawBytes(codeToolNode, "codeExecution", []byte(ce.Raw))
if errSet != nil {
log.Warnf("Failed to set codeExecution tool: %v", errSet)
continue
} }
if hasFunction || len(googleSearchNodes) > 0 { codeExecutionNodes = append(codeExecutionNodes, codeToolNode)
}
if uc := t.Get("url_context"); uc.Exists() {
urlToolNode := []byte(`{}`)
var errSet error
urlToolNode, errSet = sjson.SetRawBytes(urlToolNode, "urlContext", []byte(uc.Raw))
if errSet != nil {
log.Warnf("Failed to set urlContext tool: %v", errSet)
continue
}
urlContextNodes = append(urlContextNodes, urlToolNode)
}
}
if hasFunction || len(googleSearchNodes) > 0 || len(codeExecutionNodes) > 0 || len(urlContextNodes) > 0 {
toolsNode := []byte("[]") toolsNode := []byte("[]")
if hasFunction { if hasFunction {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode) toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode)
@@ -357,6 +379,12 @@ func ConvertOpenAIRequestToGeminiCLI(modelName string, inputRawJSON []byte, _ bo
for _, googleNode := range googleSearchNodes { for _, googleNode := range googleSearchNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode) toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode)
} }
for _, codeNode := range codeExecutionNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", codeNode)
}
for _, urlNode := range urlContextNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", urlNode)
}
out, _ = sjson.SetRawBytes(out, "request.tools", toolsNode) out, _ = sjson.SetRawBytes(out, "request.tools", toolsNode)
} }
} }

View File

@@ -289,12 +289,14 @@ func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
} }
} }
// tools -> tools[].functionDeclarations + tools[].googleSearch passthrough // tools -> tools[].functionDeclarations + tools[].googleSearch/codeExecution/urlContext 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 {
functionToolNode := []byte(`{}`) functionToolNode := []byte(`{}`)
hasFunction := false hasFunction := false
googleSearchNodes := make([][]byte, 0) googleSearchNodes := make([][]byte, 0)
codeExecutionNodes := make([][]byte, 0)
urlContextNodes := 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")
@@ -354,8 +356,28 @@ func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
} }
googleSearchNodes = append(googleSearchNodes, googleToolNode) googleSearchNodes = append(googleSearchNodes, googleToolNode)
} }
if ce := t.Get("code_execution"); ce.Exists() {
codeToolNode := []byte(`{}`)
var errSet error
codeToolNode, errSet = sjson.SetRawBytes(codeToolNode, "codeExecution", []byte(ce.Raw))
if errSet != nil {
log.Warnf("Failed to set codeExecution tool: %v", errSet)
continue
} }
if hasFunction || len(googleSearchNodes) > 0 { codeExecutionNodes = append(codeExecutionNodes, codeToolNode)
}
if uc := t.Get("url_context"); uc.Exists() {
urlToolNode := []byte(`{}`)
var errSet error
urlToolNode, errSet = sjson.SetRawBytes(urlToolNode, "urlContext", []byte(uc.Raw))
if errSet != nil {
log.Warnf("Failed to set urlContext tool: %v", errSet)
continue
}
urlContextNodes = append(urlContextNodes, urlToolNode)
}
}
if hasFunction || len(googleSearchNodes) > 0 || len(codeExecutionNodes) > 0 || len(urlContextNodes) > 0 {
toolsNode := []byte("[]") toolsNode := []byte("[]")
if hasFunction { if hasFunction {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode) toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", functionToolNode)
@@ -363,6 +385,12 @@ func ConvertOpenAIRequestToGemini(modelName string, inputRawJSON []byte, _ bool)
for _, googleNode := range googleSearchNodes { for _, googleNode := range googleSearchNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode) toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", googleNode)
} }
for _, codeNode := range codeExecutionNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", codeNode)
}
for _, urlNode := range urlContextNodes {
toolsNode, _ = sjson.SetRawBytes(toolsNode, "-1", urlNode)
}
out, _ = sjson.SetRawBytes(out, "tools", toolsNode) out, _ = sjson.SetRawBytes(out, "tools", toolsNode)
} }
} }