From 8e560d2b2eec503ae43685a5a23f0c726eb9ae58 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Thu, 6 Apr 2023 03:19:33 +0800 Subject: [PATCH] fix: #410 can not stop response --- app/api/chat-stream/route.ts | 3 +++ app/components/chat.tsx | 31 +++++++++++++++++++--------- app/requests.ts | 13 ++++++------ app/store/app.ts | 39 +++++++++++++++++++++++------------- scripts/setup.sh | 3 ++- 5 files changed, 57 insertions(+), 32 deletions(-) diff --git a/app/api/chat-stream/route.ts b/app/api/chat-stream/route.ts index f3317554..526623ce 100644 --- a/app/api/chat-stream/route.ts +++ b/app/api/chat-stream/route.ts @@ -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(""), + ); } } diff --git a/app/components/chat.tsx b/app/components/chat.tsx index dc746e24..ea1eb7e2 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -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 ? [ { - role: "assistant", - content: "……", - date: new Date().toLocaleString(), + ...createMessage({ + role: "assistant", + content: "……", + }), preview: true, }, ] @@ -474,9 +483,10 @@ export function Chat(props: { userInput.length > 0 && config.sendPreviewBubble ? [ { - role: "user", - content: userInput, - date: new Date().toLocaleString(), + ...createMessage({ + role: "user", + content: userInput, + }), 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 ? (
onUserStop(i)} + onClick={() => onUserStop(message.id ?? i)} > {Locale.Chat.Actions.Stop}
diff --git a/app/requests.ts b/app/requests.ts index da9b5c97..c60efc95 100644 --- a/app/requests.ts +++ b/app/requests.ts @@ -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]; }, diff --git a/app/store/app.ts b/app/store/app.ts index 9f1e8e88..64faa31d 100644 --- a/app/store/app.ts +++ b/app/store/app.ts @@ -15,8 +15,19 @@ export type Message = ChatCompletionResponseMessage & { date: string; streaming?: boolean; isError?: boolean; + id?: number; }; +export function createMessage(override: Partial): 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()( }, 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()( 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()( 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()( requestWithPrompt(session.messages, Locale.Store.Prompt.Topic).then( (res) => { get().updateCurrentSession( - (session) => (session.topic = trimTopic(res)), + (session) => + (session.topic = res ? trimTopic(res) : DEFAULT_TOPIC), ); }, ); diff --git a/scripts/setup.sh b/scripts/setup.sh index 63a28bf0..b9653339 100644 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -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