feat(tools): add Grok (xAI) as web_search provider#5778
feat(tools): add Grok (xAI) as web_search provider#5778tmchow wants to merge 1 commit intoopenclaw:mainfrom
Conversation
Add xAI's Grok as a new web_search provider alongside Brave and Perplexity.
Uses the xAI /v1/responses API with tools: [{type: "web_search"}].
Configuration:
- tools.web.search.provider: "grok"
- tools.web.search.grok.apiKey or XAI_API_KEY env var
- tools.web.search.grok.model (default: grok-4-1-fast)
- tools.web.search.grok.inlineCitations (optional, embeds markdown links)
Returns AI-synthesized answers with citations similar to Perplexity.
| if (provider === "grok") { | ||
| return { | ||
| error: "missing_xai_api_key", | ||
| message: | ||
| "web_search (grok) needs an xAI API key. Set XAI_API_KEY in the Gateway environment, or configure tools.web.search.grok.apiKey.", | ||
| docs: "https://docs.molt.bot/tools/web", | ||
| }; |
There was a problem hiding this comment.
[P1] missingSearchKeyPayload("grok") points to https://docs.molt.bot/tools/web, while the other providers use https://docs.openclaw.ai/tools/web. This looks like a leftover/typo and will send users to the wrong docs when they hit the missing-key error.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/tools/web-search.ts
Line: 159:165
Comment:
[P1] `missingSearchKeyPayload("grok")` points to `https://docs.molt.bot/tools/web`, while the other providers use `https://docs.openclaw.ai/tools/web`. This looks like a leftover/typo and will send users to the wrong docs when they hit the missing-key error.
How can I resolve this? If you propose a fix, please make it concise.| async function runGrokSearch(params: { | ||
| query: string; | ||
| apiKey: string; | ||
| model: string; | ||
| timeoutSeconds: number; | ||
| inlineCitations: boolean; | ||
| }): Promise<{ content: string; citations: string[] }> { | ||
| const body: Record<string, unknown> = { | ||
| model: params.model, | ||
| input: [ | ||
| { | ||
| role: "user", | ||
| content: params.query, | ||
| }, | ||
| ], | ||
| tools: [{ type: "web_search" }], | ||
| }; | ||
|
|
||
| if (params.inlineCitations) { | ||
| body.include = ["inline_citations"]; | ||
| } | ||
|
|
||
| const res = await fetch(XAI_API_ENDPOINT, { | ||
| method: "POST", | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| Authorization: `Bearer ${params.apiKey}`, | ||
| }, | ||
| body: JSON.stringify(body), | ||
| signal: withTimeout(undefined, params.timeoutSeconds * 1000), | ||
| }); | ||
|
|
||
| if (!res.ok) { | ||
| const detail = await readResponseText(res); | ||
| throw new Error(`xAI API error (${res.status}): ${detail || res.statusText}`); | ||
| } | ||
|
|
||
| const data = (await res.json()) as GrokSearchResponse; | ||
| const content = data.output_text ?? "No response"; | ||
| const citations = data.citations ?? []; | ||
|
|
||
| return { content, citations }; | ||
| } |
There was a problem hiding this comment.
[P2] runGrokSearch defines inline_citations in GrokSearchResponse, but the function always returns data.citations and ignores data.inline_citations. If the /v1/responses API only returns inline_citations when include is set (and not citations), callers will see empty citations even though citations were returned. Consider either mapping inline_citations to a citations list, or dropping the unused field/type if it’s not actually returned/needed.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/tools/web-search.ts
Line: 407:449
Comment:
[P2] `runGrokSearch` defines `inline_citations` in `GrokSearchResponse`, but the function always returns `data.citations` and ignores `data.inline_citations`. If the `/v1/responses` API only returns `inline_citations` when `include` is set (and not `citations`), callers will see empty citations even though citations were returned. Consider either mapping `inline_citations` to a citations list, or dropping the unused field/type if it’s not actually returned/needed.
How can I resolve this? If you propose a fix, please make it concise.|
CLAWDINATOR FIELD REPORT // PR Closure I am CLAWDINATOR — cybernetic crustacean, maintainer triage bot for OpenClaw. I was sent from the future to keep this repo shipping clean code. Your PR has been scanned. The effort is br00tal. Reality check: OpenClaw receives ~25 PRs every hour. The maintainers are running out of oxygen up here. This PR is unlikely to merge in the near term. Consider that a deprecation. But hey — if this is real and not a Rekall implant, come with me if you want to ship. Report to #pr-thunderdome-dangerzone on Discord — READ THE TOPIC or risk immediate termination. Bring the facts — what it fixes, why it matters. See you at the party, Richter. Stay br00tal. 🤖 This is an automated message from CLAWDINATOR, the OpenClaw maintainer bot. |

Summary
/v1/responsesAPI withtools: [{type: "web_search"}]include: ["inline_citations"].Fixes #5775
Configuration
Note: This is a reopening of PR #3147 which was accidentally closed.
Greptile Overview
Greptile Summary
This PR adds a new
grokoption to theweb_searchtool alongside the existingbraveandperplexityproviders. It threads Grok configuration through the runtime config types and Zod schema (tools.web.search.provider, plustools.web.search.grok.{apiKey,model,inlineCitations}), and implements a new request path insrc/agents/tools/web-search.tsthat calls xAI’s/v1/responsesAPI withtools: [{ type: "web_search" }]and optionalinclude: ["inline_citations"]. Tests were extended to cover Grok config resolution helpers.Overall, the change follows the existing provider pattern (resolve config → resolve API key/model → dispatch in
runWebSearch→ cache response) and integrates cleanly with the existing web tool setup.Confidence Score: 4/5
inline_citationsinclude behavior; neither is structural but both could affect user experience and output quality.