From 485bdc9c4e7d7e39e6c723bb48fb4d09bf0c19e2 Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Sun, 30 Aug 2026 16:03:41 -0500 Subject: [PATCH] fix(ai): omit empty Responses user messages (#46297) --- packages/ai/src/protocols/open-responses.ts | 6 ++---- .../openai-compatible-responses.test.ts | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/ai/src/protocols/open-responses.ts b/packages/ai/src/protocols/open-responses.ts index 79fec2d2b8b..407af480a12 100644 --- a/packages/ai/src/protocols/open-responses.ts +++ b/packages/ai/src/protocols/open-responses.ts @@ -577,10 +577,8 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques } if (message.role === "user") { - input.push({ - role: "user", - content: yield* Effect.forEach(message.content, (part) => lowerUserContent(part, request, extension)), - }) + const content = yield* Effect.forEach(message.content, (part) => lowerUserContent(part, request, extension)) + if (content.length > 0) input.push({ role: "user", content }) continue } diff --git a/packages/ai/test/provider/openai-compatible-responses.test.ts b/packages/ai/test/provider/openai-compatible-responses.test.ts index ced45842d26..a24b0c7c5a9 100644 --- a/packages/ai/test/provider/openai-compatible-responses.test.ts +++ b/packages/ai/test/provider/openai-compatible-responses.test.ts @@ -96,6 +96,27 @@ describe("Open Responses-compatible route", () => { }), ) + it.effect("omits user messages with no content", () => + Effect.gen(function* () { + const model = configure({ + apiKey: "test-key", + baseURL: "https://responses.example.test/v1", + provider: "example", + }).model("example-model") + const prepared = yield* compileRequest( + LLM.request({ + model, + messages: [Message.user("Before."), Message.user([]), Message.user("After.")], + }), + ) + + expect(prepared.body.input).toEqual([ + { role: "user", content: [{ type: "input_text", text: "Before." }] }, + { role: "user", content: [{ type: "input_text", text: "After." }] }, + ]) + }), + ) + it.effect("uses data URLs for embedded PDF messages and tool results", () => Effect.gen(function* () { const model = configure({