diff --git a/web/containers/Checkbox/index.tsx b/web/containers/Checkbox/index.tsx index 12eed7199..db331e2f7 100644 --- a/web/containers/Checkbox/index.tsx +++ b/web/containers/Checkbox/index.tsx @@ -9,12 +9,20 @@ import { TooltipTrigger, } from '@janhq/uikit' -import { useAtomValue } from 'jotai' +import { useAtomValue, useSetAtom } from 'jotai' import { InfoIcon } from 'lucide-react' +import { useActiveModel } from '@/hooks/useActiveModel' import useUpdateModelParameters from '@/hooks/useUpdateModelParameters' -import { getActiveThreadIdAtom } from '@/helpers/atoms/Thread.atom' +import { getConfigurationsData } from '@/utils/componentSettings' +import { toSettingParams } from '@/utils/model_param' + +import { + engineParamsUpdateAtom, + getActiveThreadIdAtom, + getActiveThreadModelParamsAtom, +} from '@/helpers/atoms/Thread.atom' type Props = { name: string @@ -27,8 +35,24 @@ const Checkbox: React.FC = ({ name, title, checked, description }) => { const { updateModelParameter } = useUpdateModelParameters() const threadId = useAtomValue(getActiveThreadIdAtom) + const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom) + + const modelSettingParams = toSettingParams(activeModelParams) + + const engineParams = getConfigurationsData(modelSettingParams) + + const setEngineParamsUpdate = useSetAtom(engineParamsUpdateAtom) + + const { stopModel } = useActiveModel() + const onCheckedChange = (checked: boolean) => { if (!threadId) return + if (engineParams.some((x) => x.name.includes(name))) { + setEngineParamsUpdate(true) + stopModel() + } else { + setEngineParamsUpdate(false) + } updateModelParameter(threadId, name, checked) } diff --git a/web/containers/Loader/ModelReload.tsx b/web/containers/Loader/ModelReload.tsx new file mode 100644 index 000000000..a432927aa --- /dev/null +++ b/web/containers/Loader/ModelReload.tsx @@ -0,0 +1,49 @@ +import React, { useEffect, useState } from 'react' + +import { useActiveModel } from '@/hooks/useActiveModel' + +export default function ModelReload() { + const { stateModel } = useActiveModel() + const [loader, setLoader] = useState(0) + + // This is fake loader please fix this when we have realtime percentage when load model + useEffect(() => { + if (stateModel.loading) { + if (loader === 24) { + setTimeout(() => { + setLoader(loader + 1) + }, 250) + } else if (loader === 50) { + setTimeout(() => { + setLoader(loader + 1) + }, 250) + } else if (loader === 78) { + setTimeout(() => { + setLoader(loader + 1) + }, 250) + } else if (loader === 99) { + setLoader(99) + } else { + setLoader(loader + 1) + } + } else { + setLoader(0) + } + }, [stateModel.loading, loader]) + + if (!stateModel.loading) return null + + return ( +
+
+
+ + Reloading model {stateModel.model} + +
+
+ ) +} diff --git a/web/containers/ModelConfigInput/index.tsx b/web/containers/ModelConfigInput/index.tsx index ac66011bc..b7f9e5904 100644 --- a/web/containers/ModelConfigInput/index.tsx +++ b/web/containers/ModelConfigInput/index.tsx @@ -7,13 +7,22 @@ import { TooltipTrigger, } from '@janhq/uikit' -import { useAtomValue } from 'jotai' +import { useAtomValue, useSetAtom } from 'jotai' import { InfoIcon } from 'lucide-react' +import { useActiveModel } from '@/hooks/useActiveModel' import useUpdateModelParameters from '@/hooks/useUpdateModelParameters' -import { getActiveThreadIdAtom } from '@/helpers/atoms/Thread.atom' +import { getConfigurationsData } from '@/utils/componentSettings' + +import { toSettingParams } from '@/utils/model_param' + +import { + engineParamsUpdateAtom, + getActiveThreadIdAtom, + getActiveThreadModelParamsAtom, +} from '@/helpers/atoms/Thread.atom' type Props = { title: string @@ -33,9 +42,24 @@ const ModelConfigInput: React.FC = ({ const { updateModelParameter } = useUpdateModelParameters() const threadId = useAtomValue(getActiveThreadIdAtom) + const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom) + + const modelSettingParams = toSettingParams(activeModelParams) + + const engineParams = getConfigurationsData(modelSettingParams) + + const setEngineParamsUpdate = useSetAtom(engineParamsUpdateAtom) + + const { stopModel } = useActiveModel() + const onValueChanged = (e: React.ChangeEvent) => { if (!threadId) return - + if (engineParams.some((x) => x.name.includes(name))) { + setEngineParamsUpdate(true) + stopModel() + } else { + setEngineParamsUpdate(false) + } updateModelParameter(threadId, name, e.target.value) } diff --git a/web/containers/Providers/EventHandler.tsx b/web/containers/Providers/EventHandler.tsx index a828a02a1..2c81f4c23 100644 --- a/web/containers/Providers/EventHandler.tsx +++ b/web/containers/Providers/EventHandler.tsx @@ -68,10 +68,10 @@ export default function EventHandler({ children }: { children: ReactNode }) { setTimeout(async () => { setActiveModel(undefined) setStateModel({ state: 'start', loading: false, model: '' }) - toaster({ - title: 'Success!', - description: `Model ${model.id} has been stopped.`, - }) + // toaster({ + // title: 'Success!', + // description: `Model ${model.id} has been stopped.`, + // }) }, 500) } diff --git a/web/hooks/useSendChatMessage.ts b/web/hooks/useSendChatMessage.ts index cbfcadf3a..91b709a27 100644 --- a/web/hooks/useSendChatMessage.ts +++ b/web/hooks/useSendChatMessage.ts @@ -61,6 +61,9 @@ export default function useSendChatMessage() { const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom) const engineParamsUpdate = useAtomValue(engineParamsUpdateAtom) + const setEngineParamsUpdate = useSetAtom(engineParamsUpdateAtom) + + const [reloadModel, setReloadModel] = useState(false) useEffect(() => { modelRef.current = activeModel @@ -139,7 +142,7 @@ export default function useSendChatMessage() { return } - console.log(engineParamsUpdate) + if (engineParamsUpdate) setReloadModel(true) const activeThreadState = threadStates[activeThread.id] const runtimeParams = toRuntimeParams(activeModelParams) @@ -263,9 +266,13 @@ export default function useSendChatMessage() { } events.emit(EventName.OnMessageSent, messageRequest) + + setReloadModel(false) + setEngineParamsUpdate(false) } return { + reloadModel, sendChatMessage, resendChatMessage, queuedMessage, diff --git a/web/screens/Chat/index.tsx b/web/screens/Chat/index.tsx index 283440530..10aa88833 100644 --- a/web/screens/Chat/index.tsx +++ b/web/screens/Chat/index.tsx @@ -11,6 +11,7 @@ import { twMerge } from 'tailwind-merge' import LogoMark from '@/containers/Brand/Logo/Mark' +import ModelReload from '@/containers/Loader/ModelReload' import ModelStart from '@/containers/Loader/ModelStart' import { currentPromptAtom } from '@/containers/Providers/Jotai' @@ -33,6 +34,7 @@ import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom' import { activeThreadAtom, + engineParamsUpdateAtom, getActiveThreadIdAtom, waitingToSendMessage, } from '@/helpers/atoms/Thread.atom' @@ -49,7 +51,7 @@ const ChatScreen = () => { const [currentPrompt, setCurrentPrompt] = useAtom(currentPromptAtom) const activeThreadState = useAtomValue(activeThreadStateAtom) - const { sendChatMessage, queuedMessage } = useSendChatMessage() + const { sendChatMessage, queuedMessage, reloadModel } = useSendChatMessage() const isWaitingForResponse = activeThreadState?.waitingForResponse ?? false const isDisabledChatbox = currentPrompt.trim().length === 0 || isWaitingForResponse @@ -61,6 +63,7 @@ const ChatScreen = () => { const textareaRef = useRef(null) const modelRef = useRef(activeModel) + const engineParamsUpdate = useAtomValue(engineParamsUpdateAtom) useEffect(() => { modelRef.current = activeModel @@ -146,17 +149,20 @@ const ChatScreen = () => {
)} - + {!engineParamsUpdate && } - {/* {reloadModel && ( -
- - Model is reloading to apply new changes. - -
- )} */} + {reloadModel && ( + <> + +
+ + Model is reloading to apply new changes. + +
+ + )} - {queuedMessage && ( + {queuedMessage && !reloadModel && (
Message queued. It can be sent once the model has started