fix(tools): correct Grok response parsing for xAI Responses API (#13049)

* fix(tools): correct Grok response parsing for xAI Responses API

The xAI Responses API returns content in output[0].content[0].text,
not in output_text field. Updated GrokSearchResponse type and
runGrokSearch to extract content from the correct path.

Fixes the 'No response' issue when using Grok web search.

* fix(tools): harden Grok web_search parsing (#13049) (thanks @ereid7)

---------

Co-authored-by: erai <erai@erais-Mac-mini.local>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
Evan Reid
2026-02-09 22:51:24 -05:00
committed by GitHub
parent 8fad4c2844
commit 0c7bc303c9
3 changed files with 43 additions and 3 deletions

View File

@@ -103,7 +103,15 @@ type GrokConfig = {
};
type GrokSearchResponse = {
output_text?: string;
output?: Array<{
type?: string;
role?: string;
content?: Array<{
type?: string;
text?: string;
}>;
}>;
output_text?: string; // deprecated field - kept for backwards compatibility
citations?: string[];
inline_citations?: Array<{
start_index: number;
@@ -123,6 +131,15 @@ type PerplexitySearchResponse = {
type PerplexityBaseUrlHint = "direct" | "openrouter";
function extractGrokContent(data: GrokSearchResponse): string | undefined {
// xAI Responses API format: output[0].content[0].text
const fromResponses = data.output?.[0]?.content?.[0]?.text;
if (typeof fromResponses === "string" && fromResponses) {
return fromResponses;
}
return typeof data.output_text === "string" ? data.output_text : undefined;
}
function resolveSearchConfig(cfg?: OpenClawConfig): WebSearchConfig {
const search = cfg?.tools?.web?.search;
if (!search || typeof search !== "object") {
@@ -476,7 +493,7 @@ async function runGrokSearch(params: {
}
const data = (await res.json()) as GrokSearchResponse;
const content = data.output_text ?? "No response";
const content = extractGrokContent(data) ?? "No response";
const citations = data.citations ?? [];
const inlineCitations = data.inline_citations;
@@ -548,7 +565,7 @@ async function runWebSearch(params: {
provider: params.provider,
model: params.grokModel ?? DEFAULT_GROK_MODEL,
tookMs: Date.now() - start,
content,
content: wrapWebContent(content),
citations,
inlineCitations,
};
@@ -713,4 +730,5 @@ export const __testing = {
resolveGrokApiKey,
resolveGrokModel,
resolveGrokInlineCitations,
extractGrokContent,
} as const;