diff --git a/web/helpers/atoms/ChatMessage.atom.ts b/web/helpers/atoms/ChatMessage.atom.ts index d092dd89c..4da22d13a 100644 --- a/web/helpers/atoms/ChatMessage.atom.ts +++ b/web/helpers/atoms/ChatMessage.atom.ts @@ -114,6 +114,7 @@ export const deleteMessageAtom = atom(null, (get, set, id: string) => { newData[threadId] = newData[threadId].filter( (e) => e.id !== id && e.status !== MessageStatus.Error ) + set(chatMessages, newData) } }) diff --git a/web/hooks/useDeleteThread.ts b/web/hooks/useDeleteThread.ts index 62f3a65b5..69e51228f 100644 --- a/web/hooks/useDeleteThread.ts +++ b/web/hooks/useDeleteThread.ts @@ -6,6 +6,7 @@ import { ConversationalExtension, fs, joinPath, + Thread, } from '@janhq/core' import { useAtom, useAtomValue, useSetAtom } from 'jotai' @@ -27,6 +28,7 @@ import { setActiveThreadIdAtom, deleteThreadStateAtom, updateThreadStateLastMessageAtom, + updateThreadAtom, } from '@/helpers/atoms/Thread.atom' export default function useDeleteThread() { @@ -41,6 +43,7 @@ export default function useDeleteThread() { const deleteThreadState = useSetAtom(deleteThreadStateAtom) const updateThreadLastMessage = useSetAtom(updateThreadStateLastMessageAtom) + const updateThread = useSetAtom(updateThreadAtom) const cleanThread = useCallback( async (threadId: string) => { @@ -73,19 +76,27 @@ export default function useDeleteThread() { thread.metadata = { ...thread.metadata, - lastMessage: undefined, } + + const updatedThread: Thread = { + ...thread, + title: 'New Thread', + metadata: { ...thread.metadata, lastMessage: undefined }, + } + await extensionManager .get(ExtensionTypeEnum.Conversational) - ?.saveThread(thread) + ?.saveThread(updatedThread) updateThreadLastMessage(threadId, undefined) + updateThread(updatedThread) }, [ - janDataFolderPath, + cleanMessages, threads, messages, - cleanMessages, updateThreadLastMessage, + updateThread, + janDataFolderPath, ] ) diff --git a/web/screens/Chat/MessageToolbar/index.tsx b/web/screens/Chat/MessageToolbar/index.tsx index 9c62c5d2f..744a8def0 100644 --- a/web/screens/Chat/MessageToolbar/index.tsx +++ b/web/screens/Chat/MessageToolbar/index.tsx @@ -1,3 +1,5 @@ +import { useCallback } from 'react' + import { MessageStatus, ExtensionTypeEnum, @@ -5,6 +7,7 @@ import { ChatCompletionRole, ConversationalExtension, ContentType, + Thread, } from '@janhq/core' import { useAtomValue, useSetAtom } from 'jotai' import { @@ -26,7 +29,11 @@ import { editMessageAtom, getCurrentChatMessagesAtom, } from '@/helpers/atoms/ChatMessage.atom' -import { activeThreadAtom } from '@/helpers/atoms/Thread.atom' +import { + activeThreadAtom, + updateThreadAtom, + updateThreadStateLastMessageAtom, +} from '@/helpers/atoms/Thread.atom' const MessageToolbar = ({ message }: { message: ThreadMessage }) => { const deleteMessage = useSetAtom(deleteMessageAtom) @@ -35,9 +42,19 @@ const MessageToolbar = ({ message }: { message: ThreadMessage }) => { const messages = useAtomValue(getCurrentChatMessagesAtom) const { resendChatMessage } = useSendChatMessage() const clipboard = useClipboard({ timeout: 1000 }) + const updateThreadLastMessage = useSetAtom(updateThreadStateLastMessageAtom) + const updateThread = useSetAtom(updateThreadAtom) - const onDeleteClick = async () => { + const onDeleteClick = useCallback(async () => { deleteMessage(message.id ?? '') + + const lastResponse = messages + .filter( + (msg) => + msg.id !== message.id && msg.role === ChatCompletionRole.Assistant + ) + .slice(-1)[0] + if (thread) { // Should also delete error messages to clear out the error state await extensionManager @@ -48,8 +65,26 @@ const MessageToolbar = ({ message }: { message: ThreadMessage }) => { (msg) => msg.id !== message.id && msg.status !== MessageStatus.Error ) ) + + const updatedThread: Thread = { + ...thread, + metadata: { + ...thread.metadata, + lastMessage: messages.filter( + (msg) => msg.role === ChatCompletionRole.Assistant + )[ + messages.filter((msg) => msg.role === ChatCompletionRole.Assistant) + .length - 1 + ]?.content[0].text.value, + }, + } + + updateThreadLastMessage(thread.id, lastResponse?.content) + + updateThread(updatedThread) } - } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [messages]) const onEditClick = async () => { setEditMessage(message.id ?? '')