diff --git a/docs/fixtures.html b/docs/fixtures.html index c913956..2f292ab 100644 --- a/docs/fixtures.html +++ b/docs/fixtures.html @@ -146,7 +146,7 @@

Response Types

Text - content, role?, finishReason? + content, role?, finishReason?, reasoning?, webSearches? Plain text response diff --git a/src/__tests__/reasoning-web-search.test.ts b/src/__tests__/reasoning-web-search.test.ts index 93cf588..99b9895 100644 --- a/src/__tests__/reasoning-web-search.test.ts +++ b/src/__tests__/reasoning-web-search.test.ts @@ -235,10 +235,10 @@ describe("POST /v1/responses (web search streaming)", () => { (e) => e.type === "response.output_item.done" && (e.item as { type: string })?.type === "web_search_call", - ) as (SSEEvent & { item: { query: string } })[]; + ) as (SSEEvent & { item: { action: { query: string } } })[]; - expect(searchDone[0].item.query).toBe("latest news"); - expect(searchDone[1].item.query).toBe("weather forecast"); + expect(searchDone[0].item.action.query).toBe("latest news"); + expect(searchDone[1].item.action.query).toBe("weather forecast"); }); it("response.completed includes web search output items", async () => { @@ -251,14 +251,14 @@ describe("POST /v1/responses (web search streaming)", () => { const events = parseResponsesSSEEvents(res.body); const completed = events.find((e) => e.type === "response.completed") as SSEEvent & { - response: { output: { type: string; query?: string }[] }; + response: { output: { type: string; action: { query: string } }[] }; }; expect(completed).toBeDefined(); const searchOutputs = completed.response.output.filter((o) => o.type === "web_search_call"); expect(searchOutputs).toHaveLength(2); - expect(searchOutputs[0].query).toBe("latest news"); - expect(searchOutputs[1].query).toBe("weather forecast"); + expect(searchOutputs[0].action.query).toBe("latest news"); + expect(searchOutputs[1].action.query).toBe("weather forecast"); }); }); @@ -355,8 +355,8 @@ describe("POST /v1/responses (non-streaming with reasoning)", () => { const searchOutputs = body.output.filter((o: { type: string }) => o.type === "web_search_call"); expect(searchOutputs).toHaveLength(2); - expect(searchOutputs[0].query).toBe("latest news"); - expect(searchOutputs[1].query).toBe("weather forecast"); + expect(searchOutputs[0].action.query).toBe("latest news"); + expect(searchOutputs[1].action.query).toBe("weather forecast"); }); it("combined non-streaming response has correct output order", async () => { diff --git a/src/__tests__/stream-collapse.test.ts b/src/__tests__/stream-collapse.test.ts index fc154c4..b5b304a 100644 --- a/src/__tests__/stream-collapse.test.ts +++ b/src/__tests__/stream-collapse.test.ts @@ -1715,12 +1715,12 @@ describe("collapseOpenAISSE with reasoning", () => { "", `data: ${JSON.stringify({ type: "response.output_item.done", - item: { type: "web_search_call", status: "completed", query: "test query" }, + item: { type: "web_search_call", status: "completed", action: { query: "test query" } }, })}`, "", `data: ${JSON.stringify({ type: "response.output_item.done", - item: { type: "web_search_call", status: "completed", query: "another query" }, + item: { type: "web_search_call", status: "completed", action: { query: "another query" } }, })}`, "", `data: ${JSON.stringify({ type: "response.output_text.delta", delta: "Result" })}`, diff --git a/src/responses.ts b/src/responses.ts index d7fa30d..5b7e18f 100644 --- a/src/responses.ts +++ b/src/responses.ts @@ -505,7 +505,7 @@ function buildWebSearchStreamEvents( type: "web_search_call", id: searchId, status: "in_progress", - query: queries[i], + action: { query: queries[i] }, }, }); @@ -516,7 +516,7 @@ function buildWebSearchStreamEvents( type: "web_search_call", id: searchId, status: "completed", - query: queries[i], + action: { query: queries[i] }, }, }); } @@ -550,7 +550,7 @@ function buildTextResponse( type: "web_search_call", id: generateId("ws"), status: "completed", - query, + action: { query }, }); } } diff --git a/src/stream-collapse.ts b/src/stream-collapse.ts index 01c5d87..1ecbe59 100644 --- a/src/stream-collapse.ts +++ b/src/stream-collapse.ts @@ -72,9 +72,12 @@ export function collapseOpenAISSE(body: string): CollapseResult { // Responses API web search events if (parsed.type === "response.output_item.done") { const item = parsed.item as Record | undefined; - if (item?.type === "web_search_call" && typeof item.query === "string") { - webSearchQueries.push(item.query); - continue; + if (item?.type === "web_search_call") { + const action = item.action as Record | undefined; + if (action && typeof action.query === "string") { + webSearchQueries.push(action.query); + continue; + } } }