forked from XiaoMo/ChatGPT-Next-Web
fix: #410 can not stop response
This commit is contained in:
parent
c2b37f811b
commit
8e560d2b2e
@ -53,6 +53,9 @@ export async function POST(req: NextRequest) {
|
|||||||
return new Response(stream);
|
return new Response(stream);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[Chat Stream]", error);
|
console.error("[Chat Stream]", error);
|
||||||
|
return new Response(
|
||||||
|
["```json\n", JSON.stringify(error, null, " "), "\n```"].join(""),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,14 @@ import BotIcon from "../icons/bot.svg";
|
|||||||
import AddIcon from "../icons/add.svg";
|
import AddIcon from "../icons/add.svg";
|
||||||
import DeleteIcon from "../icons/delete.svg";
|
import DeleteIcon from "../icons/delete.svg";
|
||||||
|
|
||||||
import { Message, SubmitKey, useChatStore, BOT_HELLO, ROLES } from "../store";
|
import {
|
||||||
|
Message,
|
||||||
|
SubmitKey,
|
||||||
|
useChatStore,
|
||||||
|
BOT_HELLO,
|
||||||
|
ROLES,
|
||||||
|
createMessage,
|
||||||
|
} from "../store";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
copyToClipboard,
|
copyToClipboard,
|
||||||
@ -407,8 +414,8 @@ export function Chat(props: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// stop response
|
// stop response
|
||||||
const onUserStop = (messageIndex: number) => {
|
const onUserStop = (messageId: number) => {
|
||||||
ControllerPool.stop(sessionIndex, messageIndex);
|
ControllerPool.stop(sessionIndex, messageId);
|
||||||
};
|
};
|
||||||
|
|
||||||
// check if should send message
|
// check if should send message
|
||||||
@ -439,6 +446,7 @@ export function Chat(props: {
|
|||||||
.onUserInput(messages[i].content)
|
.onUserInput(messages[i].content)
|
||||||
.then(() => setIsLoading(false));
|
.then(() => setIsLoading(false));
|
||||||
inputRef.current?.focus();
|
inputRef.current?.focus();
|
||||||
|
messages.splice(i, 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -462,9 +470,10 @@ export function Chat(props: {
|
|||||||
isLoading
|
isLoading
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
role: "assistant",
|
...createMessage({
|
||||||
content: "……",
|
role: "assistant",
|
||||||
date: new Date().toLocaleString(),
|
content: "……",
|
||||||
|
}),
|
||||||
preview: true,
|
preview: true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -474,9 +483,10 @@ export function Chat(props: {
|
|||||||
userInput.length > 0 && config.sendPreviewBubble
|
userInput.length > 0 && config.sendPreviewBubble
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
role: "user",
|
...createMessage({
|
||||||
content: userInput,
|
role: "user",
|
||||||
date: new Date().toLocaleString(),
|
content: userInput,
|
||||||
|
}),
|
||||||
preview: true,
|
preview: true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -489,6 +499,7 @@ export function Chat(props: {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.sideBarShowing && isMobileScreen()) return;
|
if (props.sideBarShowing && isMobileScreen()) return;
|
||||||
inputRef.current?.focus();
|
inputRef.current?.focus();
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -592,7 +603,7 @@ export function Chat(props: {
|
|||||||
{message.streaming ? (
|
{message.streaming ? (
|
||||||
<div
|
<div
|
||||||
className={styles["chat-message-top-action"]}
|
className={styles["chat-message-top-action"]}
|
||||||
onClick={() => onUserStop(i)}
|
onClick={() => onUserStop(message.id ?? i)}
|
||||||
>
|
>
|
||||||
{Locale.Chat.Actions.Stop}
|
{Locale.Chat.Actions.Stop}
|
||||||
</div>
|
</div>
|
||||||
|
@ -204,23 +204,22 @@ export const ControllerPool = {
|
|||||||
|
|
||||||
addController(
|
addController(
|
||||||
sessionIndex: number,
|
sessionIndex: number,
|
||||||
messageIndex: number,
|
messageId: number,
|
||||||
controller: AbortController,
|
controller: AbortController,
|
||||||
) {
|
) {
|
||||||
const key = this.key(sessionIndex, messageIndex);
|
const key = this.key(sessionIndex, messageId);
|
||||||
this.controllers[key] = controller;
|
this.controllers[key] = controller;
|
||||||
return key;
|
return key;
|
||||||
},
|
},
|
||||||
|
|
||||||
stop(sessionIndex: number, messageIndex: number) {
|
stop(sessionIndex: number, messageId: number) {
|
||||||
const key = this.key(sessionIndex, messageIndex);
|
const key = this.key(sessionIndex, messageId);
|
||||||
const controller = this.controllers[key];
|
const controller = this.controllers[key];
|
||||||
console.log(controller);
|
|
||||||
controller?.abort();
|
controller?.abort();
|
||||||
},
|
},
|
||||||
|
|
||||||
remove(sessionIndex: number, messageIndex: number) {
|
remove(sessionIndex: number, messageId: number) {
|
||||||
const key = this.key(sessionIndex, messageIndex);
|
const key = this.key(sessionIndex, messageId);
|
||||||
delete this.controllers[key];
|
delete this.controllers[key];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -15,8 +15,19 @@ export type Message = ChatCompletionResponseMessage & {
|
|||||||
date: string;
|
date: string;
|
||||||
streaming?: boolean;
|
streaming?: boolean;
|
||||||
isError?: boolean;
|
isError?: boolean;
|
||||||
|
id?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function createMessage(override: Partial<Message>): Message {
|
||||||
|
return {
|
||||||
|
id: Date.now(),
|
||||||
|
date: new Date().toLocaleString(),
|
||||||
|
role: "user",
|
||||||
|
content: "",
|
||||||
|
...override,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export enum SubmitKey {
|
export enum SubmitKey {
|
||||||
Enter = "Enter",
|
Enter = "Enter",
|
||||||
CtrlEnter = "Ctrl + Enter",
|
CtrlEnter = "Ctrl + Enter",
|
||||||
@ -159,11 +170,10 @@ export interface ChatSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_TOPIC = Locale.Store.DefaultTopic;
|
const DEFAULT_TOPIC = Locale.Store.DefaultTopic;
|
||||||
export const BOT_HELLO: Message = {
|
export const BOT_HELLO: Message = createMessage({
|
||||||
role: "assistant",
|
role: "assistant",
|
||||||
content: Locale.Store.BotHello,
|
content: Locale.Store.BotHello,
|
||||||
date: "",
|
});
|
||||||
};
|
|
||||||
|
|
||||||
function createEmptySession(): ChatSession {
|
function createEmptySession(): ChatSession {
|
||||||
const createDate = new Date().toLocaleString();
|
const createDate = new Date().toLocaleString();
|
||||||
@ -311,18 +321,15 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
},
|
},
|
||||||
|
|
||||||
async onUserInput(content) {
|
async onUserInput(content) {
|
||||||
const userMessage: Message = {
|
const userMessage: Message = createMessage({
|
||||||
role: "user",
|
role: "user",
|
||||||
content,
|
content,
|
||||||
date: new Date().toLocaleString(),
|
});
|
||||||
};
|
|
||||||
|
|
||||||
const botMessage: Message = {
|
const botMessage: Message = createMessage({
|
||||||
content: "",
|
|
||||||
role: "assistant",
|
role: "assistant",
|
||||||
date: new Date().toLocaleString(),
|
|
||||||
streaming: true,
|
streaming: true,
|
||||||
};
|
});
|
||||||
|
|
||||||
// get recent messages
|
// get recent messages
|
||||||
const recentMessages = get().getMessagesWithMemory();
|
const recentMessages = get().getMessagesWithMemory();
|
||||||
@ -345,7 +352,10 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
botMessage.streaming = false;
|
botMessage.streaming = false;
|
||||||
botMessage.content = content;
|
botMessage.content = content;
|
||||||
get().onNewMessage(botMessage);
|
get().onNewMessage(botMessage);
|
||||||
ControllerPool.remove(sessionIndex, messageIndex);
|
ControllerPool.remove(
|
||||||
|
sessionIndex,
|
||||||
|
botMessage.id ?? messageIndex,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
botMessage.content = content;
|
botMessage.content = content;
|
||||||
set(() => ({}));
|
set(() => ({}));
|
||||||
@ -361,13 +371,13 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
userMessage.isError = true;
|
userMessage.isError = true;
|
||||||
botMessage.isError = true;
|
botMessage.isError = true;
|
||||||
set(() => ({}));
|
set(() => ({}));
|
||||||
ControllerPool.remove(sessionIndex, messageIndex);
|
ControllerPool.remove(sessionIndex, botMessage.id ?? messageIndex);
|
||||||
},
|
},
|
||||||
onController(controller) {
|
onController(controller) {
|
||||||
// collect controller for stop/retry
|
// collect controller for stop/retry
|
||||||
ControllerPool.addController(
|
ControllerPool.addController(
|
||||||
sessionIndex,
|
sessionIndex,
|
||||||
messageIndex,
|
botMessage.id ?? messageIndex,
|
||||||
controller,
|
controller,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -441,7 +451,8 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
requestWithPrompt(session.messages, Locale.Store.Prompt.Topic).then(
|
requestWithPrompt(session.messages, Locale.Store.Prompt.Topic).then(
|
||||||
(res) => {
|
(res) => {
|
||||||
get().updateCurrentSession(
|
get().updateCurrentSession(
|
||||||
(session) => (session.topic = trimTopic(res)),
|
(session) =>
|
||||||
|
(session.topic = res ? trimTopic(res) : DEFAULT_TOPIC),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -61,4 +61,5 @@ read -p "Enter CODE: " CODE
|
|||||||
read -p "Enter PORT: " PORT
|
read -p "Enter PORT: " PORT
|
||||||
|
|
||||||
# Build and run the project using the environment variables
|
# Build and run the project using the environment variables
|
||||||
OPENAI_API_KEY=$OPENAI_API_KEY CODE=$CODE PORT=$PORT yarn build && OPENAI_API_KEY=$OPENAI_API_KEY CODE=$CODE PORT=$PORT yarn start
|
OPENAI_API_KEY=$OPENAI_API_KEY CODE=$CODE PORT=$PORT yarn build
|
||||||
|
OPENAI_API_KEY=$OPENAI_API_KEY CODE=$CODE PORT=$PORT yarn start
|
||||||
|
Loading…
Reference in New Issue
Block a user