diff --git a/web/helpers/atoms/ChatMessage.atom.ts b/web/helpers/atoms/ChatMessage.atom.ts index 14ad95a80..ecf45f1b6 100644 --- a/web/helpers/atoms/ChatMessage.atom.ts +++ b/web/helpers/atoms/ChatMessage.atom.ts @@ -1,4 +1,4 @@ -import { MessageStatus, ThreadMessage } from '@janhq/core' +import { ChatCompletionRole, MessageStatus, ThreadMessage } from '@janhq/core' import { atom } from 'jotai' import { @@ -94,6 +94,14 @@ export const deleteConversationMessage = atom(null, (get, set, id: string) => { set(chatMessages, newData) }) +export const cleanConversationMessages = atom(null, (get, set, id: string) => { + const newData: Record = { + ...get(chatMessages), + } + newData[id] = newData[id].filter((e) => e.role === ChatCompletionRole.System) + set(chatMessages, newData) +}) + export const updateMessageAtom = atom( null, ( diff --git a/web/hooks/useDeleteConversation.ts b/web/hooks/useDeleteConversation.ts index 4b2aa9859..f54fda928 100644 --- a/web/hooks/useDeleteConversation.ts +++ b/web/hooks/useDeleteConversation.ts @@ -1,4 +1,4 @@ -import { PluginType } from '@janhq/core' +import { ChatCompletionRole, PluginType } from '@janhq/core' import { ConversationalPlugin } from '@janhq/core/lib/plugins' import { useAtom, useAtomValue, useSetAtom } from 'jotai' @@ -10,7 +10,11 @@ import { pluginManager } from '../plugin/PluginManager' import { useActiveModel } from './useActiveModel' -import { deleteConversationMessage } from '@/helpers/atoms/ChatMessage.atom' +import { + cleanConversationMessages, + deleteConversationMessage, + getCurrentChatMessagesAtom, +} from '@/helpers/atoms/ChatMessage.atom' import { userConversationsAtom, getActiveConvoIdAtom, @@ -27,7 +31,27 @@ export default function useDeleteConversation() { const setActiveConvoId = useSetAtom(setActiveConvoIdAtom) const deleteMessages = useSetAtom(deleteConversationMessage) + const cleanMessages = useSetAtom(cleanConversationMessages) + const currentMessages = useAtomValue(getCurrentChatMessagesAtom) + const cleanConvo = async () => { + if (activeConvoId) { + const currentConversation = userConversations.filter( + (c) => c.id === activeConvoId + )[0] + cleanMessages(activeConvoId) + if (currentConversation) + await pluginManager + .get(PluginType.Conversational) + ?.saveConversation({ + ...currentConversation, + id: activeConvoId, + messages: currentMessages.filter( + (e) => e.role === ChatCompletionRole.System + ), + }) + } + } const deleteConvo = async () => { if (activeConvoId) { try { @@ -56,6 +80,7 @@ export default function useDeleteConversation() { } return { + cleanConvo, deleteConvo, } } diff --git a/web/hooks/useSendChatMessage.ts b/web/hooks/useSendChatMessage.ts index 1cdf2e7b9..fafe6eea3 100644 --- a/web/hooks/useSendChatMessage.ts +++ b/web/hooks/useSendChatMessage.ts @@ -49,7 +49,7 @@ export default function useSendChatMessage() { const summaryMsg: ChatCompletionMessage = { role: ChatCompletionRole.User, content: - 'summary this conversation in a few words, the response should just include the summary', + 'summary this conversation in less than 5 words, the response should just include the summary', } // Request convo summary setTimeout(async () => { @@ -64,7 +64,7 @@ export default function useSendChatMessage() { currentConvo.id === newMessage.threadId && result?.content && result?.content?.trim().length > 0 && - result.content.split(' ').length <= 10 + result.content.split(' ').length <= 20 ) { const updatedConv = { ...currentConvo, diff --git a/web/screens/Chat/index.tsx b/web/screens/Chat/index.tsx index 9efee34e1..7b1f50195 100644 --- a/web/screens/Chat/index.tsx +++ b/web/screens/Chat/index.tsx @@ -1,15 +1,16 @@ -import { Fragment, useEffect, useRef, useState } from 'react' +import { Fragment, useContext, useEffect, useRef, useState } from 'react' import { Model } from '@janhq/core/lib/types' import { Button, Badge, Textarea } from '@janhq/uikit' import { useAtom, useAtomValue } from 'jotai' -import { Trash2Icon } from 'lucide-react' +import { Trash2Icon, Paintbrush } from 'lucide-react' import { twMerge } from 'tailwind-merge' import { currentPromptAtom } from '@/containers/Providers/Jotai' +import { FeatureToggleContext } from '@/context/FeatureToggle' import ShortCut from '@/containers/Shortcut' import { MainViewState } from '@/constants/screens' @@ -42,7 +43,7 @@ import { currentConvoStateAtom } from '@/helpers/atoms/Conversation.atom' const ChatScreen = () => { const currentConvo = useAtomValue(currentConversationAtom) const { downloadedModels } = useGetDownloadedModels() - const { deleteConvo } = useDeleteConversation() + const { deleteConvo, cleanConvo } = useDeleteConversation() const { activeModel, stateModel } = useActiveModel() const { setMainViewState } = useMainViewState() @@ -60,6 +61,7 @@ const ChatScreen = () => { const [isModelAvailable, setIsModelAvailable] = useState( downloadedModels.some((x) => x.id === currentConvo?.modelId) ) + const { experimentalFeatureEnabed } = useContext(FeatureToggleContext) const textareaRef = useRef(null) @@ -147,13 +149,20 @@ const ChatScreen = () => { Download Model )} - {!stateModel.loading && ( + {experimentalFeatureEnabed && ( + cleanConvo()} + /> + )} + { deleteConvo()} /> - )} + }