Skip to content

Commit 667206e

Browse files
committed
fix: use flat response.create format in Responses WS handler
The real OpenAI Responses WS API expects a flat message format: { type: "response.create", model: "...", input: [...] } The handler previously required fields nested under a "response" object, which doesn't match the real API. Updated the handler and all existing WS tests to use the flat format.
1 parent 756127b commit 667206e

3 files changed

Lines changed: 23 additions & 31 deletions

File tree

src/__tests__/ws-api-conformance.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,8 @@ function parseFrames(raw: string[]): WSFrame[] {
6565
function responsesCreateMsg(userContent: string): string {
6666
return JSON.stringify({
6767
type: "response.create",
68-
response: {
69-
model: "gpt-4",
70-
input: [{ role: "user", content: userContent }],
71-
},
68+
model: "gpt-4",
69+
input: [{ role: "user", content: userContent }],
7270
});
7371
}
7472

src/__tests__/ws-responses.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,8 @@ afterEach(async () => {
4343
function responseCreateMsg(userContent: string, model = "gpt-4"): string {
4444
return JSON.stringify({
4545
type: "response.create",
46-
response: {
47-
model,
48-
input: [{ role: "user", content: userContent }],
49-
},
46+
model,
47+
input: [{ role: "user", content: userContent }],
5048
});
5149
}
5250

src/ws-responses.ts

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* WebSocket handler for OpenAI Responses API.
33
*
4-
* Accepts `{ type: "response.create", response: { ... } }` messages over
4+
* Accepts `{ type: "response.create", model: "...", input: [...] }` messages over
55
* WebSocket and sends back the same Responses API SSE events as the HTTP
66
* handler, but as individual WebSocket text frames.
77
*/
@@ -22,25 +22,22 @@ import type { WebSocketConnection } from "./ws-framing.js";
2222

2323
interface ResponseCreateMessage {
2424
type: "response.create";
25-
response: {
26-
model?: string;
27-
input?: unknown[];
28-
instructions?: string;
29-
tools?: unknown[];
30-
tool_choice?: string | object;
31-
stream?: boolean;
32-
temperature?: number;
33-
max_output_tokens?: number;
34-
[key: string]: unknown;
35-
};
25+
model?: string;
26+
input?: unknown[];
27+
instructions?: string;
28+
tools?: unknown[];
29+
tool_choice?: string | object;
30+
stream?: boolean;
31+
temperature?: number;
32+
max_output_tokens?: number;
33+
[key: string]: unknown;
3634
}
3735

3836
function isResponseCreateMessage(msg: unknown): msg is ResponseCreateMessage {
3937
return (
4038
typeof msg === "object" &&
4139
msg !== null &&
42-
(msg as ResponseCreateMessage).type === "response.create" &&
43-
typeof (msg as ResponseCreateMessage).response === "object"
40+
(msg as ResponseCreateMessage).type === "response.create"
4441
);
4542
}
4643

@@ -108,10 +105,9 @@ async function processMessage(
108105
return;
109106
}
110107

111-
// The response body inside response.create maps to a ResponsesRequest
112108
const responsesReq = {
113-
model: parsed.response.model ?? defaults.model,
114-
input: (parsed.response.input ?? []) as {
109+
model: parsed.model ?? defaults.model,
110+
input: (parsed.input ?? []) as {
115111
role?: string;
116112
type?: string;
117113
content?: string | { type: string; text?: string }[];
@@ -121,8 +117,8 @@ async function processMessage(
121117
output?: string;
122118
id?: string;
123119
}[],
124-
instructions: parsed.response.instructions,
125-
tools: parsed.response.tools as
120+
instructions: parsed.instructions,
121+
tools: parsed.tools as
126122
| {
127123
type: "function";
128124
name: string;
@@ -131,10 +127,10 @@ async function processMessage(
131127
strict?: boolean;
132128
}[]
133129
| undefined,
134-
tool_choice: parsed.response.tool_choice,
135-
stream: parsed.response.stream,
136-
temperature: parsed.response.temperature,
137-
max_output_tokens: parsed.response.max_output_tokens,
130+
tool_choice: parsed.tool_choice,
131+
stream: parsed.stream,
132+
temperature: parsed.temperature,
133+
max_output_tokens: parsed.max_output_tokens,
138134
};
139135

140136
const completionReq = responsesToCompletionRequest(responsesReq);

0 commit comments

Comments
 (0)