diff --git a/web/containers/ModelDropdown/index.tsx b/web/containers/ModelDropdown/index.tsx index 2ecdf4cd3..04e350c71 100644 --- a/web/containers/ModelDropdown/index.tsx +++ b/web/containers/ModelDropdown/index.tsx @@ -194,13 +194,22 @@ const ModelDropdown = ({ const modelId = activeAssistant?.model?.id const model = downloadedModels.find((model) => model.id === modelId) - setSelectedModel(model) + if (model) { + if ( + engines?.[model.engine]?.[0].type === 'local' || + (engines?.[model.engine]?.[0].api_key?.length ?? 0) > 0 + ) + setSelectedModel(model) + } else { + setSelectedModel(undefined) + } }, [ recommendedModel, activeThread, downloadedModels, setSelectedModel, activeAssistant?.model?.id, + engines, ]) const isLocalEngine = useCallback( diff --git a/web/containers/Providers/ModelHandler.tsx b/web/containers/Providers/ModelHandler.tsx index 32182804c..1c60eefd5 100644 --- a/web/containers/Providers/ModelHandler.tsx +++ b/web/containers/Providers/ModelHandler.tsx @@ -336,7 +336,8 @@ export default function ModelHandler() { // Check model engine; we don't want to generate a title when it's not a local engine. remote model using first promp if ( - !isLocalEngine(engines, activeModelRef.current?.engine as InferenceEngine) + activeModelRef.current?.engine !== InferenceEngine.cortex && + activeModelRef.current?.engine !== InferenceEngine.cortex_llamacpp ) { const updatedThread: Thread = { ...thread, @@ -396,9 +397,7 @@ export default function ModelHandler() { // 2. Update the title with the result of the inference setTimeout(() => { - const engine = EngineManager.instance().get( - messageRequest.model?.engine ?? activeModelRef.current?.engine ?? '' - ) + const engine = EngineManager.instance().get(InferenceEngine.cortex) engine?.inference(messageRequest) }, 1000) } diff --git a/web/hooks/useActiveModel.ts b/web/hooks/useActiveModel.ts index 25cc7fcc8..b4b8a5033 100644 --- a/web/hooks/useActiveModel.ts +++ b/web/hooks/useActiveModel.ts @@ -159,7 +159,7 @@ export function useActiveModel() { } if (!activeModel) return - const engine = EngineManager.instance().get(activeModel.engine) + const engine = EngineManager.instance().get(InferenceEngine.cortex) engine?.stopInference() }, [activeModel, stateModel, stopModel]) diff --git a/web/hooks/useConfigurations.ts b/web/hooks/useConfigurations.ts index 9d4999b2f..681239033 100644 --- a/web/hooks/useConfigurations.ts +++ b/web/hooks/useConfigurations.ts @@ -33,6 +33,7 @@ export const useConfigurations = () => { useEffect(() => { configurePullOptions() + // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return { diff --git a/web/hooks/useRecommendedModel.ts b/web/hooks/useRecommendedModel.ts index 03bcc4a30..64376f7a1 100644 --- a/web/hooks/useRecommendedModel.ts +++ b/web/hooks/useRecommendedModel.ts @@ -7,6 +7,7 @@ import { atom, useAtomValue } from 'jotai' import { activeModelAtom } from './useActiveModel' import { activeAssistantAtom } from '@/helpers/atoms/Assistant.atom' +import { installedEnginesAtom } from '@/helpers/atoms/Engines.atom' import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom' import { activeThreadAtom } from '@/helpers/atoms/Thread.atom' @@ -30,6 +31,7 @@ export default function useRecommendedModel() { const activeThread = useAtomValue(activeThreadAtom) const downloadedModels = useAtomValue(downloadedModelsAtom) const activeAssistant = useAtomValue(activeAssistantAtom) + const engines = useAtomValue(installedEnginesAtom) const getAndSortDownloadedModels = useCallback(async (): Promise => { const models = downloadedModels.sort((a, b) => @@ -45,7 +47,12 @@ export default function useRecommendedModel() { const getRecommendedModel = useCallback(async (): Promise< Model | undefined > => { - const models = await getAndSortDownloadedModels() + const models = (await getAndSortDownloadedModels()).filter((e: Model) => + engines?.[e.engine]?.[0].type === 'local' || + (engines?.[e.engine]?.[0].api_key?.length ?? 0) > 0 + ? true + : false + ) if (!activeThread || !activeAssistant) return const modelId = activeAssistant.model.id @@ -63,10 +70,8 @@ export default function useRecommendedModel() { } // sort the model, for display purpose - if (models.length === 0) { // if we have no downloaded models, then can't recommend anything - console.debug("No downloaded models, can't recommend anything") setRecommendedModel(undefined) return } @@ -94,7 +99,7 @@ export default function useRecommendedModel() { setRecommendedModel(lastUsedModel) // eslint-disable-next-line react-hooks/exhaustive-deps - }, [getAndSortDownloadedModels, activeThread]) + }, [getAndSortDownloadedModels, activeThread, engines]) useEffect(() => { getRecommendedModel() diff --git a/web/hooks/useStarterScreen.ts b/web/hooks/useStarterScreen.ts index 23a659a04..200e645dc 100644 --- a/web/hooks/useStarterScreen.ts +++ b/web/hooks/useStarterScreen.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { useMemo } from 'react' import { InferenceEngine, EngineConfig } from '@janhq/core' diff --git a/web/screens/Hub/ModelList/index.tsx b/web/screens/Hub/ModelList/index.tsx index 0d7865a81..0984a3a01 100644 --- a/web/screens/Hub/ModelList/index.tsx +++ b/web/screens/Hub/ModelList/index.tsx @@ -6,6 +6,7 @@ import { useAtomValue } from 'jotai' import ModelItem from '@/screens/Hub/ModelList/ModelItem' +import { installedEnginesAtom } from '@/helpers/atoms/Engines.atom' import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom' type Props = { @@ -14,6 +15,7 @@ type Props = { const ModelList = ({ models }: Props) => { const downloadedModels = useAtomValue(downloadedModelsAtom) + const engines = useAtomValue(installedEnginesAtom) const sortedModels: Model[] = useMemo(() => { const featuredModels: Model[] = [] const remoteModels: Model[] = [] @@ -22,7 +24,7 @@ const ModelList = ({ models }: Props) => { models.forEach((m) => { if (m.metadata?.tags?.includes('Featured')) { featuredModels.push(m) - } else if (m.format === 'api') { + } else if (engines?.[m.engine]?.[0]?.type === 'remote') { remoteModels.push(m) } else if (downloadedModels.map((m) => m.id).includes(m.id)) { localModels.push(m) @@ -40,7 +42,7 @@ const ModelList = ({ models }: Props) => { ...remainingModels, ...remoteModels, ] - }, [models, downloadedModels]) + }, [models, downloadedModels, engines]) return (
diff --git a/web/screens/LocalServer/LocalServerLeftPanel/index.tsx b/web/screens/LocalServer/LocalServerLeftPanel/index.tsx index a5250b013..99c2d7488 100644 --- a/web/screens/LocalServer/LocalServerLeftPanel/index.tsx +++ b/web/screens/LocalServer/LocalServerLeftPanel/index.tsx @@ -1,6 +1,11 @@ import { Fragment, useCallback, useState } from 'react' -import { EngineManager, Model, ModelSettingParams } from '@janhq/core' +import { + EngineManager, + InferenceEngine, + Model, + ModelSettingParams, +} from '@janhq/core' import { Button, Tooltip, Select, Input, Checkbox } from '@janhq/joi' import { useAtom, useAtomValue, useSetAtom } from 'jotai' @@ -94,7 +99,7 @@ const LocalServerLeftPanel = () => { localStorage.setItem(FIRST_TIME_VISIT_API_SERVER, 'false') setFirstTimeVisitAPIServer(false) } - const engine = EngineManager.instance().get((model as Model).engine) + const engine = EngineManager.instance().get(InferenceEngine.cortex) engine?.loadModel(model as Model) // startModel(selectedModel.id, false).catch((e) => console.error(e)) setIsLoading(false) diff --git a/web/screens/Settings/Engines/RemoteEngineSettings.tsx b/web/screens/Settings/Engines/RemoteEngineSettings.tsx index dc2948198..cb05f7f2b 100644 --- a/web/screens/Settings/Engines/RemoteEngineSettings.tsx +++ b/web/screens/Settings/Engines/RemoteEngineSettings.tsx @@ -1,11 +1,14 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable react/no-unescaped-entities */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import React, { useCallback, useRef, useState, useEffect } from 'react' import { EngineConfig as OriginalEngineConfig, InferenceEngine, + events, + EngineEvent, } from '@janhq/core' interface EngineConfig extends OriginalEngineConfig { @@ -64,6 +67,7 @@ const RemoteEngineSettings = ({ set(updatedEngine, field, value) await updateEngine(name, updatedEngine) mutate() + events.emit(EngineEvent.OnEngineUpdate, {}) }, 300) }, [engine, name, mutate] diff --git a/web/screens/Thread/ThreadCenterPanel/AssistantSetting/index.tsx b/web/screens/Thread/ThreadCenterPanel/AssistantSetting/index.tsx index d04f9b233..1ecb6f7fd 100644 --- a/web/screens/Thread/ThreadCenterPanel/AssistantSetting/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/AssistantSetting/index.tsx @@ -88,6 +88,7 @@ const AssistantSetting: React.FC = ({ componentData }) => { setEngineParamsUpdate, stopModel, updateThreadMetadata, + resetGenerating, ] ) diff --git a/web/screens/Thread/ThreadCenterPanel/LoadModelError/index.tsx b/web/screens/Thread/ThreadCenterPanel/LoadModelError/index.tsx index 204ec40fb..3a887e8ea 100644 --- a/web/screens/Thread/ThreadCenterPanel/LoadModelError/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/LoadModelError/index.tsx @@ -1,4 +1,4 @@ -import { EngineManager } from '@janhq/core' +import { EngineManager, InferenceEngine } from '@janhq/core' import { useAtomValue, useSetAtom } from 'jotai' import ModalTroubleShooting, { @@ -35,7 +35,7 @@ const LoadModelError = () => { setMainState(MainViewState.Settings) if (activeAssistant?.model.engine) { const engine = EngineManager.instance().get( - activeAssistant.model.engine + InferenceEngine.cortex ) engine?.name && setSelectedSettingScreen(engine.name) }