#13075: [Feature]: Add Gemini (Google Search grounding) as web_search provider
docs
agents
size: M
Cluster:
Gemini Provider Enhancements
## 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
#13370: Tools: rewrite Grok parser, add Tavily provider, multi-provider con...
by a-anand-91119 · 2026-02-10
81.1%
#13814: feat(web-search): add ZAI Search (zsearch) provider
by strelov1 · 2026-02-11
79.9%
#13386: feat(web-search): add Nimble Web Search API provider
by ilchemla · 2026-02-10
79.0%
#8715: fix(web-search): safer provider resolution & Perplexity auto-detection
by abhijeet117 · 2026-02-04
78.7%
#16786: fix: support google-antigravity OAuth for Gemini embeddings
by outsourc-e · 2026-02-15
78.6%
#23424: feat: add Gemini 3.1 Pro Preview support (google-gemini-cli)
by hongchanroh · 2026-02-22
78.3%
#22214: fix(tools): sanitize google-antigravity schemas for Gemini-compatib...
by Kansodata · 2026-02-20
78.2%
#19307: docs: add Google (Gemini) provider documentation
by manueltarouca · 2026-02-17
78.0%
#21263: fix: add google-vertex support for Gemini 3.1 models
by pdd-cli · 2026-02-19
77.6%
#17841: fix(google): include 'google' provider in tool schema sanitization
by zerone0x · 2026-02-16
77.4%