diff --git a/core/src/plugins/model.ts b/core/src/plugins/model.ts index 9d263aaa1b..53d3d45651 100644 --- a/core/src/plugins/model.ts +++ b/core/src/plugins/model.ts @@ -18,11 +18,10 @@ export abstract class ModelPlugin extends JanPlugin { /** * Cancels the download of a specific model. - * @param {string} name - The name of the model to cancel the download for. * @param {string} modelId - The ID of the model to cancel the download for. * @returns {Promise} A promise that resolves when the download has been cancelled. */ - abstract cancelModelDownload(name: string, modelId: string): Promise; + abstract cancelModelDownload(modelId: string): Promise; /** * Deletes a model. diff --git a/plugins/model-plugin/src/index.ts b/plugins/model-plugin/src/index.ts index c6a4687dc6..7ca63e7086 100644 --- a/plugins/model-plugin/src/index.ts +++ b/plugins/model-plugin/src/index.ts @@ -57,10 +57,10 @@ export default class JanModelPlugin implements ModelPlugin { * @param {string} modelId - The ID of the model whose download is to be cancelled. * @returns {Promise} A promise that resolves when the download has been cancelled. */ - async cancelModelDownload(name: string, modelId: string): Promise { - return abortDownload(join(JanModelPlugin._homeDir, name, modelId)).then( + async cancelModelDownload(modelId: string): Promise { + return abortDownload(join(JanModelPlugin._homeDir, modelId, modelId)).then( () => { - fs.deleteFile(join(JanModelPlugin._homeDir, name, modelId)) + fs.rmdir(join(JanModelPlugin._homeDir, modelId)) } ) } diff --git a/web/containers/Providers/EventHandler.tsx b/web/containers/Providers/EventHandler.tsx index 78a392b09b..de4a8c9a4b 100644 --- a/web/containers/Providers/EventHandler.tsx +++ b/web/containers/Providers/EventHandler.tsx @@ -16,7 +16,6 @@ import { useGetDownloadedModels } from '@/hooks/useGetDownloadedModels' import { addNewMessageAtom, - chatMessages, updateMessageAtom, } from '@/helpers/atoms/ChatMessage.atom' import { @@ -35,15 +34,12 @@ export default function EventHandler({ children }: { children: ReactNode }) { const updateConvWaiting = useSetAtom(updateConversationWaitingForResponseAtom) const models = useAtomValue(downloadingModelsAtom) - const messages = useAtomValue(chatMessages) - const conversations = useAtomValue(threadsAtom) - const messagesRef = useRef(messages) - const convoRef = useRef(conversations) + const threads = useAtomValue(threadsAtom) + const threadsRef = useRef(threads) useEffect(() => { - messagesRef.current = messages - convoRef.current = conversations - }, [messages, conversations]) + threadsRef.current = threads + }, [threads]) async function handleNewMessageResponse(message: ThreadMessage) { addNewMessage(message) @@ -59,7 +55,6 @@ export default function EventHandler({ children }: { children: ReactNode }) { } async function handleMessageResponseFinished(message: ThreadMessage) { - if (!convoRef.current) return updateConvWaiting(message.thread_id, false) if (message.id && message.content) { @@ -70,8 +65,7 @@ export default function EventHandler({ children }: { children: ReactNode }) { MessageStatus.Ready ) } - - const thread = convoRef.current.find((e) => e.id == message.thread_id) + const thread = threadsRef.current?.find((e) => e.id == message.thread_id) if (thread) { const messageContent = message.content[0]?.text.value ?? '' const metadata = { @@ -93,6 +87,7 @@ export default function EventHandler({ children }: { children: ReactNode }) { function handleDownloadUpdate(state: any) { if (!state) return + state.fileName = state.fileName.split('/').pop() ?? '' setDownloadState(state) } diff --git a/web/hooks/useDeleteConversation.ts b/web/hooks/useDeleteConversation.ts index d793f6788d..e69e0ef464 100644 --- a/web/hooks/useDeleteConversation.ts +++ b/web/hooks/useDeleteConversation.ts @@ -30,7 +30,7 @@ export default function useDeleteThread() { const deleteMessages = useSetAtom(deleteConversationMessage) const cleanMessages = useSetAtom(cleanConversationMessages) - const cleanConvo = async () => { + const cleanThread = async () => { if (activeThreadId) { const currentConversation = userConversations.filter( (c) => c.id === activeThreadId @@ -76,7 +76,7 @@ export default function useDeleteThread() { } return { - cleanConvo, + cleanThread, deleteThread, } } diff --git a/web/hooks/useDownloadState.ts b/web/hooks/useDownloadState.ts index 3af336dd80..a4a4c9f9bf 100644 --- a/web/hooks/useDownloadState.ts +++ b/web/hooks/useDownloadState.ts @@ -10,7 +10,6 @@ const setDownloadStateAtom = atom(null, (get, set, state: DownloadState) => { console.debug( `current download state for ${state.fileName} is ${JSON.stringify(state)}` ) - state.fileName = state.fileName.replace('models/', '') currentState[state.fileName] = state set(modelDownloadStateAtom, currentState) }) diff --git a/web/hooks/useGetDownloadedModels.ts b/web/hooks/useGetDownloadedModels.ts index 766ff1b9a2..b83918d297 100644 --- a/web/hooks/useGetDownloadedModels.ts +++ b/web/hooks/useGetDownloadedModels.ts @@ -1,13 +1,17 @@ -import { useEffect, useState } from 'react' +import { useEffect } from 'react' import { PluginType } from '@janhq/core' import { ModelPlugin } from '@janhq/core/lib/plugins' import { Model } from '@janhq/core/lib/types' +import { atom, useAtom } from 'jotai' + import { pluginManager } from '@/plugin/PluginManager' +const downloadedModelsAtom = atom([]) + export function useGetDownloadedModels() { - const [downloadedModels, setDownloadedModels] = useState([]) + const [downloadedModels, setDownloadedModels] = useAtom(downloadedModelsAtom) useEffect(() => { getDownloadedModels().then((downloadedModels) => { @@ -22,5 +26,6 @@ export async function getDownloadedModels(): Promise { const models = await pluginManager .get(PluginType.Model) ?.getDownloadedModels() + return models ?? [] } diff --git a/web/screens/Chat/ChatBody/index.tsx b/web/screens/Chat/ChatBody/index.tsx index 8fc59ab121..10d0086613 100644 --- a/web/screens/Chat/ChatBody/index.tsx +++ b/web/screens/Chat/ChatBody/index.tsx @@ -1,6 +1,5 @@ import { useAtomValue } from 'jotai' -import ChatInstruction from '../ChatInstruction' import ChatItem from '../ChatItem' import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom' @@ -12,7 +11,6 @@ const ChatBody: React.FC = () => { {messages.map((message) => ( ))} - {messages.length === 0 && } ) } diff --git a/web/screens/Chat/ChatInstruction/index.tsx b/web/screens/Chat/ChatInstruction/index.tsx deleted file mode 100644 index 1f927f6ce5..0000000000 --- a/web/screens/Chat/ChatInstruction/index.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { useState } from 'react' - -import { - ChatCompletionRole, - ContentType, - EventName, - MessageStatus, - ThreadMessage, - events, -} from '@janhq/core' - -import { Button, Textarea } from '@janhq/uikit' -import { useAtomValue } from 'jotai' - -import { getActiveThreadIdAtom } from '@/helpers/atoms/Conversation.atom' - -const ChatInstruction = () => { - const activeConvoId = useAtomValue(getActiveThreadIdAtom) - const [isSettingInstruction, setIsSettingInstruction] = useState(false) - const [instruction, setInstruction] = useState('') - const setSystemPrompt = (instruction: string) => { - if (!activeConvoId) return - - const message: ThreadMessage = { - id: 'system-prompt', - content: [ - { - type: ContentType.Text, - text: { value: instruction, annotations: [] }, - }, - ], - role: ChatCompletionRole.System, - status: MessageStatus.Ready, - thread_id: activeConvoId, - created: Date.now(), - updated: Date.now(), - object: 'message', - } - events.emit(EventName.OnNewMessageResponse, message) - events.emit(EventName.OnMessageResponseFinished, message) - } - return ( -
-

- What does this Assistant do? How does it behave? What should it avoid - doing? -

- {!isSettingInstruction && activeConvoId && ( - <> - - - )} - {isSettingInstruction && ( -
-