fix(gemini): preserve google search in Claude compat tools
This commit is contained in:
@@ -3169,12 +3169,17 @@ func convertClaudeToolsToGeminiTools(tools any) []any {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasWebSearch := false
|
||||||
funcDecls := make([]any, 0, len(arr))
|
funcDecls := make([]any, 0, len(arr))
|
||||||
for _, t := range arr {
|
for _, t := range arr {
|
||||||
tm, ok := t.(map[string]any)
|
tm, ok := t.(map[string]any)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if isClaudeWebSearchToolMap(tm) {
|
||||||
|
hasWebSearch = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var name, desc string
|
var name, desc string
|
||||||
var params any
|
var params any
|
||||||
@@ -3218,13 +3223,35 @@ func convertClaudeToolsToGeminiTools(tools any) []any {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(funcDecls) == 0 {
|
out := make([]any, 0, 2)
|
||||||
|
if len(funcDecls) > 0 {
|
||||||
|
out = append(out, map[string]any{
|
||||||
|
"functionDeclarations": funcDecls,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if hasWebSearch {
|
||||||
|
out = append(out, map[string]any{
|
||||||
|
"googleSearch": map[string]any{},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(out) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return []any{
|
return out
|
||||||
map[string]any{
|
}
|
||||||
"functionDeclarations": funcDecls,
|
|
||||||
},
|
func isClaudeWebSearchToolMap(tool map[string]any) bool {
|
||||||
|
toolType, _ := tool["type"].(string)
|
||||||
|
if strings.HasPrefix(toolType, "web_search") || toolType == "google_search" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
name, _ := tool["name"].(string)
|
||||||
|
switch strings.TrimSpace(name) {
|
||||||
|
case "web_search", "google_search", "web_search_20250305":
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,6 +164,35 @@ func TestConvertClaudeToolsToGeminiTools_CustomType(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConvertClaudeToolsToGeminiTools_PreservesWebSearchAlongsideFunctions(t *testing.T) {
|
||||||
|
tools := []any{
|
||||||
|
map[string]any{
|
||||||
|
"name": "get_weather",
|
||||||
|
"description": "Get weather info",
|
||||||
|
"input_schema": map[string]any{"type": "object"},
|
||||||
|
},
|
||||||
|
map[string]any{
|
||||||
|
"type": "web_search_20250305",
|
||||||
|
"name": "web_search",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
result := convertClaudeToolsToGeminiTools(tools)
|
||||||
|
require.Len(t, result, 2)
|
||||||
|
|
||||||
|
functionDecl, ok := result[0].(map[string]any)
|
||||||
|
require.True(t, ok)
|
||||||
|
funcDecls, ok := functionDecl["functionDeclarations"].([]any)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Len(t, funcDecls, 1)
|
||||||
|
|
||||||
|
searchDecl, ok := result[1].(map[string]any)
|
||||||
|
require.True(t, ok)
|
||||||
|
googleSearch, ok := searchDecl["googleSearch"].(map[string]any)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Empty(t, googleSearch)
|
||||||
|
}
|
||||||
|
|
||||||
func TestGeminiHandleNativeNonStreamingResponse_DebugDisabledDoesNotEmitHeaderLogs(t *testing.T) {
|
func TestGeminiHandleNativeNonStreamingResponse_DebugDisabledDoesNotEmitHeaderLogs(t *testing.T) {
|
||||||
gin.SetMode(gin.TestMode)
|
gin.SetMode(gin.TestMode)
|
||||||
logSink, restore := captureStructuredLog(t)
|
logSink, restore := captureStructuredLog(t)
|
||||||
|
|||||||
Reference in New Issue
Block a user