上下文中包含机器人消息
diff --git a/app/components/ui-lib.module.scss b/app/components/ui-lib.module.scss
index a86b4b9e..1a378141 100644
--- a/app/components/ui-lib.module.scss
+++ b/app/components/ui-lib.module.scss
@@ -90,7 +90,7 @@
}
.modal-content {
- height: 40vh;
+ max-height: 40vh;
padding: var(--modal-padding);
overflow: auto;
}
@@ -118,7 +118,7 @@
width: 90vw;
.modal-content {
- height: 50vh;
+ max-height: 50vh;
}
}
}
\ No newline at end of file
diff --git a/app/icons/clear.svg b/app/icons/clear.svg
new file mode 100644
index 00000000..f0430fc4
--- /dev/null
+++ b/app/icons/clear.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/store.ts b/app/store.ts
index 2124b23d..267e1e05 100644
--- a/app/store.ts
+++ b/app/store.ts
@@ -26,6 +26,7 @@ export enum Theme {
interface ChatConfig {
maxToken?: number;
historyMessageCount: number; // -1 means all
+ compressMessageLengthThreshold: number;
sendBotMessages: boolean; // send bot's message or not
submitKey: SubmitKey;
avatar: string;
@@ -35,9 +36,10 @@ interface ChatConfig {
const DEFAULT_CONFIG: ChatConfig = {
historyMessageCount: 5,
- sendBotMessages: false as boolean,
+ compressMessageLengthThreshold: 500,
+ sendBotMessages: true as boolean,
submitKey: SubmitKey.CtrlEnter as SubmitKey,
- avatar: "1fae0",
+ avatar: "1f603",
theme: Theme.Auto as Theme,
tightBorder: false,
};
@@ -55,7 +57,7 @@ interface ChatSession {
messages: Message[];
stat: ChatStat;
lastUpdate: string;
- deleted?: boolean;
+ lastSummarizeIndex: number;
}
const DEFAULT_TOPIC = "新的聊天";
@@ -80,6 +82,7 @@ function createEmptySession(): ChatSession {
charCount: 0,
},
lastUpdate: createDate,
+ lastSummarizeIndex: 0,
};
}
@@ -93,7 +96,6 @@ interface ChatStore {
currentSession: () => ChatSession;
onNewMessage: (message: Message) => void;
onUserInput: (content: string) => Promise
;
- onBotResponse: (message: Message) => void;
summarizeSession: () => void;
updateStat: (message: Message) => void;
updateCurrentSession: (updater: (session: ChatSession) => void) => void;
@@ -102,10 +104,12 @@ interface ChatStore {
messageIndex: number,
updater: (message?: Message) => void
) => void;
+ getMessagesWithMemory: () => Message[];
getConfig: () => ChatConfig;
resetConfig: () => void;
updateConfig: (updater: (config: ChatConfig) => void) => void;
+ clearAllData: () => void;
}
const LOCAL_KEY = "chat-next-web-store";
@@ -186,9 +190,6 @@ export const useChatStore = create()(
},
onNewMessage(message) {
- get().updateCurrentSession((session) => {
- session.messages.push(message);
- });
get().updateStat(message);
get().summarizeSession();
},
@@ -200,9 +201,12 @@ export const useChatStore = create()(
date: new Date().toLocaleString(),
};
+ get().updateCurrentSession((session) => {
+ session.messages.push(message);
+ });
+
// get last five messges
const messages = get().currentSession().messages.concat(message);
- get().onNewMessage(message);
const botMessage: Message = {
content: "",
@@ -215,14 +219,13 @@ export const useChatStore = create()(
session.messages.push(botMessage);
});
- const fiveMessages = messages.slice(-5);
+ const recentMessages = get().getMessagesWithMemory()
- requestChatStream(fiveMessages, {
+ requestChatStream(recentMessages, {
onMessage(content, done) {
if (done) {
botMessage.streaming = false;
- get().updateStat(botMessage);
- get().summarizeSession();
+ get().onNewMessage(botMessage)
} else {
botMessage.content = content;
set(() => ({}));
@@ -237,6 +240,24 @@ export const useChatStore = create()(
});
},
+ 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(
sessionIndex: number,
messageIndex: number,
@@ -249,10 +270,6 @@ export const useChatStore = create()(
set(() => ({ sessions }));
},
- onBotResponse(message) {
- get().onNewMessage(message);
- },
-
summarizeSession() {
const session = get().currentSession();
@@ -260,13 +277,37 @@ export const useChatStore = create()(
// should summarize topic
requestWithPrompt(
session.messages,
- "直接返回这句话的简要主题,不要解释"
+ "直接返回这句话的简要主题,不要解释,如果没有主题,请直接返回“闲聊”"
).then((res) => {
get().updateCurrentSession(
(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) {
@@ -282,6 +323,13 @@ export const useChatStore = create()(
updater(sessions[index]);
set(() => ({ sessions }));
},
+
+ clearAllData() {
+ if (confirm('确认清除所有聊天、设置数据?')) {
+ localStorage.clear()
+ location.reload()
+ }
+ },
}),
{
name: LOCAL_KEY,
diff --git a/app/styles/globals.scss b/app/styles/globals.scss
index 4d72994b..af0b092b 100644
--- a/app/styles/globals.scss
+++ b/app/styles/globals.scss
@@ -161,6 +161,17 @@ input[type="range"]::-webkit-slider-thumb:hover {
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 {
overflow-x: auto;
}