mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-11-04 16:23:41 +08:00 
			
		
		
		
	fix: #410 can not stop response
This commit is contained in:
		@@ -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(""),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 ? (
 | 
			
		||||
                          <div
 | 
			
		||||
                            className={styles["chat-message-top-action"]}
 | 
			
		||||
                            onClick={() => onUserStop(i)}
 | 
			
		||||
                            onClick={() => onUserStop(message.id ?? i)}
 | 
			
		||||
                          >
 | 
			
		||||
                            {Locale.Chat.Actions.Stop}
 | 
			
		||||
                          </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -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];
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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),
 | 
			
		||||
              );
 | 
			
		||||
            },
 | 
			
		||||
          );
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user