fix: #410 can not stop response

This commit is contained in:
Yidadaa 2023-04-06 03:19:33 +08:00
parent c2b37f811b
commit 8e560d2b2e
5 changed files with 57 additions and 32 deletions

View File

@ -53,6 +53,9 @@ export async function POST(req: NextRequest) {
return new Response(stream);
} catch (error) {
console.error("[Chat Stream]", error);
return new Response(
["```json\n", JSON.stringify(error, null, " "), "\n```"].join(""),
);
}
}

View File

@ -12,7 +12,14 @@ import BotIcon from "../icons/bot.svg";
import AddIcon from "../icons/add.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 {
copyToClipboard,
@ -407,8 +414,8 @@ export function Chat(props: {
};
// stop response
const onUserStop = (messageIndex: number) => {
ControllerPool.stop(sessionIndex, messageIndex);
const onUserStop = (messageId: number) => {
ControllerPool.stop(sessionIndex, messageId);
};
// check if should send message
@ -439,6 +446,7 @@ export function Chat(props: {
.onUserInput(messages[i].content)
.then(() => setIsLoading(false));
inputRef.current?.focus();
messages.splice(i, 2);
return;
}
}
@ -462,9 +470,10 @@ export function Chat(props: {
isLoading
? [
{
...createMessage({
role: "assistant",
content: "……",
date: new Date().toLocaleString(),
}),
preview: true,
},
]
@ -474,9 +483,10 @@ export function Chat(props: {
userInput.length > 0 && config.sendPreviewBubble
? [
{
...createMessage({
role: "user",
content: userInput,
date: new Date().toLocaleString(),
}),
preview: true,
},
]
@ -489,6 +499,7 @@ export function Chat(props: {
useEffect(() => {
if (props.sideBarShowing && isMobileScreen()) return;
inputRef.current?.focus();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
@ -592,7 +603,7 @@ export function Chat(props: {
{message.streaming ? (
<div
className={styles["chat-message-top-action"]}
onClick={() => onUserStop(i)}
onClick={() => onUserStop(message.id ?? i)}
>
{Locale.Chat.Actions.Stop}
</div>

View File

@ -204,23 +204,22 @@ export const ControllerPool = {
addController(
sessionIndex: number,
messageIndex: number,
messageId: number,
controller: AbortController,
) {
const key = this.key(sessionIndex, messageIndex);
const key = this.key(sessionIndex, messageId);
this.controllers[key] = controller;
return key;
},
stop(sessionIndex: number, messageIndex: number) {
const key = this.key(sessionIndex, messageIndex);
stop(sessionIndex: number, messageId: number) {
const key = this.key(sessionIndex, messageId);
const controller = this.controllers[key];
console.log(controller);
controller?.abort();
},
remove(sessionIndex: number, messageIndex: number) {
const key = this.key(sessionIndex, messageIndex);
remove(sessionIndex: number, messageId: number) {
const key = this.key(sessionIndex, messageId);
delete this.controllers[key];
},

View File

@ -15,8 +15,19 @@ export type Message = ChatCompletionResponseMessage & {
date: string;
streaming?: 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 {
Enter = "Enter",
CtrlEnter = "Ctrl + Enter",
@ -159,11 +170,10 @@ export interface ChatSession {
}
const DEFAULT_TOPIC = Locale.Store.DefaultTopic;
export const BOT_HELLO: Message = {
export const BOT_HELLO: Message = createMessage({
role: "assistant",
content: Locale.Store.BotHello,
date: "",
};
});
function createEmptySession(): ChatSession {
const createDate = new Date().toLocaleString();
@ -311,18 +321,15 @@ export const useChatStore = create<ChatStore>()(
},
async onUserInput(content) {
const userMessage: Message = {
const userMessage: Message = createMessage({
role: "user",
content,
date: new Date().toLocaleString(),
};
});
const botMessage: Message = {
content: "",
const botMessage: Message = createMessage({
role: "assistant",
date: new Date().toLocaleString(),
streaming: true,
};
});
// get recent messages
const recentMessages = get().getMessagesWithMemory();
@ -345,7 +352,10 @@ export const useChatStore = create<ChatStore>()(
botMessage.streaming = false;
botMessage.content = content;
get().onNewMessage(botMessage);
ControllerPool.remove(sessionIndex, messageIndex);
ControllerPool.remove(
sessionIndex,
botMessage.id ?? messageIndex,
);
} else {
botMessage.content = content;
set(() => ({}));
@ -361,13 +371,13 @@ export const useChatStore = create<ChatStore>()(
userMessage.isError = true;
botMessage.isError = true;
set(() => ({}));
ControllerPool.remove(sessionIndex, messageIndex);
ControllerPool.remove(sessionIndex, botMessage.id ?? messageIndex);
},
onController(controller) {
// collect controller for stop/retry
ControllerPool.addController(
sessionIndex,
messageIndex,
botMessage.id ?? messageIndex,
controller,
);
},
@ -441,7 +451,8 @@ export const useChatStore = create<ChatStore>()(
requestWithPrompt(session.messages, Locale.Store.Prompt.Topic).then(
(res) => {
get().updateCurrentSession(
(session) => (session.topic = trimTopic(res)),
(session) =>
(session.topic = res ? trimTopic(res) : DEFAULT_TOPIC),
);
},
);

View File

@ -61,4 +61,5 @@ read -p "Enter CODE: " CODE
read -p "Enter PORT: " PORT
# 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