fix: error when switching between threads (#736)
* fix: error when switching between threads * chore: fix model loading state
This commit is contained in:
parent
23c7586f15
commit
d74698a448
@ -25,6 +25,7 @@ let currentModelFile = null;
|
|||||||
*/
|
*/
|
||||||
interface InitModelResponse {
|
interface InitModelResponse {
|
||||||
error?: any;
|
error?: any;
|
||||||
|
modelFile?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +52,7 @@ function initModel(modelFile: string): Promise<InitModelResponse> {
|
|||||||
.then(validateModelStatus)
|
.then(validateModelStatus)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
log.error("error: " + JSON.stringify(err));
|
log.error("error: " + JSON.stringify(err));
|
||||||
return { error: err };
|
return { error: err, modelFile };
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,6 +31,8 @@ export function useActiveModel() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setActiveModel(undefined)
|
||||||
|
|
||||||
setStateModel({ state: 'start', loading: true, model: modelId })
|
setStateModel({ state: 'start', loading: true, model: modelId })
|
||||||
|
|
||||||
const model = downloadedModels.find((e) => e.id === modelId)
|
const model = downloadedModels.find((e) => e.id === modelId)
|
||||||
@ -52,7 +54,7 @@ export function useActiveModel() {
|
|||||||
console.debug('Init model: ', modelId)
|
console.debug('Init model: ', modelId)
|
||||||
const path = join('models', model.name, modelId)
|
const path = join('models', model.name, modelId)
|
||||||
const res = await initModel(path)
|
const res = await initModel(path)
|
||||||
if (res?.error && (!activeModel?.id || modelId === activeModel?.id)) {
|
if (res && res.error && res.modelFile === stateModel.model) {
|
||||||
const errorMessage = `${res.error}`
|
const errorMessage = `${res.error}`
|
||||||
alert(errorMessage)
|
alert(errorMessage)
|
||||||
setStateModel(() => ({
|
setStateModel(() => ({
|
||||||
@ -60,7 +62,6 @@ export function useActiveModel() {
|
|||||||
loading: false,
|
loading: false,
|
||||||
model: modelId,
|
model: modelId,
|
||||||
}))
|
}))
|
||||||
setActiveModel(undefined)
|
|
||||||
} else {
|
} else {
|
||||||
console.debug(
|
console.debug(
|
||||||
`Init model ${modelId} successfully!, take ${
|
`Init model ${modelId} successfully!, take ${
|
||||||
|
|||||||
@ -59,6 +59,7 @@ export default function useSendChatMessage() {
|
|||||||
...newMessage,
|
...newMessage,
|
||||||
messages: newMessage.messages?.slice(0, -1).concat([summaryMsg]),
|
messages: newMessage.messages?.slice(0, -1).concat([summaryMsg]),
|
||||||
})
|
})
|
||||||
|
.catch(console.error)
|
||||||
if (
|
if (
|
||||||
currentConvo &&
|
currentConvo &&
|
||||||
currentConvo.id === newMessage.threadId &&
|
currentConvo.id === newMessage.threadId &&
|
||||||
|
|||||||
@ -31,11 +31,12 @@ const ChatInstruction = () => {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto mb-20 flex flex-col space-y-2">
|
<div className="mx-auto mb-20 flex flex-col space-y-2">
|
||||||
|
{!isSettingInstruction && activeConvoId && (
|
||||||
|
<>
|
||||||
<p>
|
<p>
|
||||||
What does this Assistant do? How does it behave? What should it avoid
|
What does this Assistant do? How does it behave? What should it
|
||||||
doing?
|
avoid doing?
|
||||||
</p>
|
</p>
|
||||||
{!isSettingInstruction && (
|
|
||||||
<Button
|
<Button
|
||||||
themes={'outline'}
|
themes={'outline'}
|
||||||
className="w-32"
|
className="w-32"
|
||||||
@ -43,6 +44,7 @@ const ChatInstruction = () => {
|
|||||||
>
|
>
|
||||||
Give Instruction
|
Give Instruction
|
||||||
</Button>
|
</Button>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{isSettingInstruction && (
|
{isSettingInstruction && (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { twMerge } from 'tailwind-merge'
|
|||||||
|
|
||||||
import { useActiveModel } from '@/hooks/useActiveModel'
|
import { useActiveModel } from '@/hooks/useActiveModel'
|
||||||
import { useCreateConversation } from '@/hooks/useCreateConversation'
|
import { useCreateConversation } from '@/hooks/useCreateConversation'
|
||||||
import { useGetDownloadedModels } from '@/hooks/useGetDownloadedModels'
|
|
||||||
import useGetUserConversations from '@/hooks/useGetUserConversations'
|
import useGetUserConversations from '@/hooks/useGetUserConversations'
|
||||||
|
|
||||||
import { displayDate } from '@/utils/datetime'
|
import { displayDate } from '@/utils/datetime'
|
||||||
@ -27,11 +26,10 @@ export default function HistoryList() {
|
|||||||
const conversations = useAtomValue(userConversationsAtom)
|
const conversations = useAtomValue(userConversationsAtom)
|
||||||
const threadStates = useAtomValue(conversationStatesAtom)
|
const threadStates = useAtomValue(conversationStatesAtom)
|
||||||
const { getUserConversations } = useGetUserConversations()
|
const { getUserConversations } = useGetUserConversations()
|
||||||
const { activeModel, startModel } = useActiveModel()
|
const { activeModel } = useActiveModel()
|
||||||
const { requestCreateConvo } = useCreateConversation()
|
const { requestCreateConvo } = useCreateConversation()
|
||||||
const activeConvoId = useAtomValue(getActiveConvoIdAtom)
|
const activeConvoId = useAtomValue(getActiveConvoIdAtom)
|
||||||
const setActiveConvoId = useSetAtom(setActiveConvoIdAtom)
|
const setActiveConvoId = useSetAtom(setActiveConvoIdAtom)
|
||||||
const { downloadedModels } = useGetDownloadedModels()
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getUserConversations()
|
getUserConversations()
|
||||||
@ -48,14 +46,6 @@ export default function HistoryList() {
|
|||||||
console.debug('modelId is undefined')
|
console.debug('modelId is undefined')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const model = downloadedModels.find((e) => e.id === convo.modelId)
|
|
||||||
if (convo == null) {
|
|
||||||
console.debug('modelId is undefined')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (model != null) {
|
|
||||||
startModel(model.id)
|
|
||||||
}
|
|
||||||
if (activeConvoId !== convo.id) {
|
if (activeConvoId !== convo.id) {
|
||||||
setActiveConvoId(convo.id)
|
setActiveConvoId(convo.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,9 +10,12 @@ import { twMerge } from 'tailwind-merge'
|
|||||||
|
|
||||||
import { currentPromptAtom } from '@/containers/Providers/Jotai'
|
import { currentPromptAtom } from '@/containers/Providers/Jotai'
|
||||||
|
|
||||||
import { FeatureToggleContext } from '@/context/FeatureToggle'
|
|
||||||
import ShortCut from '@/containers/Shortcut'
|
import ShortCut from '@/containers/Shortcut'
|
||||||
|
|
||||||
|
import { toaster } from '@/containers/Toast'
|
||||||
|
|
||||||
|
import { FeatureToggleContext } from '@/context/FeatureToggle'
|
||||||
|
|
||||||
import { MainViewState } from '@/constants/screens'
|
import { MainViewState } from '@/constants/screens'
|
||||||
|
|
||||||
import { useActiveModel } from '@/hooks/useActiveModel'
|
import { useActiveModel } from '@/hooks/useActiveModel'
|
||||||
@ -64,6 +67,12 @@ const ChatScreen = () => {
|
|||||||
const { experimentalFeatureEnabed } = useContext(FeatureToggleContext)
|
const { experimentalFeatureEnabed } = useContext(FeatureToggleContext)
|
||||||
|
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
||||||
|
const { startModel } = useActiveModel()
|
||||||
|
const modelRef = useRef(activeModel)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
modelRef.current = activeModel
|
||||||
|
}, [activeModel])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getUserConversations()
|
getUserConversations()
|
||||||
@ -81,6 +90,24 @@ const ChatScreen = () => {
|
|||||||
}, [currentConvo, downloadedModels])
|
}, [currentConvo, downloadedModels])
|
||||||
|
|
||||||
const handleSendMessage = async () => {
|
const handleSendMessage = async () => {
|
||||||
|
if (!activeModel || activeModel.id !== currentConvo?.modelId) {
|
||||||
|
const model = downloadedModels.find((e) => e.id === currentConvo?.modelId)
|
||||||
|
|
||||||
|
// Model is available to start
|
||||||
|
if (model != null) {
|
||||||
|
toaster({
|
||||||
|
title: 'Message queued.',
|
||||||
|
description: 'It will be sent once the model is done loading.',
|
||||||
|
})
|
||||||
|
startModel(model.id).then(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (modelRef?.current?.id === currentConvo?.modelId)
|
||||||
|
sendChatMessage()
|
||||||
|
}, 300)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
if (activeConversationId) {
|
if (activeConversationId) {
|
||||||
sendChatMessage()
|
sendChatMessage()
|
||||||
} else {
|
} else {
|
||||||
@ -206,11 +233,7 @@ const ChatScreen = () => {
|
|||||||
ref={textareaRef}
|
ref={textareaRef}
|
||||||
onKeyDown={(e) => handleKeyDown(e)}
|
onKeyDown={(e) => handleKeyDown(e)}
|
||||||
placeholder="Type your message ..."
|
placeholder="Type your message ..."
|
||||||
disabled={
|
disabled={stateModel.loading || !currentConvo}
|
||||||
!activeModel ||
|
|
||||||
stateModel.loading ||
|
|
||||||
activeModel.id !== currentConvo?.modelId
|
|
||||||
}
|
|
||||||
value={currentPrompt}
|
value={currentPrompt}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
handleMessageChange(e)
|
handleMessageChange(e)
|
||||||
@ -218,8 +241,8 @@ const ChatScreen = () => {
|
|||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
size="lg"
|
size="lg"
|
||||||
disabled={!activeModel || disabled || stateModel.loading}
|
disabled={disabled || stateModel.loading || !currentConvo}
|
||||||
themes={!activeModel ? 'secondary' : 'primary'}
|
themes={'primary'}
|
||||||
onClick={handleSendMessage}
|
onClick={handleSendMessage}
|
||||||
>
|
>
|
||||||
Send
|
Send
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user