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'