← Back to PRs

#13075: [Feature]: Add Gemini (Google Search grounding) as web_search provider

by akoscz open 2026-02-10 03:10 View on GitHub →
docs agents size: M
## Summary Adds `"gemini"` as a web_search provider alongside Brave, Perplexity, and Grok, using Gemini's built-in [Google Search grounding](https://ai.google.dev/gemini-api/docs/grounding). Also adds **auto-detection** of search providers when no explicit `provider` is configured. Closes #13074 ## What changed ### `src/agents/tools/web-search.ts` - New `runGeminiSearch()` — calls Gemini `generateContent` with `tools: [{ google_search: {} }]` - `resolveRedirectUrl()` — resolves Google grounding redirect URLs to direct URLs via parallel HEAD requests (5s timeout, graceful fallback) - Gemini config resolution helpers (`resolveGeminiConfig`, `resolveGeminiApiKey`, `resolveGeminiModel`) - Updated `runWebSearch()`, `createWebSearchTool()`, `missingSearchKeyPayload()`, `resolveSearchProvider()` to handle the gemini provider path - **Auto-detection:** When no explicit `provider` is set, checks for available API keys in priority order: Brave → Gemini → Perplexity → Grok. Falls back to Brave if none found. - **Security:** API key stripped from error messages (`key=***`) to prevent leakage in logs — Gemini REST API requires key as query parameter (no Bearer token alternative without ADC) ### Config types & validation - `types.tools.ts` — added `"gemini"` to provider union, added `gemini` config block - `zod-schema.agent-runtime.ts` — added `"gemini"` to zod validation, added gemini schema - `schema.ts` — updated provider description string ### Tests - 2 new config validation tests (gemini with config, gemini with defaults) - 8 new auto-detection tests (per-provider detection, priority order, explicit override, fallback) - All existing + new tests passing (11 total) ### Docs - `docs/tools/web.md` — added Auto-detection section documenting priority order and fallback behavior ## Config ```json5 { tools: { web: { search: { provider: "gemini", // optional — auto-detected from available keys gemini: { apiKey: "...", // optional if GEMINI_API_KEY env var is set model: "gemini-2.5-flash" // optional, this is the default } } } } } ``` ### Auto-detection When no `provider` is explicitly set, OpenClaw checks for available API keys in this order: 1. **Brave** — `BRAVE_API_KEY` env var or `search.apiKey` config 2. **Gemini** — `GEMINI_API_KEY` env var or `search.gemini.apiKey` config 3. **Perplexity** — `PERPLEXITY_API_KEY` / `OPENROUTER_API_KEY` env var or `search.perplexity.apiKey` config 4. **Grok** — `XAI_API_KEY` env var or `search.grok.apiKey` config If no keys are found, falls back to Brave (existing behavior). ## Testing - [x] `pnpm check` passes (lint + format) - [x] Unit tests pass (11/11) - [x] Live tested against Gemini API — grounding returns content + citations with resolved URLs - [x] Self-review completed — found and fixed API key leakage in error messages before finalizing - [x] AI-assisted (Claude Opus 4.6 via OpenClaw) — fully reviewed and understood ## Design decisions - **URL resolution:** Gemini grounding returns citations through `vertexaisearch.cloud.google.com/grounding-api-redirect/...` redirects. We resolve these to direct URLs via parallel HEAD requests (5s timeout, graceful fallback to redirect URL on failure). This adds latency but gives the agent usable URLs. - **API key in query string:** Gemini REST API requires this (no header alternative without ADC). We strip `key=...` from error messages to prevent log leakage. - **Default model:** `gemini-2.5-flash` — fast, cheap, supports grounding. - **Auto-detection priority:** Brave first (most common existing setup), then Gemini, Perplexity, Grok. Explicit `provider` config always overrides auto-detection. ## Related - #5775 (Grok provider — similar pattern) - #11399 (Extensible providers) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> Adds Gemini as a web search provider with Google Search grounding capability, alongside existing Brave, Perplexity, and Grok providers. Implements auto-detection of search providers based on available API keys when no explicit `provider` is configured. **Key changes:** - New `runGeminiSearch()` function calling Gemini's `generateContent` API with Google Search grounding tool - URL resolution helper (`resolveRedirectUrl()`) to convert Google grounding redirect URLs to direct URLs via parallel HEAD requests (5s timeout, graceful fallback) - Auto-detection logic checking API keys in priority order: Brave → Gemini → Perplexity → Grok, with fallback to Brave - Configuration schema updates across types, zod validation, and documentation - Security: API key redaction in error messages to prevent log leakage (Gemini REST API requires key as query param) - Comprehensive test coverage (11 tests total: 3 config validation, 8 auto-detection scenarios) **Implementation follows existing patterns:** - Consistent with Grok/Perplexity provider structure - Proper `externalContent` metadata included - API keys marked as sensitive in zod schema - Config help and labels added for new Gemini fields - Documentation updated with setup instructions and auto-detection behavior All previously reported issues from review threads have been addressed (error message redaction, JSON parse guards, config schema entries). <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - Implementation is thorough and follows established patterns in the codebase. All previously identified issues (API key leakage, JSON parse guards, missing config entries) have been addressed. The code includes proper error handling, security measures (API key redaction), comprehensive test coverage (11/11 passing), and maintains consistency with existing provider implementations. Auto-detection logic is well-tested with 8 test cases covering priority order and fallback behavior. - No files require special attention <sub>Last reviewed commit: cfca253</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs