diff --git a/packages/ai/src/protocols/open-responses.ts b/packages/ai/src/protocols/open-responses.ts index 33594399697..80a0299ce35 100644 --- a/packages/ai/src/protocols/open-responses.ts +++ b/packages/ai/src/protocols/open-responses.ts @@ -657,14 +657,7 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques } } - // With store:false, Responses APIs only accept previous reasoning items when the - // complete item has encrypted state. Summary blocks for one item may carry - // that state only on the last block, so filter after they have been joined. - return store === false - ? input.filter( - (item) => !("type" in item) || item.type !== "reasoning" || typeof item.encrypted_content === "string", - ) - : input + return input }) const lowerOptions = (request: LLMRequest) => { diff --git a/packages/ai/test/provider/openai-responses.test.ts b/packages/ai/test/provider/openai-responses.test.ts index e3eba0b3e02..f798bd80e2b 100644 --- a/packages/ai/test/provider/openai-responses.test.ts +++ b/packages/ai/test/provider/openai-responses.test.ts @@ -3157,7 +3157,7 @@ describe("OpenAI Responses route", () => { }), ) - it.effect("skips non-persisted reasoning ids without encrypted state", () => + it.effect("replays stateless reasoning without encrypted state", () => Effect.gen(function* () { const prepared = yield* compileRequest( LLM.request({ @@ -3187,6 +3187,12 @@ describe("OpenAI Responses route", () => { expect(prepared.body).toMatchObject({ input: [ { role: "user", content: [{ type: "input_text", text: "What changed?" }] }, + { + type: "reasoning", + id: "rs_1", + summary: [{ type: "summary_text", text: "Checked the previous diff." }], + encrypted_content: null, + }, { role: "assistant", content: [{ type: "output_text", text: "The parser changed." }] }, { role: "user", content: [{ type: "input_text", text: "Summarize it." }] }, ],