From 4cdb2f0fa37c9e97dd4dafe490955a57a5940370 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Sat, 22 Apr 2023 01:13:23 +0800 Subject: [PATCH] feat: session-level model config --- app/components/home.module.scss | 4 +- app/components/home.tsx | 7 +- app/components/settings.module.scss | 14 -- app/components/settings.tsx | 271 ++++++++++++++-------------- app/components/ui-lib.tsx | 29 ++- app/store/app.ts | 11 +- app/store/config.ts | 4 +- app/styles/globals.scss | 14 ++ 8 files changed, 187 insertions(+), 167 deletions(-) diff --git a/app/components/home.module.scss b/app/components/home.module.scss index b0b44d9c..7476c08f 100644 --- a/app/components/home.module.scss +++ b/app/components/home.module.scss @@ -138,9 +138,7 @@ .sidebar-body { flex: 1; overflow: auto; -} - -.chat-list { + overflow-x: hidden; } .chat-item { diff --git a/app/components/home.tsx b/app/components/home.tsx index 32334028..851dba1a 100644 --- a/app/components/home.tsx +++ b/app/components/home.tsx @@ -2,7 +2,7 @@ require("../polyfill"); -import { useState, useEffect, StyleHTMLAttributes } from "react"; +import { useState, useEffect } from "react"; import styles from "./home.module.scss"; @@ -10,7 +10,6 @@ import BotIcon from "../icons/bot.svg"; import LoadingIcon from "../icons/three-dots.svg"; import { getCSSVar, useMobileScreen } from "../utils"; -import { Chat } from "./chat"; import dynamic from "next/dynamic"; import { Path } from "../constant"; @@ -38,6 +37,10 @@ const Settings = dynamic(async () => (await import("./settings")).Settings, { loading: () => , }); +const Chat = dynamic(async () => (await import("./chat")).Chat, { + loading: () => , +}); + export function useSwitchTheme() { const config = useAppConfig(); diff --git a/app/components/settings.module.scss b/app/components/settings.module.scss index b7f09558..9df76d32 100644 --- a/app/components/settings.module.scss +++ b/app/components/settings.module.scss @@ -19,20 +19,6 @@ cursor: pointer; } -.password-input-container { - max-width: 50%; - display: flex; - justify-content: flex-end; - - .password-eye { - margin-right: 4px; - } - - .password-input { - min-width: 80%; - } -} - .user-prompt-modal { min-height: 40vh; diff --git a/app/components/settings.tsx b/app/components/settings.tsx index ae412870..1b2b4c7f 100644 --- a/app/components/settings.tsx +++ b/app/components/settings.tsx @@ -9,10 +9,7 @@ import CloseIcon from "../icons/close.svg"; import CopyIcon from "../icons/copy.svg"; import ClearIcon from "../icons/clear.svg"; import EditIcon from "../icons/edit.svg"; -import EyeIcon from "../icons/eye.svg"; -import EyeOffIcon from "../icons/eye-off.svg"; - -import { Input, List, ListItem, Modal, Popover } from "./ui-lib"; +import { Input, List, ListItem, Modal, PasswordInput, Popover } from "./ui-lib"; import { IconButton } from "./button"; import { @@ -24,6 +21,8 @@ import { useAccessStore, ModalConfigValidator, useAppConfig, + ChatConfig, + ModelConfig, } from "../store"; import { Avatar } from "./chat"; @@ -155,26 +154,127 @@ function SettingItem(props: { ); } -function PasswordInput(props: HTMLProps) { - const [visible, setVisible] = useState(false); - - function changeVisibility() { - setVisible(!visible); - } - +export function ModelConfigList(props: { + modelConfig: ModelConfig; + updateConfig: (updater: (config: ModelConfig) => void) => void; +}) { return ( -
- : } - onClick={changeVisibility} - className={styles["password-eye"]} - /> - -
+ <> + + + + + { + props.updateConfig( + (config) => + (config.temperature = ModalConfigValidator.temperature( + e.currentTarget.valueAsNumber, + )), + ); + }} + > + + + + props.updateConfig( + (config) => + (config.max_tokens = ModalConfigValidator.max_tokens( + e.currentTarget.valueAsNumber, + )), + ) + } + > + + + { + props.updateConfig( + (config) => + (config.presence_penalty = + ModalConfigValidator.presence_penalty( + e.currentTarget.valueAsNumber, + )), + ); + }} + > + + + + + props.updateConfig( + (config) => (config.historyMessageCount = e.target.valueAsNumber), + ) + } + > + + + + + props.updateConfig( + (config) => + (config.compressMessageLengthThreshold = + e.currentTarget.valueAsNumber), + ) + } + > + + ); } @@ -505,44 +605,6 @@ export function Settings() { /> )} - - - - updateConfig( - (config) => - (config.historyMessageCount = e.target.valueAsNumber), - ) - } - > - - - - - updateConfig( - (config) => - (config.compressMessageLengthThreshold = - e.currentTarget.valueAsNumber), - ) - } - > - @@ -578,85 +640,14 @@ export function Settings() { - - - - - { - updateConfig( - (config) => - (config.modelConfig.temperature = - ModalConfigValidator.temperature( - e.currentTarget.valueAsNumber, - )), - ); - }} - > - - - - updateConfig( - (config) => - (config.modelConfig.max_tokens = - ModalConfigValidator.max_tokens( - e.currentTarget.valueAsNumber, - )), - ) - } - > - - - { - updateConfig( - (config) => - (config.modelConfig.presence_penalty = - ModalConfigValidator.presence_penalty( - e.currentTarget.valueAsNumber, - )), - ); - }} - > - + { + const modelConfig = { ...config.modelConfig }; + upater(modelConfig); + config.update((config) => (config.modelConfig = modelConfig)); + }} + /> {shouldShowPromptModal && ( diff --git a/app/components/ui-lib.tsx b/app/components/ui-lib.tsx index ffc05cf8..8e04db3a 100644 --- a/app/components/ui-lib.tsx +++ b/app/components/ui-lib.tsx @@ -1,8 +1,12 @@ import styles from "./ui-lib.module.scss"; import LoadingIcon from "../icons/three-dots.svg"; import CloseIcon from "../icons/close.svg"; +import EyeIcon from "../icons/eye.svg"; +import EyeOffIcon from "../icons/eye-off.svg"; + import { createRoot } from "react-dom/client"; -import React, { useEffect } from "react"; +import React, { HTMLProps, useEffect, useState } from "react"; +import { IconButton } from "./button"; export function Popover(props: { children: JSX.Element; @@ -190,3 +194,26 @@ export function Input(props: InputProps) { > ); } + +export function PasswordInput(props: HTMLProps) { + const [visible, setVisible] = useState(false); + + function changeVisibility() { + setVisible(!visible); + } + + return ( +
+ : } + onClick={changeVisibility} + className={"password-eye"} + /> + +
+ ); +} diff --git a/app/store/app.ts b/app/store/app.ts index 2294130a..652e26f5 100644 --- a/app/store/app.ts +++ b/app/store/app.ts @@ -334,14 +334,14 @@ export const useChatStore = create()( // get short term and unmemoried long term memory const shortTermMemoryMessageIndex = Math.max( 0, - n - config.historyMessageCount, + n - config.modelConfig.historyMessageCount, ); const longTermMemoryMessageIndex = session.lastSummarizeIndex; const oldestIndex = Math.max( shortTermMemoryMessageIndex, longTermMemoryMessageIndex, ); - const threshold = config.compressMessageLengthThreshold; + const threshold = config.modelConfig.compressMessageLengthThreshold; // get recent messages as many as possible const reversedRecentMessages = []; @@ -410,7 +410,7 @@ export const useChatStore = create()( if (historyMsgLength > config?.modelConfig?.max_tokens ?? 4000) { const n = toBeSummarizedMsgs.length; toBeSummarizedMsgs = toBeSummarizedMsgs.slice( - Math.max(0, n - config.historyMessageCount), + Math.max(0, n - config.modelConfig.historyMessageCount), ); } @@ -423,11 +423,12 @@ export const useChatStore = create()( "[Chat History] ", toBeSummarizedMsgs, historyMsgLength, - config.compressMessageLengthThreshold, + config.modelConfig.compressMessageLengthThreshold, ); if ( - historyMsgLength > config.compressMessageLengthThreshold && + historyMsgLength > + config.modelConfig.compressMessageLengthThreshold && session.sendMemory ) { requestChatStream( diff --git a/app/store/config.ts b/app/store/config.ts index 346f38da..93733409 100644 --- a/app/store/config.ts +++ b/app/store/config.ts @@ -16,8 +16,6 @@ export enum Theme { } const DEFAULT_CONFIG = { - historyMessageCount: 4, - compressMessageLengthThreshold: 1000, sendBotMessages: true as boolean, submitKey: SubmitKey.CtrlEnter as SubmitKey, avatar: "1f603", @@ -34,6 +32,8 @@ const DEFAULT_CONFIG = { temperature: 1, max_tokens: 2000, presence_penalty: 0, + historyMessageCount: 4, + compressMessageLengthThreshold: 1000, }, }; diff --git a/app/styles/globals.scss b/app/styles/globals.scss index 37c66228..5815d741 100644 --- a/app/styles/globals.scss +++ b/app/styles/globals.scss @@ -311,3 +311,17 @@ pre { overflow: auto; } } + +.password-input-container { + max-width: 50%; + display: flex; + justify-content: flex-end; + + .password-eye { + margin-right: 4px; + } + + .password-input { + min-width: 80%; + } +}