try to fix streaming responses
This commit is contained in:
@@ -1241,7 +1241,7 @@ async function sendChat() {
|
||||
.map(msg => ({ role: msg.role, content: msg.content })),
|
||||
{ role: "user", content: prompt },
|
||||
],
|
||||
stream: false,
|
||||
stream: true,
|
||||
max_tokens: 15120,
|
||||
};
|
||||
chatBusy = true;
|
||||
@@ -1249,36 +1249,83 @@ async function sendChat() {
|
||||
promptEl.value = "";
|
||||
promptEl.style.height = "auto";
|
||||
chatHistory.push({ role: "user", content: prompt, model: selectedChatModel });
|
||||
const assistantMessage = { role: "assistant", content: "", model: selectedChatModel };
|
||||
chatHistory.push(assistantMessage);
|
||||
renderChatHistory();
|
||||
persistActiveChatSession();
|
||||
renderChatStatus("sending request…");
|
||||
const r = await apiCall("/v1/chat/completions", "POST", body, bearerToken);
|
||||
chatBusy = false;
|
||||
$("chat-send").disabled = false;
|
||||
if (!r.ok) {
|
||||
const error = r.data && r.data.error
|
||||
? (typeof r.data.error === "string" ? r.data.error : r.data.error.message || "request failed")
|
||||
: "request failed";
|
||||
chatHistory.push({ role: "error", content: error, model: selectedChatModel });
|
||||
renderChatStatus("streaming response…");
|
||||
|
||||
try {
|
||||
const headers = { "Content-Type": "application/json" };
|
||||
if (bearerToken) headers["Authorization"] = "Bearer " + bearerToken;
|
||||
const response = await fetch("/v1/chat/completions", {
|
||||
method: "POST",
|
||||
headers,
|
||||
credentials: "same-origin",
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => ({}));
|
||||
const error = data && data.error
|
||||
? (typeof data.error === "string" ? data.error : data.error.message || "request failed")
|
||||
: "request failed";
|
||||
assistantMessage.role = "error";
|
||||
assistantMessage.content = error;
|
||||
renderChatHistory();
|
||||
persistActiveChatSession();
|
||||
renderChatStatus(error);
|
||||
return;
|
||||
}
|
||||
if (!response.body) throw new Error("stream response body is missing");
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let buffer = "";
|
||||
let receivedAny = false;
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) break;
|
||||
buffer += decoder.decode(value, { stream: true });
|
||||
const events = buffer.split("\n\n");
|
||||
buffer = events.pop() || "";
|
||||
for (const eventText of events) {
|
||||
for (const line of eventText.split("\n")) {
|
||||
if (!line.startsWith("data: ")) continue;
|
||||
const data = line.slice(6).trim();
|
||||
if (data === "[DONE]") {
|
||||
buffer = "";
|
||||
break;
|
||||
}
|
||||
try {
|
||||
const chunk = JSON.parse(data);
|
||||
const delta = chunk.choices && chunk.choices[0] && chunk.choices[0].delta;
|
||||
if (delta && delta.content) {
|
||||
assistantMessage.content += delta.content;
|
||||
receivedAny = true;
|
||||
renderChatHistory();
|
||||
persistActiveChatSession();
|
||||
}
|
||||
} catch {
|
||||
// Ignore malformed SSE keepalive/event lines.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!receivedAny) assistantMessage.content = "(empty response)";
|
||||
renderChatHistory();
|
||||
persistActiveChatSession();
|
||||
renderChatStatus(error);
|
||||
renderChatStatus("done");
|
||||
} catch (err) {
|
||||
assistantMessage.role = "error";
|
||||
assistantMessage.content = err && err.message ? err.message : "request failed";
|
||||
renderChatHistory();
|
||||
persistActiveChatSession();
|
||||
renderChatStatus(assistantMessage.content);
|
||||
} finally {
|
||||
chatBusy = false;
|
||||
$("chat-send").disabled = false;
|
||||
promptEl.focus();
|
||||
return;
|
||||
}
|
||||
const reply = (r.data && r.data.choices && r.data.choices[0] && r.data.choices[0].message && r.data.choices[0].message.content) || "";
|
||||
const usage = r.data && r.data.usage;
|
||||
chatHistory.push({
|
||||
role: "assistant",
|
||||
content: reply || "(empty response)",
|
||||
model: selectedChatModel,
|
||||
});
|
||||
renderChatHistory();
|
||||
persistActiveChatSession();
|
||||
renderChatStatus(usage
|
||||
? `done: ${usage.total_tokens ?? "?"} tokens`
|
||||
: "done");
|
||||
promptEl.focus();
|
||||
}
|
||||
|
||||
function bindChatPromptShortcuts() {
|
||||
|
||||
Reference in New Issue
Block a user