fix: #1498 missing text caused by streaming

This commit is contained in:
Yidadaa 2023-05-16 01:25:16 +08:00
parent 8b0cf7d248
commit aed6b34950
3 changed files with 28 additions and 35 deletions

View File

@ -3,6 +3,7 @@ import { useAccessStore, useAppConfig, useChatStore } from "@/app/store";
import { ChatOptions, getHeaders, LLMApi, LLMUsage } from "../api"; import { ChatOptions, getHeaders, LLMApi, LLMUsage } from "../api";
import Locale from "../../locales"; import Locale from "../../locales";
import { fetchEventSource } from "@microsoft/fetch-event-source";
export class ChatGPTApi implements LLMApi { export class ChatGPTApi implements LLMApi {
public ChatPath = "v1/chat/completions"; public ChatPath = "v1/chat/completions";
@ -71,40 +72,20 @@ export class ChatGPTApi implements LLMApi {
options.onFinish(responseText); options.onFinish(responseText);
}; };
const res = await fetch(chatPath, chatPayload); fetchEventSource(chatPath, {
clearTimeout(reqestTimeoutId); ...chatPayload,
async onopen(res) {
if (res.status === 401) { clearTimeout(reqestTimeoutId);
responseText += "\n\n" + Locale.Error.Unauthorized; if (res.status === 401) {
return finish(); responseText += "\n\n" + Locale.Error.Unauthorized;
}
if (
!res.ok ||
!res.headers.get("Content-Type")?.includes("stream") ||
!res.body
) {
return options.onError?.(new Error());
}
const reader = res.body.getReader();
const decoder = new TextDecoder("utf-8");
while (true) {
const { done, value } = await reader.read();
if (done) {
return finish();
}
const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split("data: ");
for (const line of lines) {
const text = line.trim();
if (line.startsWith("[DONE]")) {
return finish(); return finish();
} }
if (text.length === 0) continue; },
onmessage(msg) {
if (msg.data === "[DONE]") {
return finish();
}
const text = msg.data;
try { try {
const json = JSON.parse(text); const json = JSON.parse(text);
const delta = json.choices[0].delta.content; const delta = json.choices[0].delta.content;
@ -113,10 +94,16 @@ export class ChatGPTApi implements LLMApi {
options.onUpdate?.(responseText, delta); options.onUpdate?.(responseText, delta);
} }
} catch (e) { } catch (e) {
console.error("[Request] parse error", text, chunk); console.error("[Request] parse error", text, msg);
} }
} },
} onclose() {
finish();
},
onerror(e) {
options.onError?.(e);
},
});
} else { } else {
const res = await fetch(chatPath, chatPayload); const res = await fetch(chatPath, chatPayload);
clearTimeout(reqestTimeoutId); clearTimeout(reqestTimeoutId);

View File

@ -14,6 +14,7 @@
}, },
"dependencies": { "dependencies": {
"@hello-pangea/dnd": "^16.2.0", "@hello-pangea/dnd": "^16.2.0",
"@microsoft/fetch-event-source": "^2.0.1",
"@svgr/webpack": "^6.5.1", "@svgr/webpack": "^6.5.1",
"@vercel/analytics": "^0.1.11", "@vercel/analytics": "^0.1.11",
"emoji-picker-react": "^4.4.7", "emoji-picker-react": "^4.4.7",

View File

@ -1111,6 +1111,11 @@
dependencies: dependencies:
"@types/react" ">=16.0.0" "@types/react" ">=16.0.0"
"@microsoft/fetch-event-source@^2.0.1":
version "2.0.1"
resolved "https://registry.npmmirror.com/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz#9ceecc94b49fbaa15666e38ae8587f64acce007d"
integrity sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==
"@next/env@13.4.2": "@next/env@13.4.2":
version "13.4.2" version "13.4.2"
resolved "https://registry.npmmirror.com/@next/env/-/env-13.4.2.tgz#cf3ebfd523a33d8404c1216e02ac8d856a73170e" resolved "https://registry.npmmirror.com/@next/env/-/env-13.4.2.tgz#cf3ebfd523a33d8404c1216e02ac8d856a73170e"