feat(google): native Google Search grounding behind OPENCLAW_GOOGLE_GROUNDING#4
Conversation
…ROUNDING When the env flag is set, the Google transport adds the google_search built-in tool to every request (with includeServerSideToolInvocations so it can coexist with function declarations), captures the streamed groundingMetadata onto the assistant message as a normalized webGrounding payload (queries + sources ranked by citation count), and surfaces it as a 'grounding' agent event that the OpenAI-compat endpoint forwards as a content-free delta.dojo_grounding chunk for downstream consumers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
✅ Approved
Approved — 0 blockers, 1 P3. Confidence: 4.80/5.00.
Walkthrough
main branch directly, departing from the standard GitFlow pattern (expected: feature → develop → main). This is an informative warning only and does not affect the technical merge status.
Walkthrough
This PR adds native Google Search grounding for Gemini models, gated under the OPENCLAW_GOOGLE_GROUNDING opt-in environment variable. It implements:
- Tool Configuration & Mapping (
src/agents/google-transport-stream.ts): Injects thegoogle_searchtool dynamically. When combined with client-side function declarations, it configurestoolConfig.includeServerSideToolInvocationsto prevent Gemini API 400 errors. It also parses and normalizes streamedgroundingMetadata(queries and source citation counts) onto the assistant message aswebGrounding. - Event Dispatching (
src/agents/pi-embedded-subscribe.handlers.messages.ts): Emits agroundingagent event downstream whenwebGroundingis present on the assistant message. - SSE Compat Layer (
src/gateway/openai-http.ts): Forwards this event as a content-freedelta.dojo_groundingchunk, allowing custom clients to render cited source cards while remaining fully backward-compatible with standard OpenAI clients.
Reviewed Areas
We reviewed the tool parameter builder and metadata streaming helpers in google-transport-stream.ts, message-end lifecycle handling in pi-embedded-subscribe.handlers.messages.ts, and the custom SSE chunk delivery schema in openai-http.ts.
Safety Rationale
The feature is strictly opt-in and fully gated behind process.env.OPENCLAW_GOOGLE_GROUNDING. Without this environment variable enabled, the entire code path is bypassed, guaranteeing zero behavioral regressions or runtime impacts for existing clients and services.
Approved — 0 blockers, 1 P3.
🔵 P3 — Minor
src/agents/pi-embedded-subscribe.handlers.messages.ts:536— 🔵 P3 (minor) — Use a defensive array check onwebGrounding.sourcesbefore evaluating.length. This prevents any potential runtime TypeError crashes if a provider or plugin initializeswebGroundingwith missing or malformed properties in the future.
[pass 1]
Total findings: 1 business context (1 total)
| // `webGrounding`. Surface it as its own event stream so channel consumers | ||
| // (e.g. the OpenAI-compat endpoint) can forward the cited sources. | ||
| const webGrounding = ( | ||
| assistantMessage as { webGrounding?: { queries: string[]; sources: unknown[] } } |
There was a problem hiding this comment.
🔵 P3 (minor) — Use a defensive array check on webGrounding.sources before evaluating .length. This prevents any potential runtime TypeError crashes if a provider or plugin initializes webGrounding with missing or malformed properties in the future.
[pass 1]
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
✅ Approved
Approved — no findings. Confidence: 5.00/5.00.
Walkthrough
main directly instead of following GitFlow conventions (feature → develop → main). Since this is informative only, the technical verdict remains based purely on the code quality.
Walkthrough
This PR implements opt-in native Google Search grounding for Gemini models, gated behind the OPENCLAW_GOOGLE_GROUNDING environment variable. It adds the built-in google_search tool to requests, normalizes raw groundingMetadata into a clean webGrounding representation, surfaces grounding events via the agent stream, and exposes them in the OpenAI-compatible gateway as standard SSE chunks carrying the custom dojo_grounding delta field.
Reviewed Areas
- Transport (
src/agents/google-transport-stream.ts): Reviewed type definitions, parameter construction logic (buildGoogleGenerativeAiParams), and the chunk-merging utility (mergeWebGrounding). - Runner (
src/agents/pi-embedded-subscribe.handlers.messages.ts): Reviewed the message-end handler (handleMessageEnd) and event emissions for thegroundingstream. - Gateway API (
src/gateway/openai-http.ts): Reviewed the OpenAI-compatible HTTP response streaming loop and chunk-writing helpers.
Safety Rationale
The entire Google Search grounding feature is completely opt-in and gated behind the OPENCLAW_GOOGLE_GROUNDING environment variable, ensuring zero behavior changes or regressions for existing configurations when disabled.
Approved — no findings.
|
CI triage before merge — the branch's own diff is clean; every remaining red is pre-existing baseline (main has received direct pushes without PR CI since the last green run):
Merging per the agreed flow; baseline cleanup tracked separately. |
What
Opt-in native web search for Gemini models, gated by the
OPENCLAW_GOOGLE_GROUNDINGenv var (off by default — zero behavior change without it):google-transport-stream.ts): adds thegoogle_searchbuilt-in tool to every request and, when function declarations are present, setstoolConfig.includeServerSideToolInvocations(the API 400s on the mix without it). StreamedgroundingMetadatais normalized onto the assistant output aswebGrounding— queries + sources with per-source citation counts derived fromgroundingSupports.pi-embedded-subscribe.handlers.messages.ts): at message end, a message carryingwebGroundingemits agroundingagent event.openai-http.ts): forwards that event as a content-freedelta.dojo_groundingchunk. Standard OpenAI clients ignore the unknown delta field; the Dojo web-chat proxy consumes it to render a cited-sources card.Why
Cross-pillar conversational web search for the Dojo agent (Claude/ChatGPT-style grounded answers with real citations), verified E2E against the live UI locally. Companion PRs: dojo-agent-openclaw-plugin (proxy/card/booster) and dojo-os (web-results card).
Notes
cut-dojo-tarball.ymlone-shot release workflow (authored 2026-07-02) — needed to cut the next fork tarball with this change.__testOnlyOpenAiHttpdangling underscore,resolveThinkingLevelconsistent-return) — untouched by this diff; CI is the gate.Created by Claude Code on behalf of @StevenMendez
🤖 Generated with Claude Code