mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 23:58:25 +00:00
fix(web-search): handle xAI Responses API format in Grok provider
The xAI /v1/responses API returns content in a structured format with typed output blocks (type: 'message') containing typed content blocks (type: 'output_text') and url_citation annotations. The previous code only checked output[0].content[0].text without filtering by type, which could miss content in responses with multiple output entries. Changes: - Update GrokSearchResponse type to include annotations on content blocks - Filter output blocks by type='message' and content by type='output_text' - Extract url_citation annotations as fallback citations when top-level citations array is empty - Deduplicate annotation-derived citation URLs - Update tests for the new structured return type Closes #13520
This commit is contained in:
@@ -145,21 +145,66 @@ describe("web_search grok config resolution", () => {
|
||||
});
|
||||
|
||||
describe("web_search grok response parsing", () => {
|
||||
it("extracts content from Responses API output blocks", () => {
|
||||
expect(
|
||||
extractGrokContent({
|
||||
output: [
|
||||
{
|
||||
content: [{ text: "hello from output" }],
|
||||
},
|
||||
],
|
||||
}),
|
||||
).toBe("hello from output");
|
||||
it("extracts content from Responses API message blocks", () => {
|
||||
const result = extractGrokContent({
|
||||
output: [
|
||||
{
|
||||
type: "message",
|
||||
content: [{ type: "output_text", text: "hello from output" }],
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(result.text).toBe("hello from output");
|
||||
expect(result.annotationCitations).toEqual([]);
|
||||
});
|
||||
|
||||
it("extracts url_citation annotations from content blocks", () => {
|
||||
const result = extractGrokContent({
|
||||
output: [
|
||||
{
|
||||
type: "message",
|
||||
content: [
|
||||
{
|
||||
type: "output_text",
|
||||
text: "hello with citations",
|
||||
annotations: [
|
||||
{
|
||||
type: "url_citation",
|
||||
url: "https://example.com/a",
|
||||
start_index: 0,
|
||||
end_index: 5,
|
||||
},
|
||||
{
|
||||
type: "url_citation",
|
||||
url: "https://example.com/b",
|
||||
start_index: 6,
|
||||
end_index: 10,
|
||||
},
|
||||
{
|
||||
type: "url_citation",
|
||||
url: "https://example.com/a",
|
||||
start_index: 11,
|
||||
end_index: 15,
|
||||
}, // duplicate
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(result.text).toBe("hello with citations");
|
||||
expect(result.annotationCitations).toEqual(["https://example.com/a", "https://example.com/b"]);
|
||||
});
|
||||
|
||||
it("falls back to deprecated output_text", () => {
|
||||
expect(extractGrokContent({ output_text: "hello from output_text" })).toBe(
|
||||
"hello from output_text",
|
||||
);
|
||||
const result = extractGrokContent({ output_text: "hello from output_text" });
|
||||
expect(result.text).toBe("hello from output_text");
|
||||
expect(result.annotationCitations).toEqual([]);
|
||||
});
|
||||
|
||||
it("returns undefined text when no content found", () => {
|
||||
const result = extractGrokContent({});
|
||||
expect(result.text).toBeUndefined();
|
||||
expect(result.annotationCitations).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user