From: Stefan Gasser Date: Sun, 11 Jan 2026 09:14:06 +0000 (+0100) Subject: fix: support developer and function roles for GPT-5.x compatibility (#23) X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=ece1ffe8bee99d06cecf8cc970e9858a67765efd;p=sgasser-llm-shield.git fix: support developer and function roles for GPT-5.x compatibility (#23) GPT-5.x models use the 'developer' role instead of 'system' for instructions. The 'function' role is also added for legacy compatibility. Fixes #22 --- diff --git a/src/routes/proxy.test.ts b/src/routes/proxy.test.ts index 660be97..cabdb24 100644 --- a/src/routes/proxy.test.ts +++ b/src/routes/proxy.test.ts @@ -41,6 +41,24 @@ describe("POST /openai/v1/chat/completions", () => { expect(res.status).toBe(400); }); + + test("accepts developer role (GPT-5.x compatibility)", async () => { + const res = await app.request("/openai/v1/chat/completions", { + method: "POST", + body: JSON.stringify({ + messages: [ + { role: "developer", content: "You are a helpful assistant" }, + { role: "user", content: "Hello" }, + ], + model: "gpt-5.2", + }), + headers: { "Content-Type": "application/json" }, + }); + + // Should not be 400 (validation passed) + // Will be 401/502 without API key, but that's fine - we're testing validation + expect(res.status).not.toBe(400); + }); }); describe("GET /openai/v1/models", () => { diff --git a/src/routes/proxy.ts b/src/routes/proxy.ts index c1f6e3e..509fc5d 100644 --- a/src/routes/proxy.ts +++ b/src/routes/proxy.ts @@ -30,7 +30,7 @@ const ChatCompletionSchema = z .array( z .object({ - role: z.enum(["system", "user", "assistant", "tool"]), + role: z.enum(["system", "developer", "user", "assistant", "tool", "function"]), content: z.union([z.string(), z.array(z.any()), z.null()]).optional(), }) .passthrough(), // Allow additional fields like name, tool_calls, etc. diff --git a/src/services/llm-client.ts b/src/services/llm-client.ts index 451ccfd..b986a14 100644 --- a/src/services/llm-client.ts +++ b/src/services/llm-client.ts @@ -6,7 +6,7 @@ import type { MessageContent } from "../utils/content"; * Supports both text-only (content: string) and multimodal (content: array) formats */ export interface ChatMessage { - role: "system" | "user" | "assistant"; + role: "system" | "developer" | "user" | "assistant"; content: MessageContent; }