diff --git a/.gitignore b/.gitignore index e3e4635fc..4540e5c7a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ build electron/renderer electron/models electron/docs +electron/engines +server/pre-install package-lock.json *.log @@ -26,3 +28,4 @@ extensions/inference-nitro-extension/bin/*/*.exp extensions/inference-nitro-extension/bin/*/*.lib extensions/inference-nitro-extension/bin/saved-* extensions/inference-nitro-extension/bin/*.tar.gz + diff --git a/extensions/assistant-extension/src/index.ts b/extensions/assistant-extension/src/index.ts index 96de33b7b..098ab1f54 100644 --- a/extensions/assistant-extension/src/index.ts +++ b/extensions/assistant-extension/src/index.ts @@ -1,5 +1,4 @@ -import { fs, Assistant } from "@janhq/core"; -import { AssistantExtension } from "@janhq/core"; +import { fs, Assistant, AssistantExtension } from "@janhq/core"; import { join } from "path"; export default class JanAssistantExtension extends AssistantExtension { diff --git a/extensions/monitoring-extension/src/index.ts b/extensions/monitoring-extension/src/index.ts index d3f20b437..9297a770f 100644 --- a/extensions/monitoring-extension/src/index.ts +++ b/extensions/monitoring-extension/src/index.ts @@ -1,5 +1,4 @@ -import { MonitoringExtension } from "@janhq/core"; -import { executeOnMain } from "@janhq/core"; +import { MonitoringExtension, executeOnMain } from "@janhq/core"; /** * JanMonitoringExtension is a extension that provides system monitoring functionality. diff --git a/web/containers/Layout/index.tsx b/web/containers/Layout/index.tsx index 54a7845a4..e7bde49c0 100644 --- a/web/containers/Layout/index.tsx +++ b/web/containers/Layout/index.tsx @@ -28,7 +28,7 @@ const BaseLayout = (props: PropsWithChildren) => { if (localStorage.getItem(SUCCESS_SET_NEW_DESTINATION) === 'true') { setMainViewState(MainViewState.Settings) } - }, []) + }, [setMainViewState]) return (
diff --git a/web/containers/Providers/EventHandler.tsx b/web/containers/Providers/EventHandler.tsx index 1f9d6d7af..114370359 100644 --- a/web/containers/Providers/EventHandler.tsx +++ b/web/containers/Providers/EventHandler.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { ReactNode, useEffect, useRef } from 'react' +import { ReactNode, useCallback, useEffect, useRef } from 'react' import { events, @@ -48,48 +48,61 @@ export default function EventHandler({ children }: { children: ReactNode }) { modelsRef.current = downloadedModels }, [downloadedModels]) - async function handleNewMessageResponse(message: ThreadMessage) { - addNewMessage(message) - } + const onNewMessageResponse = useCallback( + (message: ThreadMessage) => { + addNewMessage(message) + }, + [addNewMessage] + ) - async function handleModelReady(model: Model) { - setActiveModel(model) - toaster({ - title: 'Success!', - description: `Model ${model.id} has been started.`, - }) - setStateModel(() => ({ - state: 'stop', - loading: false, - model: model.id, - })) - } + const onModelReady = useCallback( + (model: Model) => { + setActiveModel(model) + toaster({ + title: 'Success!', + description: `Model ${model.id} has been started.`, + }) + setStateModel(() => ({ + state: 'stop', + loading: false, + model: model.id, + })) + }, + [setActiveModel, setStateModel] + ) - async function handleModelStopped() { - setTimeout(async () => { + const onModelStopped = useCallback(() => { + setTimeout(() => { setActiveModel(undefined) setStateModel({ state: 'start', loading: false, model: '' }) }, 500) - } + }, [setActiveModel, setStateModel]) - async function handleModelFail(res: any) { - const errorMessage = `${res.error}` - alert(errorMessage) - setStateModel(() => ({ - state: 'start', - loading: false, - model: res.modelId, - })) - } + const onModelInitFailed = useCallback( + (res: any) => { + const errorMessage = `${res.error}` + console.error('Failed to load model: ' + errorMessage) + setStateModel(() => ({ + state: 'start', + loading: false, + model: res.modelId, + })) + }, + [setStateModel] + ) + + const onMessageResponseUpdate = useCallback( + (message: ThreadMessage) => { + updateMessage( + message.id, + message.thread_id, + message.content, + message.status + ) + if (message.status === MessageStatus.Pending) { + return + } - async function handleMessageResponseUpdate(message: ThreadMessage) { - updateMessage( - message.id, - message.thread_id, - message.content, - message.status - ) - if (message.status !== MessageStatus.Pending) { // Mark the thread as not waiting for response updateThreadWaiting(message.thread_id, false) @@ -111,26 +124,33 @@ export default function EventHandler({ children }: { children: ReactNode }) { .get(ExtensionTypeEnum.Conversational) ?.addNewMessage(message) } - } - } + }, + [updateMessage, updateThreadWaiting] + ) useEffect(() => { + console.log('Registering events') if (window.core?.events) { - events.on(MessageEvent.OnMessageResponse, handleNewMessageResponse) - events.on(MessageEvent.OnMessageUpdate, handleMessageResponseUpdate) - events.on(ModelEvent.OnModelReady, handleModelReady) - events.on(ModelEvent.OnModelFail, handleModelFail) - events.on(ModelEvent.OnModelStopped, handleModelStopped) + events.on(MessageEvent.OnMessageResponse, onNewMessageResponse) + events.on(MessageEvent.OnMessageUpdate, onMessageResponseUpdate) + + events.on(ModelEvent.OnModelReady, onModelReady) + events.on(ModelEvent.OnModelFail, onModelInitFailed) + events.on(ModelEvent.OnModelStopped, onModelStopped) } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + }, [ + onNewMessageResponse, + onMessageResponseUpdate, + onModelReady, + onModelInitFailed, + onModelStopped, + ]) useEffect(() => { return () => { - events.off(MessageEvent.OnMessageResponse, handleNewMessageResponse) - events.off(MessageEvent.OnMessageUpdate, handleMessageResponseUpdate) + events.off(MessageEvent.OnMessageResponse, onNewMessageResponse) + events.off(MessageEvent.OnMessageUpdate, onMessageResponseUpdate) } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + }, [onNewMessageResponse, onMessageResponseUpdate]) return <>{children} } diff --git a/web/containers/Providers/EventListener.tsx b/web/containers/Providers/EventListener.tsx index 2816c88e2..62d4cacb6 100644 --- a/web/containers/Providers/EventListener.tsx +++ b/web/containers/Providers/EventListener.tsx @@ -105,12 +105,14 @@ export default function EventListenerWrapper({ children }: PropsWithChildren) { }) } return () => {} - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + }, [ + setDownloadState, + setDownloadStateCancelled, + setDownloadStateFailed, + setDownloadStateSuccess, + setDownloadedModels, + setProgress, + ]) - return ( -
- {children} -
- ) + return {children} } diff --git a/web/hooks/useGetConfiguredModels.ts b/web/hooks/useGetConfiguredModels.ts index 919f43754..8be052ae2 100644 --- a/web/hooks/useGetConfiguredModels.ts +++ b/web/hooks/useGetConfiguredModels.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react' +import { useCallback, useEffect, useState } from 'react' import { ExtensionTypeEnum, ModelExtension, Model } from '@janhq/core' @@ -8,24 +8,23 @@ export function useGetConfiguredModels() { const [loading, setLoading] = useState(false) const [models, setModels] = useState([]) - const getConfiguredModels = async (): Promise => { - const models = await extensionManager - .get(ExtensionTypeEnum.Model) - ?.getConfiguredModels() - return models ?? [] - } - - async function fetchModels() { + const fetchModels = useCallback(async () => { setLoading(true) const models = await getConfiguredModels() setLoading(false) setModels(models) - } + }, []) useEffect(() => { fetchModels() - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + }, [fetchModels]) return { loading, models } } + +const getConfiguredModels = async (): Promise => { + const models = await extensionManager + .get(ExtensionTypeEnum.Model) + ?.getConfiguredModels() + return models ?? [] +} diff --git a/web/screens/Chat/MessageToolbar/index.tsx b/web/screens/Chat/MessageToolbar/index.tsx index 183eae814..dfa8d63c6 100644 --- a/web/screens/Chat/MessageToolbar/index.tsx +++ b/web/screens/Chat/MessageToolbar/index.tsx @@ -3,8 +3,8 @@ import { ExtensionTypeEnum, ThreadMessage, ChatCompletionRole, + ConversationalExtension, } from '@janhq/core' -import { ConversationalExtension } from '@janhq/core' import { useAtomValue, useSetAtom } from 'jotai' import { RefreshCcw, CopyIcon, Trash2Icon, CheckIcon } from 'lucide-react'