I'm working on a ChatGPT integration in Node/Express and would like to first respond to my client with some metadata in JSON, then start streaming ChatGPT's response as it streams in.
Currently, there are no errors and it works but the chunks are coming through in an unexpected manner on the client side. The client onprogress handler doesn't start receiving chunks until the server starts sending the chunked response from GPT.
Server-Side
// Send response message array to client
res.setHeader('Transfer-Encoding', 'chunked')
let chunkedJSON = chunkString(JSON.stringify(myJSON), 20)
for(let i = 0; i < chunkedJSON.length; i++){
res.write(chunkedJSON[i])
}
res.write('END-JSON')
// Get GPT Response
const stream = await openai.chat.completions.create(
{
messages: messages,
model: thread.model,
stream: true
},
{
responseType: "stream"
}
)
// Stream ChatGPT response
for await (const part of stream) {
tokens++ // each chunk from the completion API is a token
if (part.choices[0].finish_reason === "stop") {
res.end();
} else {
res.write(part.choices[0]?.delta?.content || "")
}
}
Client-Side
let xhr = new XMLHttpRequest();
xhr.open("POST", environment.serverBaseUrl + '/chat/message', true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("x-access-token", this.userAuth!);
xhr.onprogress = function () {
var curr_index = xhr.responseText.length;
if (last_index == curr_index) return;
var s = xhr.responseText.substring(last_index, curr_index);
last_index = curr_index;
console.log("PROGRESS:", s);
}
xhr.onload = function () {
console.log("COMPLETE:", xhr.responseText);
}
xhr.send(JSON.stringify({
test: true,
message: message
}));
Removing res.setHeader('Transfer-Encoding', 'chunked') worked