fix: render performance while generating messages (#4328)
This commit is contained in:
parent
e8e5c8c5f4
commit
b28cac7083
@ -18,7 +18,7 @@ import {
|
|||||||
extractInferenceParams,
|
extractInferenceParams,
|
||||||
ModelExtension,
|
ModelExtension,
|
||||||
} from '@janhq/core'
|
} from '@janhq/core'
|
||||||
import { useAtomValue, useSetAtom } from 'jotai'
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
|
||||||
import { ulid } from 'ulidx'
|
import { ulid } from 'ulidx'
|
||||||
|
|
||||||
import { activeModelAtom, stateModelAtom } from '@/hooks/useActiveModel'
|
import { activeModelAtom, stateModelAtom } from '@/hooks/useActiveModel'
|
||||||
@ -32,6 +32,7 @@ import {
|
|||||||
updateMessageAtom,
|
updateMessageAtom,
|
||||||
tokenSpeedAtom,
|
tokenSpeedAtom,
|
||||||
deleteMessageAtom,
|
deleteMessageAtom,
|
||||||
|
subscribedGeneratingMessageAtom,
|
||||||
} from '@/helpers/atoms/ChatMessage.atom'
|
} from '@/helpers/atoms/ChatMessage.atom'
|
||||||
import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'
|
import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'
|
||||||
import {
|
import {
|
||||||
@ -40,6 +41,7 @@ import {
|
|||||||
isGeneratingResponseAtom,
|
isGeneratingResponseAtom,
|
||||||
updateThreadAtom,
|
updateThreadAtom,
|
||||||
getActiveThreadModelParamsAtom,
|
getActiveThreadModelParamsAtom,
|
||||||
|
activeThreadAtom,
|
||||||
} from '@/helpers/atoms/Thread.atom'
|
} from '@/helpers/atoms/Thread.atom'
|
||||||
|
|
||||||
const maxWordForThreadTitle = 10
|
const maxWordForThreadTitle = 10
|
||||||
@ -54,6 +56,10 @@ export default function ModelHandler() {
|
|||||||
const activeModel = useAtomValue(activeModelAtom)
|
const activeModel = useAtomValue(activeModelAtom)
|
||||||
const setActiveModel = useSetAtom(activeModelAtom)
|
const setActiveModel = useSetAtom(activeModelAtom)
|
||||||
const setStateModel = useSetAtom(stateModelAtom)
|
const setStateModel = useSetAtom(stateModelAtom)
|
||||||
|
const [subscribedGeneratingMessage, setSubscribedGeneratingMessage] = useAtom(
|
||||||
|
subscribedGeneratingMessageAtom
|
||||||
|
)
|
||||||
|
const activeThread = useAtomValue(activeThreadAtom)
|
||||||
|
|
||||||
const updateThreadWaiting = useSetAtom(updateThreadWaitingForResponseAtom)
|
const updateThreadWaiting = useSetAtom(updateThreadWaitingForResponseAtom)
|
||||||
const threads = useAtomValue(threadsAtom)
|
const threads = useAtomValue(threadsAtom)
|
||||||
@ -62,11 +68,17 @@ export default function ModelHandler() {
|
|||||||
const setIsGeneratingResponse = useSetAtom(isGeneratingResponseAtom)
|
const setIsGeneratingResponse = useSetAtom(isGeneratingResponseAtom)
|
||||||
const updateThread = useSetAtom(updateThreadAtom)
|
const updateThread = useSetAtom(updateThreadAtom)
|
||||||
const messagesRef = useRef(messages)
|
const messagesRef = useRef(messages)
|
||||||
|
const messageGenerationSubscriber = useRef(subscribedGeneratingMessage)
|
||||||
const activeModelRef = useRef(activeModel)
|
const activeModelRef = useRef(activeModel)
|
||||||
|
const activeThreadRef = useRef(activeThread)
|
||||||
const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom)
|
const activeModelParams = useAtomValue(getActiveThreadModelParamsAtom)
|
||||||
const activeModelParamsRef = useRef(activeModelParams)
|
const activeModelParamsRef = useRef(activeModelParams)
|
||||||
const setTokenSpeed = useSetAtom(tokenSpeedAtom)
|
const setTokenSpeed = useSetAtom(tokenSpeedAtom)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
activeThreadRef.current = activeThread
|
||||||
|
}, [activeThread])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
threadsRef.current = threads
|
threadsRef.current = threads
|
||||||
}, [threads])
|
}, [threads])
|
||||||
@ -87,6 +99,10 @@ export default function ModelHandler() {
|
|||||||
activeModelParamsRef.current = activeModelParams
|
activeModelParamsRef.current = activeModelParams
|
||||||
}, [activeModelParams])
|
}, [activeModelParams])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
messageGenerationSubscriber.current = subscribedGeneratingMessage
|
||||||
|
}, [subscribedGeneratingMessage])
|
||||||
|
|
||||||
const onNewMessageResponse = useCallback(
|
const onNewMessageResponse = useCallback(
|
||||||
async (message: ThreadMessage) => {
|
async (message: ThreadMessage) => {
|
||||||
if (message.type === MessageRequestType.Thread) {
|
if (message.type === MessageRequestType.Thread) {
|
||||||
@ -179,12 +195,19 @@ export default function ModelHandler() {
|
|||||||
|
|
||||||
const updateThreadMessage = useCallback(
|
const updateThreadMessage = useCallback(
|
||||||
(message: ThreadMessage) => {
|
(message: ThreadMessage) => {
|
||||||
updateMessage(
|
if (
|
||||||
message.id,
|
messageGenerationSubscriber.current &&
|
||||||
message.thread_id,
|
message.thread_id === activeThreadRef.current?.id &&
|
||||||
message.content,
|
!messageGenerationSubscriber.current!.thread_id
|
||||||
message.status
|
) {
|
||||||
)
|
updateMessage(
|
||||||
|
message.id,
|
||||||
|
message.thread_id,
|
||||||
|
message.content,
|
||||||
|
message.status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (message.status === MessageStatus.Pending) {
|
if (message.status === MessageStatus.Pending) {
|
||||||
if (message.content.length) {
|
if (message.content.length) {
|
||||||
setIsGeneratingResponse(false)
|
setIsGeneratingResponse(false)
|
||||||
|
|||||||
@ -35,6 +35,13 @@ export const chatMessages = atom(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store subscribed generating message thread
|
||||||
|
*/
|
||||||
|
export const subscribedGeneratingMessageAtom = atom<{
|
||||||
|
thread_id?: string
|
||||||
|
}>({})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the status of the messages load for each thread
|
* Stores the status of the messages load for each thread
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
import { ExtensionTypeEnum, Thread, ConversationalExtension } from '@janhq/core'
|
import { ExtensionTypeEnum, Thread, ConversationalExtension } from '@janhq/core'
|
||||||
|
|
||||||
import { useSetAtom } from 'jotai'
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
|
||||||
|
|
||||||
import { extensionManager } from '@/extension'
|
import { extensionManager } from '@/extension'
|
||||||
import { activeAssistantAtom } from '@/helpers/atoms/Assistant.atom'
|
import { activeAssistantAtom } from '@/helpers/atoms/Assistant.atom'
|
||||||
import { setConvoMessagesAtom } from '@/helpers/atoms/ChatMessage.atom'
|
|
||||||
import {
|
import {
|
||||||
|
setConvoMessagesAtom,
|
||||||
|
subscribedGeneratingMessageAtom,
|
||||||
|
} from '@/helpers/atoms/ChatMessage.atom'
|
||||||
|
import {
|
||||||
|
getActiveThreadIdAtom,
|
||||||
setActiveThreadIdAtom,
|
setActiveThreadIdAtom,
|
||||||
setThreadModelParamsAtom,
|
setThreadModelParamsAtom,
|
||||||
} from '@/helpers/atoms/Thread.atom'
|
} from '@/helpers/atoms/Thread.atom'
|
||||||
@ -13,14 +17,18 @@ import { ModelParams } from '@/types/model'
|
|||||||
|
|
||||||
export default function useSetActiveThread() {
|
export default function useSetActiveThread() {
|
||||||
const setActiveThreadId = useSetAtom(setActiveThreadIdAtom)
|
const setActiveThreadId = useSetAtom(setActiveThreadIdAtom)
|
||||||
const setThreadMessage = useSetAtom(setConvoMessagesAtom)
|
const activeThreadId = useAtomValue(getActiveThreadIdAtom)
|
||||||
|
const setThreadMessages = useSetAtom(setConvoMessagesAtom)
|
||||||
const setThreadModelParams = useSetAtom(setThreadModelParamsAtom)
|
const setThreadModelParams = useSetAtom(setThreadModelParamsAtom)
|
||||||
const setActiveAssistant = useSetAtom(activeAssistantAtom)
|
const setActiveAssistant = useSetAtom(activeAssistantAtom)
|
||||||
|
const [messageSubscriber, setMessageSubscriber] = useAtom(
|
||||||
|
subscribedGeneratingMessageAtom
|
||||||
|
)
|
||||||
|
|
||||||
const setActiveThread = async (thread: Thread) => {
|
const setActiveThread = async (thread: Thread) => {
|
||||||
if (!thread?.id) return
|
if (!thread?.id || activeThreadId === thread.id) return
|
||||||
|
|
||||||
setActiveThreadId(thread?.id)
|
setActiveThreadId(thread.id)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const assistantInfo = await getThreadAssistant(thread.id)
|
const assistantInfo = await getThreadAssistant(thread.id)
|
||||||
@ -32,7 +40,8 @@ export default function useSetActiveThread() {
|
|||||||
...assistantInfo?.model?.settings,
|
...assistantInfo?.model?.settings,
|
||||||
}
|
}
|
||||||
setThreadModelParams(thread?.id, modelParams)
|
setThreadModelParams(thread?.id, modelParams)
|
||||||
setThreadMessage(thread.id, messages)
|
setThreadMessages(thread.id, messages)
|
||||||
|
if (messageSubscriber.thread_id !== thread.id) setMessageSubscriber({})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { forwardRef, useEffect, useState } from 'react'
|
import React, { forwardRef, useEffect, useRef, useState } from 'react'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
events,
|
events,
|
||||||
@ -8,10 +8,14 @@ import {
|
|||||||
ThreadMessage,
|
ThreadMessage,
|
||||||
} from '@janhq/core'
|
} from '@janhq/core'
|
||||||
|
|
||||||
|
import { useAtom } from 'jotai'
|
||||||
|
|
||||||
import ErrorMessage from '@/containers/ErrorMessage'
|
import ErrorMessage from '@/containers/ErrorMessage'
|
||||||
|
|
||||||
import MessageContainer from '../TextMessage'
|
import MessageContainer from '../TextMessage'
|
||||||
|
|
||||||
|
import { subscribedGeneratingMessageAtom } from '@/helpers/atoms/ChatMessage.atom'
|
||||||
|
|
||||||
type Ref = HTMLDivElement
|
type Ref = HTMLDivElement
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -22,9 +26,13 @@ type Props = {
|
|||||||
const ChatItem = forwardRef<Ref, Props>((message, ref) => {
|
const ChatItem = forwardRef<Ref, Props>((message, ref) => {
|
||||||
const [content, setContent] = useState<ThreadContent[]>(message.content)
|
const [content, setContent] = useState<ThreadContent[]>(message.content)
|
||||||
const [status, setStatus] = useState<MessageStatus>(message.status)
|
const [status, setStatus] = useState<MessageStatus>(message.status)
|
||||||
|
const [subscribedGeneratingMessage, setSubscribedGeneratingMessage] = useAtom(
|
||||||
|
subscribedGeneratingMessageAtom
|
||||||
|
)
|
||||||
const [errorMessage, setErrorMessage] = useState<ThreadMessage | undefined>(
|
const [errorMessage, setErrorMessage] = useState<ThreadMessage | undefined>(
|
||||||
message.isCurrentMessage && !!message?.metadata?.error ? message : undefined
|
message.isCurrentMessage && !!message?.metadata?.error ? message : undefined
|
||||||
)
|
)
|
||||||
|
const subscribedGeneratingMessageRef = useRef(subscribedGeneratingMessage)
|
||||||
|
|
||||||
function onMessageUpdate(data: ThreadMessage) {
|
function onMessageUpdate(data: ThreadMessage) {
|
||||||
if (data.id === message.id) {
|
if (data.id === message.id) {
|
||||||
@ -32,9 +40,21 @@ const ChatItem = forwardRef<Ref, Props>((message, ref) => {
|
|||||||
if (data.status !== status) setStatus(data.status)
|
if (data.status !== status) setStatus(data.status)
|
||||||
if (data.status === MessageStatus.Error && message.isCurrentMessage)
|
if (data.status === MessageStatus.Error && message.isCurrentMessage)
|
||||||
setErrorMessage(data)
|
setErrorMessage(data)
|
||||||
|
|
||||||
|
// Update subscriber if the message is generating
|
||||||
|
if (
|
||||||
|
subscribedGeneratingMessageRef.current?.thread_id !== message.thread_id
|
||||||
|
)
|
||||||
|
setSubscribedGeneratingMessage({
|
||||||
|
thread_id: message.thread_id,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
subscribedGeneratingMessageRef.current = subscribedGeneratingMessage
|
||||||
|
}, [subscribedGeneratingMessage])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!message.isCurrentMessage && errorMessage) setErrorMessage(undefined)
|
if (!message.isCurrentMessage && errorMessage) setErrorMessage(undefined)
|
||||||
}, [message, errorMessage])
|
}, [message, errorMessage])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user