Merge pull request #1418 from YanzheL/fix/1161-gemini-google-search-grounding
fix(gemini): preserve google search grounding tools
This commit is contained in:
@@ -612,7 +612,8 @@ func (s *GeminiMessagesCompatService) Forward(ctx context.Context, c *gin.Contex
|
||||
fullURL += "?alt=sse"
|
||||
}
|
||||
|
||||
upstreamReq, err := http.NewRequestWithContext(ctx, http.MethodPost, fullURL, bytes.NewReader(geminiReq))
|
||||
restGeminiReq := normalizeGeminiRequestForAIStudio(geminiReq)
|
||||
upstreamReq, err := http.NewRequestWithContext(ctx, http.MethodPost, fullURL, bytes.NewReader(restGeminiReq))
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
@@ -685,7 +686,8 @@ func (s *GeminiMessagesCompatService) Forward(ctx context.Context, c *gin.Contex
|
||||
fullURL += "?alt=sse"
|
||||
}
|
||||
|
||||
upstreamReq, err := http.NewRequestWithContext(ctx, http.MethodPost, fullURL, bytes.NewReader(geminiReq))
|
||||
restGeminiReq := normalizeGeminiRequestForAIStudio(geminiReq)
|
||||
upstreamReq, err := http.NewRequestWithContext(ctx, http.MethodPost, fullURL, bytes.NewReader(restGeminiReq))
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
@@ -3184,12 +3186,17 @@ func convertClaudeToolsToGeminiTools(tools any) []any {
|
||||
return nil
|
||||
}
|
||||
|
||||
hasWebSearch := false
|
||||
funcDecls := make([]any, 0, len(arr))
|
||||
for _, t := range arr {
|
||||
tm, ok := t.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if isClaudeWebSearchToolMap(tm) {
|
||||
hasWebSearch = true
|
||||
continue
|
||||
}
|
||||
|
||||
var name, desc string
|
||||
var params any
|
||||
@@ -3233,13 +3240,75 @@ 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 []any{
|
||||
map[string]any{
|
||||
"functionDeclarations": funcDecls,
|
||||
},
|
||||
return out
|
||||
}
|
||||
|
||||
func normalizeGeminiRequestForAIStudio(body []byte) []byte {
|
||||
var payload map[string]any
|
||||
if err := json.Unmarshal(body, &payload); err != nil {
|
||||
return body
|
||||
}
|
||||
|
||||
tools, ok := payload["tools"].([]any)
|
||||
if !ok || len(tools) == 0 {
|
||||
return body
|
||||
}
|
||||
|
||||
modified := false
|
||||
for _, rawTool := range tools {
|
||||
tool, ok := rawTool.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
googleSearch, ok := tool["googleSearch"]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if _, exists := tool["google_search"]; exists {
|
||||
continue
|
||||
}
|
||||
tool["google_search"] = googleSearch
|
||||
delete(tool, "googleSearch")
|
||||
modified = true
|
||||
}
|
||||
|
||||
if !modified {
|
||||
return body
|
||||
}
|
||||
|
||||
normalized, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return body
|
||||
}
|
||||
return normalized
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user