mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-11-04 16:23:41 +08:00 
			
		
		
		
	feat: support compress chat history
This commit is contained in:
		@@ -208,7 +208,10 @@ export function Chat(props: { showSideBar?: () => void }) {
 | 
				
			|||||||
            <IconButton
 | 
					            <IconButton
 | 
				
			||||||
              icon={<BrainIcon />}
 | 
					              icon={<BrainIcon />}
 | 
				
			||||||
              bordered
 | 
					              bordered
 | 
				
			||||||
              title="查看压缩后的历史 Prompt(开发中)"
 | 
					              title="查看压缩后的历史 Prompt"
 | 
				
			||||||
 | 
					              onClick={() => {
 | 
				
			||||||
 | 
					                showMemoryPrompt(session.memoryPrompt)
 | 
				
			||||||
 | 
					              }}
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
          <div className={styles["window-action-button"]}>
 | 
					          <div className={styles["window-action-button"]}>
 | 
				
			||||||
@@ -320,6 +323,16 @@ function exportMessages(messages: Message[], topic: string) {
 | 
				
			|||||||
  })
 | 
					  })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function showMemoryPrompt(prompt: string) {
 | 
				
			||||||
 | 
					  showModal({
 | 
				
			||||||
 | 
					    title: "上下文记忆 Prompt", children: <div className="markdown-body">
 | 
				
			||||||
 | 
					      <pre className={styles['export-content']}>{prompt}</pre>
 | 
				
			||||||
 | 
					    </div>, actions: [
 | 
				
			||||||
 | 
					      <IconButton key="copy" icon={<CopyIcon />} bordered text="全部复制" onClick={() => copyToClipboard(prompt)} />,
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function Home() {
 | 
					export function Home() {
 | 
				
			||||||
  const [createNewSession] = useChatStore((state) => [state.newSession]);
 | 
					  const [createNewSession] = useChatStore((state) => [state.newSession]);
 | 
				
			||||||
  const loading = !useChatStore?.persist?.hasHydrated();
 | 
					  const loading = !useChatStore?.persist?.hasHydrated();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ import styles from "./settings.module.scss";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import ResetIcon from "../icons/reload.svg";
 | 
					import ResetIcon from "../icons/reload.svg";
 | 
				
			||||||
import CloseIcon from "../icons/close.svg";
 | 
					import CloseIcon from "../icons/close.svg";
 | 
				
			||||||
 | 
					import ClearIcon from "../icons/clear.svg";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { List, ListItem, Popover } from "./ui-lib";
 | 
					import { List, ListItem, Popover } from "./ui-lib";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,10 +16,11 @@ import { Avatar } from "./home";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export function Settings(props: { closeSettings: () => void }) {
 | 
					export function Settings(props: { closeSettings: () => void }) {
 | 
				
			||||||
  const [showEmojiPicker, setShowEmojiPicker] = useState(false);
 | 
					  const [showEmojiPicker, setShowEmojiPicker] = useState(false);
 | 
				
			||||||
  const [config, updateConfig, resetConfig] = useChatStore((state) => [
 | 
					  const [config, updateConfig, resetConfig, clearAllData] = useChatStore((state) => [
 | 
				
			||||||
    state.config,
 | 
					    state.config,
 | 
				
			||||||
    state.updateConfig,
 | 
					    state.updateConfig,
 | 
				
			||||||
    state.resetConfig,
 | 
					    state.resetConfig,
 | 
				
			||||||
 | 
					    state.clearAllData,
 | 
				
			||||||
  ]);
 | 
					  ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@@ -31,10 +33,10 @@ export function Settings(props: { closeSettings: () => void }) {
 | 
				
			|||||||
        <div className={styles["window-actions"]}>
 | 
					        <div className={styles["window-actions"]}>
 | 
				
			||||||
          <div className={styles["window-action-button"]}>
 | 
					          <div className={styles["window-action-button"]}>
 | 
				
			||||||
            <IconButton
 | 
					            <IconButton
 | 
				
			||||||
              icon={<CloseIcon />}
 | 
					              icon={<ClearIcon />}
 | 
				
			||||||
              onClick={props.closeSettings}
 | 
					              onClick={clearAllData}
 | 
				
			||||||
              bordered
 | 
					              bordered
 | 
				
			||||||
              title="重置所有选项"
 | 
					              title="清除所有数据"
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
          <div className={styles["window-action-button"]}>
 | 
					          <div className={styles["window-action-button"]}>
 | 
				
			||||||
@@ -45,6 +47,14 @@ export function Settings(props: { closeSettings: () => void }) {
 | 
				
			|||||||
              title="重置所有选项"
 | 
					              title="重置所有选项"
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div className={styles["window-action-button"]}>
 | 
				
			||||||
 | 
					            <IconButton
 | 
				
			||||||
 | 
					              icon={<CloseIcon />}
 | 
				
			||||||
 | 
					              onClick={props.closeSettings}
 | 
				
			||||||
 | 
					              bordered
 | 
				
			||||||
 | 
					              title="关闭"
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div className={styles["settings"]}>
 | 
					      <div className={styles["settings"]}>
 | 
				
			||||||
@@ -147,6 +157,24 @@ export function Settings(props: { closeSettings: () => void }) {
 | 
				
			|||||||
            ></input>
 | 
					            ></input>
 | 
				
			||||||
          </ListItem>
 | 
					          </ListItem>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <ListItem>
 | 
				
			||||||
 | 
					            <div className={styles["settings-title"]}>
 | 
				
			||||||
 | 
					              历史消息压缩长度阈值
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <input
 | 
				
			||||||
 | 
					              type="number"
 | 
				
			||||||
 | 
					              min={500}
 | 
				
			||||||
 | 
					              max={4000}
 | 
				
			||||||
 | 
					              value={config.compressMessageLengthThreshold}
 | 
				
			||||||
 | 
					              onChange={(e) =>
 | 
				
			||||||
 | 
					                updateConfig(
 | 
				
			||||||
 | 
					                  (config) => (config.compressMessageLengthThreshold = e.currentTarget.valueAsNumber)
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ></input>
 | 
				
			||||||
 | 
					          </ListItem>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <ListItem>
 | 
					          <ListItem>
 | 
				
			||||||
            <div className={styles["settings-title"]}>
 | 
					            <div className={styles["settings-title"]}>
 | 
				
			||||||
              上下文中包含机器人消息
 | 
					              上下文中包含机器人消息
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,7 +90,7 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .modal-content {
 | 
					  .modal-content {
 | 
				
			||||||
    height: 40vh;
 | 
					    max-height: 40vh;
 | 
				
			||||||
    padding: var(--modal-padding);
 | 
					    padding: var(--modal-padding);
 | 
				
			||||||
    overflow: auto;
 | 
					    overflow: auto;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -118,7 +118,7 @@
 | 
				
			|||||||
    width: 90vw;
 | 
					    width: 90vw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .modal-content {
 | 
					    .modal-content {
 | 
				
			||||||
      height: 50vh;
 | 
					      max-height: 50vh;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								app/icons/clear.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								app/icons/clear.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16" fill="none"><defs><rect id="path_0" x="0" y="0" width="16" height="16" /></defs><g opacity="1" transform="translate(0 0)  rotate(0 8 8)"><mask id="bg-mask-0" fill="white"><use xlink:href="#path_0"></use></mask><g mask="url(#bg-mask-0)" ><path  id="路径 1" style="stroke:#333333; stroke-width:1.3333333333333333; stroke-opacity:1; stroke-dasharray:0 0" transform="translate(2.6666666666666665 5)  rotate(0 5.333333333333333 4.833333333333333)" d="M1,9.67L9.67,9.67L10.67,0L0,0L1,9.67Z " /><path  id="路径 2" style="stroke:#333333; stroke-width:1.3333333333333333; stroke-opacity:1; stroke-dasharray:0 0" transform="translate(6.667333333333333 8.334133333333334)  rotate(0 0 1.6666999999999998)" d="M0,0L0,3.33 " /><path  id="路径 3" style="stroke:#333333; stroke-width:1.3333333333333333; stroke-opacity:1; stroke-dasharray:0 0" transform="translate(9.334133333333334 8.333166666666667)  rotate(0 0 1.666283333333333)" d="M0,0L0,3.33 " /><path  id="路径 4" style="stroke:#333333; stroke-width:1.3333333333333333; stroke-opacity:1; stroke-dasharray:0 0" transform="translate(4 1)  rotate(0 4 2)" d="M0,4L5.44,0L8,4 " /></g></g></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 1.2 KiB  | 
							
								
								
									
										82
									
								
								app/store.ts
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								app/store.ts
									
									
									
									
									
								
							@@ -26,6 +26,7 @@ export enum Theme {
 | 
				
			|||||||
interface ChatConfig {
 | 
					interface ChatConfig {
 | 
				
			||||||
  maxToken?: number;
 | 
					  maxToken?: number;
 | 
				
			||||||
  historyMessageCount: number; // -1 means all
 | 
					  historyMessageCount: number; // -1 means all
 | 
				
			||||||
 | 
					  compressMessageLengthThreshold: number;
 | 
				
			||||||
  sendBotMessages: boolean; // send bot's message or not
 | 
					  sendBotMessages: boolean; // send bot's message or not
 | 
				
			||||||
  submitKey: SubmitKey;
 | 
					  submitKey: SubmitKey;
 | 
				
			||||||
  avatar: string;
 | 
					  avatar: string;
 | 
				
			||||||
@@ -35,9 +36,10 @@ interface ChatConfig {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const DEFAULT_CONFIG: ChatConfig = {
 | 
					const DEFAULT_CONFIG: ChatConfig = {
 | 
				
			||||||
  historyMessageCount: 5,
 | 
					  historyMessageCount: 5,
 | 
				
			||||||
  sendBotMessages: false as boolean,
 | 
					  compressMessageLengthThreshold: 500,
 | 
				
			||||||
 | 
					  sendBotMessages: true as boolean,
 | 
				
			||||||
  submitKey: SubmitKey.CtrlEnter as SubmitKey,
 | 
					  submitKey: SubmitKey.CtrlEnter as SubmitKey,
 | 
				
			||||||
  avatar: "1fae0",
 | 
					  avatar: "1f603",
 | 
				
			||||||
  theme: Theme.Auto as Theme,
 | 
					  theme: Theme.Auto as Theme,
 | 
				
			||||||
  tightBorder: false,
 | 
					  tightBorder: false,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -55,7 +57,7 @@ interface ChatSession {
 | 
				
			|||||||
  messages: Message[];
 | 
					  messages: Message[];
 | 
				
			||||||
  stat: ChatStat;
 | 
					  stat: ChatStat;
 | 
				
			||||||
  lastUpdate: string;
 | 
					  lastUpdate: string;
 | 
				
			||||||
  deleted?: boolean;
 | 
					  lastSummarizeIndex: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const DEFAULT_TOPIC = "新的聊天";
 | 
					const DEFAULT_TOPIC = "新的聊天";
 | 
				
			||||||
@@ -80,6 +82,7 @@ function createEmptySession(): ChatSession {
 | 
				
			|||||||
      charCount: 0,
 | 
					      charCount: 0,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    lastUpdate: createDate,
 | 
					    lastUpdate: createDate,
 | 
				
			||||||
 | 
					    lastSummarizeIndex: 0,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -93,7 +96,6 @@ interface ChatStore {
 | 
				
			|||||||
  currentSession: () => ChatSession;
 | 
					  currentSession: () => ChatSession;
 | 
				
			||||||
  onNewMessage: (message: Message) => void;
 | 
					  onNewMessage: (message: Message) => void;
 | 
				
			||||||
  onUserInput: (content: string) => Promise<void>;
 | 
					  onUserInput: (content: string) => Promise<void>;
 | 
				
			||||||
  onBotResponse: (message: Message) => void;
 | 
					 | 
				
			||||||
  summarizeSession: () => void;
 | 
					  summarizeSession: () => void;
 | 
				
			||||||
  updateStat: (message: Message) => void;
 | 
					  updateStat: (message: Message) => void;
 | 
				
			||||||
  updateCurrentSession: (updater: (session: ChatSession) => void) => void;
 | 
					  updateCurrentSession: (updater: (session: ChatSession) => void) => void;
 | 
				
			||||||
@@ -102,10 +104,12 @@ interface ChatStore {
 | 
				
			|||||||
    messageIndex: number,
 | 
					    messageIndex: number,
 | 
				
			||||||
    updater: (message?: Message) => void
 | 
					    updater: (message?: Message) => void
 | 
				
			||||||
  ) => void;
 | 
					  ) => void;
 | 
				
			||||||
 | 
					  getMessagesWithMemory: () => Message[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getConfig: () => ChatConfig;
 | 
					  getConfig: () => ChatConfig;
 | 
				
			||||||
  resetConfig: () => void;
 | 
					  resetConfig: () => void;
 | 
				
			||||||
  updateConfig: (updater: (config: ChatConfig) => void) => void;
 | 
					  updateConfig: (updater: (config: ChatConfig) => void) => void;
 | 
				
			||||||
 | 
					  clearAllData: () => void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const LOCAL_KEY = "chat-next-web-store";
 | 
					const LOCAL_KEY = "chat-next-web-store";
 | 
				
			||||||
@@ -186,9 +190,6 @@ export const useChatStore = create<ChatStore>()(
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      onNewMessage(message) {
 | 
					      onNewMessage(message) {
 | 
				
			||||||
        get().updateCurrentSession((session) => {
 | 
					 | 
				
			||||||
          session.messages.push(message);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        get().updateStat(message);
 | 
					        get().updateStat(message);
 | 
				
			||||||
        get().summarizeSession();
 | 
					        get().summarizeSession();
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@@ -200,9 +201,12 @@ export const useChatStore = create<ChatStore>()(
 | 
				
			|||||||
          date: new Date().toLocaleString(),
 | 
					          date: new Date().toLocaleString(),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        get().updateCurrentSession((session) => {
 | 
				
			||||||
 | 
					          session.messages.push(message);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // get last five messges
 | 
					        // get last five messges
 | 
				
			||||||
        const messages = get().currentSession().messages.concat(message);
 | 
					        const messages = get().currentSession().messages.concat(message);
 | 
				
			||||||
        get().onNewMessage(message);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const botMessage: Message = {
 | 
					        const botMessage: Message = {
 | 
				
			||||||
          content: "",
 | 
					          content: "",
 | 
				
			||||||
@@ -215,14 +219,13 @@ export const useChatStore = create<ChatStore>()(
 | 
				
			|||||||
          session.messages.push(botMessage);
 | 
					          session.messages.push(botMessage);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const fiveMessages = messages.slice(-5);
 | 
					        const recentMessages = get().getMessagesWithMemory()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        requestChatStream(fiveMessages, {
 | 
					        requestChatStream(recentMessages, {
 | 
				
			||||||
          onMessage(content, done) {
 | 
					          onMessage(content, done) {
 | 
				
			||||||
            if (done) {
 | 
					            if (done) {
 | 
				
			||||||
              botMessage.streaming = false;
 | 
					              botMessage.streaming = false;
 | 
				
			||||||
              get().updateStat(botMessage);
 | 
					              get().onNewMessage(botMessage)
 | 
				
			||||||
              get().summarizeSession();
 | 
					 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
              botMessage.content = content;
 | 
					              botMessage.content = content;
 | 
				
			||||||
              set(() => ({}));
 | 
					              set(() => ({}));
 | 
				
			||||||
@@ -237,6 +240,24 @@ export const useChatStore = create<ChatStore>()(
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      getMessagesWithMemory() {
 | 
				
			||||||
 | 
					        const session = get().currentSession()
 | 
				
			||||||
 | 
					        const config = get().config
 | 
				
			||||||
 | 
					        const recentMessages = session.messages.slice(-config.historyMessageCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const memoryPrompt: Message = {
 | 
				
			||||||
 | 
					          role: 'system',
 | 
				
			||||||
 | 
					          content: '这是你和用户的历史聊天总结:' + session.memoryPrompt,
 | 
				
			||||||
 | 
					          date: ''
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (session.memoryPrompt) {
 | 
				
			||||||
 | 
					          recentMessages.unshift(memoryPrompt)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return recentMessages
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      updateMessage(
 | 
					      updateMessage(
 | 
				
			||||||
        sessionIndex: number,
 | 
					        sessionIndex: number,
 | 
				
			||||||
        messageIndex: number,
 | 
					        messageIndex: number,
 | 
				
			||||||
@@ -249,10 +270,6 @@ export const useChatStore = create<ChatStore>()(
 | 
				
			|||||||
        set(() => ({ sessions }));
 | 
					        set(() => ({ sessions }));
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      onBotResponse(message) {
 | 
					 | 
				
			||||||
        get().onNewMessage(message);
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      summarizeSession() {
 | 
					      summarizeSession() {
 | 
				
			||||||
        const session = get().currentSession();
 | 
					        const session = get().currentSession();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -260,13 +277,37 @@ export const useChatStore = create<ChatStore>()(
 | 
				
			|||||||
          // should summarize topic
 | 
					          // should summarize topic
 | 
				
			||||||
          requestWithPrompt(
 | 
					          requestWithPrompt(
 | 
				
			||||||
            session.messages,
 | 
					            session.messages,
 | 
				
			||||||
            "直接返回这句话的简要主题,不要解释"
 | 
					            "直接返回这句话的简要主题,不要解释,如果没有主题,请直接返回“闲聊”"
 | 
				
			||||||
          ).then((res) => {
 | 
					          ).then((res) => {
 | 
				
			||||||
            get().updateCurrentSession(
 | 
					            get().updateCurrentSession(
 | 
				
			||||||
              (session) => (session.topic = trimTopic(res))
 | 
					              (session) => (session.topic = trimTopic(res))
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const messages = get().getMessagesWithMemory()
 | 
				
			||||||
 | 
					        const toBeSummarizedMsgs = messages.slice(session.lastSummarizeIndex)
 | 
				
			||||||
 | 
					        const historyMsgLength = session.memoryPrompt.length + toBeSummarizedMsgs.reduce((pre, cur) => pre + cur.content.length, 0)
 | 
				
			||||||
 | 
					        const lastSummarizeIndex = messages.length
 | 
				
			||||||
 | 
					        if (historyMsgLength > 500) {
 | 
				
			||||||
 | 
					          requestChatStream(toBeSummarizedMsgs.concat({
 | 
				
			||||||
 | 
					            role: 'system',
 | 
				
			||||||
 | 
					            content: '总结一下你和用户的对话,用作后续的上下文提示 prompt,控制在 50 字以内',
 | 
				
			||||||
 | 
					            date: ''
 | 
				
			||||||
 | 
					          }), {
 | 
				
			||||||
 | 
					            filterBot: false,
 | 
				
			||||||
 | 
					            onMessage(message, done) {
 | 
				
			||||||
 | 
					              session.memoryPrompt = message
 | 
				
			||||||
 | 
					              session.lastSummarizeIndex = lastSummarizeIndex
 | 
				
			||||||
 | 
					              if (done) {
 | 
				
			||||||
 | 
					                console.log('[Memory] ', session.memoryPrompt)
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            onError(error) {
 | 
				
			||||||
 | 
					              console.error('[Summarize] ', error)
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      updateStat(message) {
 | 
					      updateStat(message) {
 | 
				
			||||||
@@ -282,6 +323,13 @@ export const useChatStore = create<ChatStore>()(
 | 
				
			|||||||
        updater(sessions[index]);
 | 
					        updater(sessions[index]);
 | 
				
			||||||
        set(() => ({ sessions }));
 | 
					        set(() => ({ sessions }));
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      clearAllData() {
 | 
				
			||||||
 | 
					        if (confirm('确认清除所有聊天、设置数据?')) {
 | 
				
			||||||
 | 
					          localStorage.clear()
 | 
				
			||||||
 | 
					          location.reload()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
    }),
 | 
					    }),
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      name: LOCAL_KEY,
 | 
					      name: LOCAL_KEY,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -161,6 +161,17 @@ input[type="range"]::-webkit-slider-thumb:hover {
 | 
				
			|||||||
  width: 24px;
 | 
					  width: 24px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input[type="number"] {
 | 
				
			||||||
 | 
					  appearance: none;
 | 
				
			||||||
 | 
					  border-radius: 10px;
 | 
				
			||||||
 | 
					  border: var(--border-in-light);
 | 
				
			||||||
 | 
					  height: 32px;
 | 
				
			||||||
 | 
					  box-sizing: border-box;
 | 
				
			||||||
 | 
					  background: var(--white);
 | 
				
			||||||
 | 
					  color: var(--black);
 | 
				
			||||||
 | 
					  padding: 0 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
div.math {
 | 
					div.math {
 | 
				
			||||||
  overflow-x: auto;
 | 
					  overflow-x: auto;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user