fix(translator): normalize developer role to system for OpenAI-format providers

`filterToOpenAIFormat` rewrites the OpenAI Responses-style `developer` role
to `system` before downstream dispatch so OpenAI-compatible providers that
reject the newer role keep working on passthrough routes.

Co-authored-by: Tran Hoang Nguyen <tranhoangnguyen03@gmail.com>
Inspired-by: https://github.com/decolua/9router/pull/1011
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-22 08:49:18 -03:00
committed by Diego Rodrigues de Sa e Souza
parent fc2fdc7e3c
commit 5f0c1382ab
2 changed files with 43 additions and 0 deletions

View File

@@ -35,6 +35,11 @@ export function filterToOpenAIFormat(body) {
if (!body.messages || !Array.isArray(body.messages)) return body;
body.messages = body.messages.map((msg) => {
// Normalize OpenAI Responses-style `developer` role to `system` — many
// OpenAI-compatible providers reject `developer` (ported from
// decolua/9router#1011).
if (msg.role === "developer") msg = { ...msg, role: "system" };
// Keep tool messages as-is (OpenAI format)
if (msg.role === "tool") return msg;

View File

@@ -0,0 +1,38 @@
import { test } from "node:test";
import assert from "node:assert/strict";
import { filterToOpenAIFormat } from "../../open-sse/translator/helpers/openaiHelper.ts";
// Ported from upstream decolua/9router#1011 — many OpenAI-compatible providers
// reject the `developer` role (introduced by OpenAI Responses API). Normalize to
// `system` so passthrough requests keep working downstream.
test("filterToOpenAIFormat normalizes developer role to system", () => {
const body = {
messages: [
{ role: "developer", content: "You are helpful" },
{ role: "user", content: "Hi" },
],
};
const out = filterToOpenAIFormat(body);
assert.equal(out.messages[0].role, "system");
assert.equal(out.messages[0].content, "You are helpful");
assert.equal(out.messages[1].role, "user");
});
test("filterToOpenAIFormat normalizes developer role with array content", () => {
const body = {
messages: [
{
role: "developer",
content: [{ type: "text", text: "Be concise" }],
},
],
};
const out = filterToOpenAIFormat(body);
assert.equal(out.messages[0].role, "system");
assert.deepEqual(out.messages[0].content, [{ type: "text", text: "Be concise" }]);
});