fix(gateway): send terminal chunk before [DONE] in OpenAI streaming
OpenAI-compatible clients expect a terminal chunk with an empty delta and finish_reason:"stop" before the [DONE] sentinel. Without it, some clients crash while finalizing the stream. Centralizes stream shutdown in an endStream() helper that ensures the terminal chunk is sent exactly once before [DONE]. Closes #4298
This commit is contained in:
parent
6af205a13a
commit
b6ea87d6ac
@ -252,6 +252,26 @@ export async function handleOpenAiHttpRequest(
|
||||
let wroteRole = false;
|
||||
let sawAssistantDelta = false;
|
||||
let closed = false;
|
||||
let sentTerminalChunk = false;
|
||||
|
||||
/** Send a terminal chunk with finish_reason before [DONE]. */
|
||||
const endStream = () => {
|
||||
if (closed) return;
|
||||
closed = true;
|
||||
if (!sentTerminalChunk) {
|
||||
sentTerminalChunk = true;
|
||||
writeSse(res, {
|
||||
id: runId,
|
||||
object: "chat.completion.chunk",
|
||||
created: Math.floor(Date.now() / 1000),
|
||||
model,
|
||||
choices: [{ index: 0, delta: {}, finish_reason: "stop" }],
|
||||
});
|
||||
}
|
||||
unsubscribe();
|
||||
writeDone(res);
|
||||
res.end();
|
||||
};
|
||||
|
||||
const unsubscribe = onAgentEvent((evt) => {
|
||||
if (evt.runId !== runId) return;
|
||||
@ -294,17 +314,16 @@ export async function handleOpenAiHttpRequest(
|
||||
if (evt.stream === "lifecycle") {
|
||||
const phase = evt.data?.phase;
|
||||
if (phase === "end" || phase === "error") {
|
||||
closed = true;
|
||||
unsubscribe();
|
||||
writeDone(res);
|
||||
res.end();
|
||||
endStream();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
req.on("close", () => {
|
||||
closed = true;
|
||||
unsubscribe();
|
||||
if (!closed) {
|
||||
closed = true;
|
||||
unsubscribe();
|
||||
}
|
||||
});
|
||||
|
||||
void (async () => {
|
||||
@ -363,6 +382,7 @@ export async function handleOpenAiHttpRequest(
|
||||
}
|
||||
} catch (err) {
|
||||
if (closed) return;
|
||||
sentTerminalChunk = true;
|
||||
writeSse(res, {
|
||||
id: runId,
|
||||
object: "chat.completion.chunk",
|
||||
@ -382,12 +402,7 @@ export async function handleOpenAiHttpRequest(
|
||||
data: { phase: "error" },
|
||||
});
|
||||
} finally {
|
||||
if (!closed) {
|
||||
closed = true;
|
||||
unsubscribe();
|
||||
writeDone(res);
|
||||
res.end();
|
||||
}
|
||||
endStream();
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user