From 0b85d8a9bcbe0bc7a83f7b79e3d1785d9b8c028e Mon Sep 17 00:00:00 2001 From: AveryanAlex Date: Sun, 29 Mar 2026 00:12:18 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20translate=20input=5Ffile=E2=86=94file=20?= =?UTF-8?q?content=20parts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../translator/request/openai-responses.ts | 17 ++++++++ .../unit/responses-translation-fixes.test.mjs | 41 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/open-sse/translator/request/openai-responses.ts b/open-sse/translator/request/openai-responses.ts index a9fcca0331..715126044b 100644 --- a/open-sse/translator/request/openai-responses.ts +++ b/open-sse/translator/request/openai-responses.ts @@ -122,6 +122,14 @@ export function openaiResponsesToOpenAIRequest( } return imgResult; } + if (contentItem.type === "input_file") { + const fileObj: JsonRecord = {}; + if (contentItem.file_data !== undefined) fileObj.file_data = contentItem.file_data; + if (contentItem.file_id !== undefined) fileObj.file_id = contentItem.file_id; + if (contentItem.file_url !== undefined) fileObj.file_url = contentItem.file_url; + if (contentItem.filename !== undefined) fileObj.filename = contentItem.filename; + return { type: "file", file: fileObj }; + } return contentValue; }) : item.content; @@ -308,6 +316,15 @@ export function openaiToOpenAIResponsesRequest( } return imgResult; } + if (contentItem.type === "file") { + const file = toRecord(contentItem.file); + const fileResult: JsonRecord = { type: "input_file" }; + if (file.file_data !== undefined) fileResult.file_data = file.file_data; + if (file.file_id !== undefined) fileResult.file_id = file.file_id; + if (file.file_url !== undefined) fileResult.file_url = file.file_url; + if (file.filename !== undefined) fileResult.filename = file.filename; + return fileResult; + } return contentValue; }) : [{ type: "input_text", text: "" }]; diff --git a/tests/unit/responses-translation-fixes.test.mjs b/tests/unit/responses-translation-fixes.test.mjs index fd0355d5db..7c41feb9df 100644 --- a/tests/unit/responses-translation-fixes.test.mjs +++ b/tests/unit/responses-translation-fixes.test.mjs @@ -117,3 +117,44 @@ test("Chat→Responses: image_url without detail omits detail", () => { assert.ok(imgPart); assert.equal(imgPart.detail, undefined); }); + +test("Responses→Chat: input_file converted to file content part", () => { + const body = { + model: "gpt-4", + input: [ + { + type: "message", + role: "user", + content: [ + { type: "input_file", file_id: "file-abc", filename: "data.csv" }, + ], + }, + ], + }; + const result = openaiResponsesToOpenAIRequest(null, body, null, null); + const userMsg = result.messages.find((m) => m.role === "user"); + const filePart = userMsg.content.find((c) => c.type === "file"); + assert.ok(filePart, "should have file content part"); + assert.equal(filePart.file.file_id, "file-abc"); + assert.equal(filePart.file.filename, "data.csv"); +}); + +test("Chat→Responses: file content part converted to input_file", () => { + const body = { + model: "gpt-4", + messages: [ + { + role: "user", + content: [ + { type: "file", file: { file_id: "file-abc", filename: "data.csv" } }, + ], + }, + ], + }; + const result = openaiToOpenAIResponsesRequest("gpt-4", body, true, null); + const userItem = result.input.find((i) => i.type === "message" && i.role === "user"); + const filePart = userItem.content.find((c) => c.type === "input_file"); + assert.ok(filePart, "should have input_file content part"); + assert.equal(filePart.file_id, "file-abc"); + assert.equal(filePart.filename, "data.csv"); +});