feat(tools): add Grok (xAI) as web_search provider

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.
This commit is contained in:
Trevin Chow
2026-01-27 21:06:53 -08:00
committed by clawdinator[bot]
parent 07375a65d8
commit 139d70e2a9
4 changed files with 194 additions and 8 deletions
+11 -2
View File
@@ -336,8 +336,8 @@ export type ToolsConfig = {
search?: {
/** Enable web search tool (default: true when API key is present). */
enabled?: boolean;
/** Search provider ("brave" or "perplexity"). */
provider?: "brave" | "perplexity";
/** Search provider ("brave", "perplexity", or "grok"). */
provider?: "brave" | "perplexity" | "grok";
/** Brave Search API key (optional; defaults to BRAVE_API_KEY env var). */
apiKey?: string;
/** Default search results count (1-10). */
@@ -355,6 +355,15 @@ export type ToolsConfig = {
/** Model to use (defaults to "perplexity/sonar-pro"). */
model?: string;
};
/** Grok-specific configuration (used when provider="grok"). */
grok?: {
/** API key for xAI (defaults to XAI_API_KEY env var). */
apiKey?: string;
/** Model to use (defaults to "grok-4-1-fast"). */
model?: string;
/** Include inline citations in response text as markdown links (default: false). */
inlineCitations?: boolean;
};
};
fetch?: {
/** Enable web fetch tool (default: true). */
+9 -1
View File
@@ -171,7 +171,7 @@ export const ToolPolicySchema = ToolPolicyBaseSchema.superRefine((value, ctx) =>
export const ToolsWebSearchSchema = z
.object({
enabled: z.boolean().optional(),
provider: z.union([z.literal("brave"), z.literal("perplexity")]).optional(),
provider: z.union([z.literal("brave"), z.literal("perplexity"), z.literal("grok")]).optional(),
apiKey: z.string().optional(),
maxResults: z.number().int().positive().optional(),
timeoutSeconds: z.number().int().positive().optional(),
@@ -184,6 +184,14 @@ export const ToolsWebSearchSchema = z
})
.strict()
.optional(),
grok: z
.object({
apiKey: z.string().optional(),
model: z.string().optional(),
inlineCitations: z.boolean().optional(),
})
.strict()
.optional(),
})
.strict()
.optional();