From fe7d8f93a1803e7674da233c2b1a308a8bcdffbf Mon Sep 17 00:00:00 2001 From: AveryanAlex Date: Sun, 29 Mar 2026 00:17:49 +0300 Subject: [PATCH] fix: stringify arguments and convert tool output content types --- .../translator/request/openai-responses.ts | 14 ++++++- .../unit/responses-translation-fixes.test.mjs | 38 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/open-sse/translator/request/openai-responses.ts b/open-sse/translator/request/openai-responses.ts index 5c9147a268..18fc18418a 100644 --- a/open-sse/translator/request/openai-responses.ts +++ b/open-sse/translator/request/openai-responses.ts @@ -162,7 +162,9 @@ export function openaiResponsesToOpenAIRequest( type: "function", function: { name: fnName, - arguments: item.arguments, + arguments: typeof item.arguments === "string" + ? item.arguments + : JSON.stringify(item.arguments ?? {}), }, }); currentAssistantMsg.tool_calls = toolCalls; @@ -410,7 +412,15 @@ export function openaiToOpenAIResponsesRequest( input.push({ type: "function_call_output", call_id: toString(msg.tool_call_id), - output: msg.content, + output: typeof msg.content === "string" + ? msg.content + : Array.isArray(msg.content) + ? msg.content.map((c) => { + const part = toRecord(c); + if (part.type === "text") return { type: "input_text", text: toString(part.text) }; + return c; + }) + : String(msg.content ?? ""), }); } } diff --git a/tests/unit/responses-translation-fixes.test.mjs b/tests/unit/responses-translation-fixes.test.mjs index 76df1146c6..5f581af49f 100644 --- a/tests/unit/responses-translation-fixes.test.mjs +++ b/tests/unit/responses-translation-fixes.test.mjs @@ -251,6 +251,44 @@ test("Responses→Chat: mcp tool type throws unsupported error", () => { ); }); +test("Responses→Chat: non-string arguments are JSON-stringified", () => { + const body = { + model: "gpt-4", + input: [ + { type: "function_call", call_id: "c1", name: "fn", arguments: { key: "val" } }, + { type: "function_call_output", call_id: "c1", output: "ok" }, + ], + }; + const result = openaiResponsesToOpenAIRequest(null, body, null, null); + const assistantMsg = result.messages.find((m) => m.role === "assistant"); + assert.equal(typeof assistantMsg.tool_calls[0].function.arguments, "string"); + assert.equal(assistantMsg.tool_calls[0].function.arguments, '{"key":"val"}'); +}); + +test("Chat→Responses: array tool content converts text→input_text types", () => { + const body = { + model: "gpt-4", + messages: [ + { role: "user", content: "hello" }, + { + role: "assistant", + content: null, + tool_calls: [{ id: "c1", type: "function", function: { name: "fn", arguments: "{}" } }], + }, + { + role: "tool", + tool_call_id: "c1", + content: [{ type: "text", text: "result data" }], + }, + ], + }; + const result = openaiToOpenAIResponsesRequest("gpt-4", body, true, null); + const outputItem = result.input.find((i) => i.type === "function_call_output"); + assert.ok(Array.isArray(outputItem.output), "output should be array"); + assert.equal(outputItem.output[0].type, "input_text"); + assert.equal(outputItem.output[0].text, "result data"); +}); + test("Responses→Chat: function tool type passes through", () => { const body = { model: "gpt-4",