diff --git a/app/components/home.tsx b/app/components/home.tsx index 1215aac8..8fbe04a8 100644 --- a/app/components/home.tsx +++ b/app/components/home.tsx @@ -26,7 +26,7 @@ import CloseIcon from "../icons/close.svg"; import CopyIcon from "../icons/copy.svg"; import DownloadIcon from "../icons/download.svg"; -import { Message, SubmitKey, useChatStore, Theme } from "../store"; +import { Message, SubmitKey, useChatStore, ChatSession } from "../store"; import { Settings } from "./settings"; import { showModal } from "./ui-lib"; import { copyToClipboard, downloadAs, isIOS } from "../utils"; @@ -189,8 +189,8 @@ export function Chat(props: { showSideBar?: () => void }) { return (
-
-
{session.topic}
+
+
{session.topic}
与 ChatGPT 的 {session.messages.length} 条对话
@@ -210,7 +210,7 @@ export function Chat(props: { showSideBar?: () => void }) { bordered title="查看压缩后的历史 Prompt" onClick={() => { - showMemoryPrompt(session.memoryPrompt) + showMemoryPrompt(session) }} />
@@ -323,12 +323,12 @@ function exportMessages(messages: Message[], topic: string) { }) } -function showMemoryPrompt(prompt: string) { +function showMemoryPrompt(session: ChatSession) { showModal({ - title: "上下文记忆 Prompt", children:
-
{prompt}
+ title: `上下文记忆 Prompt (${session.lastSummarizeIndex} of ${session.messages.length})`, children:
+
{session.memoryPrompt || '无'}
, actions: [ - } bordered text="全部复制" onClick={() => copyToClipboard(prompt)} />, + } bordered text="全部复制" onClick={() => copyToClipboard(session.memoryPrompt)} />, ] }) } diff --git a/app/components/settings.tsx b/app/components/settings.tsx index 435df4c5..b88d3ff6 100644 --- a/app/components/settings.tsx +++ b/app/components/settings.tsx @@ -26,8 +26,8 @@ export function Settings(props: { closeSettings: () => void }) { return ( <>
-
-
设置
+
+
设置
设置选项
@@ -140,14 +140,14 @@ export function Settings(props: { closeSettings: () => void }) { -
最大上下文消息数
+
附带历史消息数
updateConfig( (config) => @@ -157,7 +157,6 @@ export function Settings(props: { closeSettings: () => void }) { >
-
历史消息压缩长度阈值 diff --git a/app/components/window.scss b/app/components/window.scss index c01b6fd0..c1727115 100644 --- a/app/components/window.scss +++ b/app/components/window.scss @@ -8,18 +8,22 @@ } .window-header-title { - font-size: 20px; - font-weight: bolder; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - display: block; - max-width: 50vw; -} + max-width: calc(100% - 100px); -.window-header-sub-title { - font-size: 14px; - margin-top: 5px; + .window-header-main-title { + font-size: 20px; + font-weight: bolder; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + display: block; + max-width: 50vw; + } + + .window-header-sub-title { + font-size: 14px; + margin-top: 5px; + } } .window-actions { @@ -28,4 +32,4 @@ .window-action-button { margin-left: 10px; -} +} \ No newline at end of file diff --git a/app/store.ts b/app/store.ts index 267e1e05..0edd51af 100644 --- a/app/store.ts +++ b/app/store.ts @@ -23,7 +23,7 @@ export enum Theme { Light = "light", } -interface ChatConfig { +export interface ChatConfig { maxToken?: number; historyMessageCount: number; // -1 means all compressMessageLengthThreshold: number; @@ -35,7 +35,7 @@ interface ChatConfig { } const DEFAULT_CONFIG: ChatConfig = { - historyMessageCount: 5, + historyMessageCount: 4, compressMessageLengthThreshold: 500, sendBotMessages: true as boolean, submitKey: SubmitKey.CtrlEnter as SubmitKey, @@ -44,13 +44,13 @@ const DEFAULT_CONFIG: ChatConfig = { tightBorder: false, }; -interface ChatStat { +export interface ChatStat { tokenCount: number; wordCount: number; charCount: number; } -interface ChatSession { +export interface ChatSession { id: number; topic: string; memoryPrompt: string; @@ -190,24 +190,20 @@ export const useChatStore = create()( }, onNewMessage(message) { + get().updateCurrentSession(session => { + session.lastUpdate = new Date().toLocaleString() + }) get().updateStat(message); get().summarizeSession(); }, async onUserInput(content) { - const message: Message = { + const userMessage: Message = { role: "user", content, date: new Date().toLocaleString(), }; - get().updateCurrentSession((session) => { - session.messages.push(message); - }); - - // get last five messges - const messages = get().currentSession().messages.concat(message); - const botMessage: Message = { content: "", role: "assistant", @@ -215,13 +211,18 @@ export const useChatStore = create()( streaming: true, }; + // get recent messages + const recentMessages = get().getMessagesWithMemory() + const sendMessages = recentMessages.concat(userMessage) + + // save user's and bot's message get().updateCurrentSession((session) => { + session.messages.push(userMessage); session.messages.push(botMessage); }); - const recentMessages = get().getMessagesWithMemory() - - requestChatStream(recentMessages, { + console.log('[User Input] ', sendMessages) + requestChatStream(sendMessages, { onMessage(content, done) { if (done) { botMessage.streaming = false; @@ -243,11 +244,12 @@ export const useChatStore = create()( getMessagesWithMemory() { const session = get().currentSession() const config = get().config - const recentMessages = session.messages.slice(-config.historyMessageCount); + const n = session.messages.length + const recentMessages = session.messages.slice(n - config.historyMessageCount); const memoryPrompt: Message = { role: 'system', - content: '这是你和用户的历史聊天总结:' + session.memoryPrompt, + content: '这是 ai 和用户的历史聊天总结作为前情提要:' + session.memoryPrompt, date: '' } @@ -285,22 +287,26 @@ export const useChatStore = create()( }); } + const config = get().config 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) { + const toBeSummarizedMsgs = get().getMessagesWithMemory() + const historyMsgLength = toBeSummarizedMsgs.reduce((pre, cur) => pre + cur.content.length, 0) + const lastSummarizeIndex = session.messages.length + + console.log('[Chat History] ', messages, historyMsgLength, config.compressMessageLengthThreshold) + + if (historyMsgLength > config.compressMessageLengthThreshold) { requestChatStream(toBeSummarizedMsgs.concat({ role: 'system', - content: '总结一下你和用户的对话,用作后续的上下文提示 prompt,控制在 50 字以内', + content: '总结一下 ai 和用户的对话,用作后续的上下文提示 prompt,控制在 100 字以内,你在回复时用 ai 自称', date: '' }), { filterBot: false, onMessage(message, done) { session.memoryPrompt = message - session.lastSummarizeIndex = lastSummarizeIndex if (done) { console.log('[Memory] ', session.memoryPrompt) + session.lastSummarizeIndex = lastSummarizeIndex } }, onError(error) {