forked from XiaoMo/ChatGPT-Next-Web
Merge branch 'main' of https://github.com/Yidadaa/ChatGPT-Next-Web
This commit is contained in:
commit
a70d59eb45
@ -43,8 +43,7 @@ export function auth(req: NextRequest) {
|
||||
if (serverConfig.needCode && !serverConfig.codes.has(hashedCode) && !token) {
|
||||
return {
|
||||
error: true,
|
||||
needAccessCode: true,
|
||||
msg: "Please go settings page and fill your access code.",
|
||||
msg: !accessCode ? "empty access code" : "wrong access code",
|
||||
};
|
||||
}
|
||||
|
||||
@ -58,7 +57,7 @@ export function auth(req: NextRequest) {
|
||||
console.log("[Auth] admin did not provide an api key");
|
||||
return {
|
||||
error: true,
|
||||
msg: "Empty Api Key",
|
||||
msg: "admin did not provide an api key",
|
||||
};
|
||||
}
|
||||
} else {
|
||||
|
@ -3,6 +3,8 @@ import { useAccessStore, useAppConfig, useChatStore } from "@/app/store";
|
||||
|
||||
import { ChatOptions, getHeaders, LLMApi, LLMUsage } from "../api";
|
||||
import Locale from "../../locales";
|
||||
import { fetchEventSource } from "@microsoft/fetch-event-source";
|
||||
import { prettyObject } from "@/app/utils/format";
|
||||
|
||||
export class ChatGPTApi implements LLMApi {
|
||||
public ChatPath = "v1/chat/completions";
|
||||
@ -10,8 +12,10 @@ export class ChatGPTApi implements LLMApi {
|
||||
public SubsPath = "dashboard/billing/subscription";
|
||||
|
||||
path(path: string): string {
|
||||
const openaiUrl = useAccessStore.getState().openaiUrl;
|
||||
if (openaiUrl.endsWith("/")) openaiUrl.slice(0, openaiUrl.length - 1);
|
||||
let openaiUrl = useAccessStore.getState().openaiUrl;
|
||||
if (openaiUrl.endsWith("/")) {
|
||||
openaiUrl = openaiUrl.slice(0, openaiUrl.length - 1);
|
||||
}
|
||||
return [openaiUrl, path].join("/");
|
||||
}
|
||||
|
||||
@ -69,40 +73,32 @@ export class ChatGPTApi implements LLMApi {
|
||||
options.onFinish(responseText);
|
||||
};
|
||||
|
||||
const res = await fetch(chatPath, chatPayload);
|
||||
clearTimeout(reqestTimeoutId);
|
||||
controller.signal.onabort = finish;
|
||||
|
||||
if (res.status === 401) {
|
||||
responseText += "\n\n" + Locale.Error.Unauthorized;
|
||||
return finish();
|
||||
}
|
||||
fetchEventSource(chatPath, {
|
||||
...chatPayload,
|
||||
async onopen(res) {
|
||||
clearTimeout(reqestTimeoutId);
|
||||
if (res.status === 401) {
|
||||
let extraInfo = { error: undefined };
|
||||
try {
|
||||
extraInfo = await res.clone().json();
|
||||
} catch {}
|
||||
|
||||
if (
|
||||
!res.ok ||
|
||||
!res.headers.get("Content-Type")?.includes("stream") ||
|
||||
!res.body
|
||||
) {
|
||||
return options.onError?.(new Error());
|
||||
}
|
||||
responseText += "\n\n" + Locale.Error.Unauthorized;
|
||||
|
||||
const reader = res.body.getReader();
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
if (extraInfo.error) {
|
||||
responseText += "\n\n" + prettyObject(extraInfo);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
if (text.length === 0) continue;
|
||||
},
|
||||
onmessage(msg) {
|
||||
if (msg.data === "[DONE]") {
|
||||
return finish();
|
||||
}
|
||||
const text = msg.data;
|
||||
try {
|
||||
const json = JSON.parse(text);
|
||||
const delta = json.choices[0].delta.content;
|
||||
@ -111,10 +107,16 @@ export class ChatGPTApi implements LLMApi {
|
||||
options.onUpdate?.(responseText, delta);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("[Request] parse error", text, chunk);
|
||||
console.error("[Request] parse error", text, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onclose() {
|
||||
finish();
|
||||
},
|
||||
onerror(e) {
|
||||
options.onError?.(e);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const res = await fetch(chatPath, chatPayload);
|
||||
clearTimeout(reqestTimeoutId);
|
||||
|
@ -249,7 +249,7 @@ export const useChatStore = create<ChatStore>()(
|
||||
|
||||
const systemInfo = createMessage({
|
||||
role: "system",
|
||||
content: `IMPRTANT: You are a virtual assistant powered by the ${
|
||||
content: `IMPORTANT: You are a virtual assistant powered by the ${
|
||||
modelConfig.model
|
||||
} model, now time is ${new Date().toLocaleString()}}`,
|
||||
id: botMessage.id! + 1,
|
||||
@ -296,9 +296,7 @@ export const useChatStore = create<ChatStore>()(
|
||||
botMessage.content !== Locale.Error.Unauthorized &&
|
||||
!isAborted
|
||||
) {
|
||||
botMessage.content += "\n\n" + Locale.Store.Error;
|
||||
} else if (botMessage.content.length === 0) {
|
||||
botMessage.content = prettyObject(error);
|
||||
botMessage.content += "\n\n" + prettyObject(error);
|
||||
}
|
||||
botMessage.streaming = false;
|
||||
userMessage.isError = !isAborted;
|
||||
|
@ -14,6 +14,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@hello-pangea/dnd": "^16.2.0",
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
"@svgr/webpack": "^6.5.1",
|
||||
"@vercel/analytics": "^0.1.11",
|
||||
"emoji-picker-react": "^4.4.7",
|
||||
|
@ -1111,6 +1111,11 @@
|
||||
dependencies:
|
||||
"@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":
|
||||
version "13.4.2"
|
||||
resolved "https://registry.npmmirror.com/@next/env/-/env-13.4.2.tgz#cf3ebfd523a33d8404c1216e02ac8d856a73170e"
|
||||
|
Loading…
Reference in New Issue
Block a user