From 6f81b7f0cf1900cfa53368efddaf43ffefbc4f1c Mon Sep 17 00:00:00 2001 From: Louis <133622055+louis-jan@users.noreply.github.com> Date: Thu, 26 Oct 2023 08:59:28 +0700 Subject: [PATCH] fix: correct app version display (#452) --- plugins/inference-plugin/index.ts | 5 +- plugins/inference-plugin/module.ts | 70 +++++++++---------- .../_components/ConversationalList/index.tsx | 2 +- .../_components/CreateBotContainer/index.tsx | 3 +- web/app/_components/HistoryItem/index.tsx | 2 +- web/app/_components/LeftRibbonNav/index.tsx | 2 +- web/app/_components/ModelTable/index.tsx | 2 +- web/containers/BottomBar/index.tsx | 4 +- web/containers/Providers/index.tsx | 6 +- web/containers/Sidebar/Left.tsx | 4 +- web/helpers/EventListenerWrapper.tsx | 2 +- web/hooks/useCreateBot.ts | 5 +- web/hooks/useDeleteBot.ts | 5 +- web/hooks/useGetAppVersion.ts | 2 +- web/hooks/useGetBots.ts | 7 +- web/hooks/useGetDownloadedModels.ts | 6 +- web/hooks/useGetSystemResources.ts | 2 +- web/hooks/useUpdateBot.ts | 5 +- web/next.config.js | 9 ++- .../ExploreModels/ExploreModelList/index.tsx | 2 +- .../Settings/CorePlugins/PluginsCatalog.tsx | 14 +++- .../CorePlugins/PreferencePlugins/index.tsx | 2 +- web/services/pluginService.ts | 9 +-- web/types/index.d.ts | 2 +- 24 files changed, 95 insertions(+), 77 deletions(-) diff --git a/plugins/inference-plugin/index.ts b/plugins/inference-plugin/index.ts index 04ed4b0f0..525e7e009 100644 --- a/plugins/inference-plugin/index.ts +++ b/plugins/inference-plugin/index.ts @@ -67,7 +67,7 @@ function requestInference( } subscriber.complete(); }) - .catch(subscriber.error); + .catch((err) => subscriber.error(err)); }); } @@ -143,7 +143,8 @@ async function handleMessageRequest(data: NewMessageRequest) { }, error: async (err) => { message.message = - message.message.trim() + "\n" + "Error occurred: " + err; + message.message.trim() + "\n" + "Error occurred: " + err.message; + events.emit(EventName.OnMessageResponseUpdate, message); // TODO: Common collections should be able to access via core functions instead of store await store.updateOne("messages", message._id, message); }, diff --git a/plugins/inference-plugin/module.ts b/plugins/inference-plugin/module.ts index 0ddddc37e..b851f0c4e 100644 --- a/plugins/inference-plugin/module.ts +++ b/plugins/inference-plugin/module.ts @@ -14,53 +14,49 @@ const initModel = (fileName) => { if (!fileName) { reject("Model not found, please download again."); } - if (subprocess) { - console.error("A subprocess is already running. Attempt to kill then reinit."); - killSubprocess(); - } resolve(fileName); }) - // Kill port process if it is already in use - .then((fileName) => - tcpPortUsed - .waitUntilFree(PORT, 200, 3000) - .catch(() => killPortProcess(PORT)) - .then(() => fileName) - ) // Spawn Nitro subprocess to load model .then(() => { - let binaryFolder = path.join(__dirname, "nitro"); // Current directory by default - let binaryName; + return tcpPortUsed.check(PORT, "127.0.0.1").then((inUse) => { + if (!inUse) { + let binaryFolder = path.join(__dirname, "nitro"); // Current directory by default + let binaryName; - if (process.platform === "win32") { - // Todo: Need to check for CUDA support to switch between CUDA and non-CUDA binaries - binaryName = "nitro_start_windows.bat"; - } else if (process.platform === "darwin") { - // Mac OS platform - binaryName = process.arch === "arm64" ? "nitro_mac_arm64" : "nitro_mac_intel"; - } else { - // Linux - // Todo: Need to check for CUDA support to switch between CUDA and non-CUDA binaries - binaryName = "nitro_start_linux.sh"; // For other platforms - } + if (process.platform === "win32") { + // Todo: Need to check for CUDA support to switch between CUDA and non-CUDA binaries + binaryName = "nitro_start_windows.bat"; + } else if (process.platform === "darwin") { + // Mac OS platform + binaryName = + process.arch === "arm64" + ? "nitro_mac_arm64" + : "nitro_mac_intel"; + } else { + // Linux + // Todo: Need to check for CUDA support to switch between CUDA and non-CUDA binaries + binaryName = "nitro_start_linux.sh"; // For other platforms + } - const binaryPath = path.join(binaryFolder, binaryName); + const binaryPath = path.join(binaryFolder, binaryName); - // Execute the binary - subprocess = spawn(binaryPath, { cwd: binaryFolder }); + // Execute the binary + subprocess = spawn(binaryPath, { cwd: binaryFolder }); - // Handle subprocess output - subprocess.stdout.on("data", (data) => { - console.log(`stdout: ${data}`); - }); + // Handle subprocess output + subprocess.stdout.on("data", (data) => { + console.log(`stdout: ${data}`); + }); - subprocess.stderr.on("data", (data) => { - console.error(`stderr: ${data}`); - }); + subprocess.stderr.on("data", (data) => { + console.error(`stderr: ${data}`); + }); - subprocess.on("close", (code) => { - console.log(`child process exited with code ${code}`); - subprocess = null; + subprocess.on("close", (code) => { + console.log(`child process exited with code ${code}`); + subprocess = null; + }); + } }); }) .then(() => tcpPortUsed.waitUntilUsed(PORT, 300, 30000)) diff --git a/web/app/_components/ConversationalList/index.tsx b/web/app/_components/ConversationalList/index.tsx index 6a49318fb..827874923 100644 --- a/web/app/_components/ConversationalList/index.tsx +++ b/web/app/_components/ConversationalList/index.tsx @@ -14,7 +14,7 @@ const ConversationalList: React.FC = ({ models }) => (
- {models.map((item) => ( + {models?.map((item) => ( ))}
diff --git a/web/app/_components/CreateBotContainer/index.tsx b/web/app/_components/CreateBotContainer/index.tsx index 52111e21f..2ba2946ad 100644 --- a/web/app/_components/CreateBotContainer/index.tsx +++ b/web/app/_components/CreateBotContainer/index.tsx @@ -13,15 +13,14 @@ import DraggableProgressBar from '../DraggableProgressBar' import { useSetAtom } from 'jotai' import { activeBotAtom } from '@helpers/atoms/Bot.atom' import { - leftSideBarExpandStateAtom, rightSideBarExpandStateAtom, } from '@helpers/atoms/SideBarExpand.atom' import { MainViewState, setMainViewStateAtom, } from '@helpers/atoms/MainView.atom' -import { executeSerial } from '../../../../electron/core/plugin-manager/execution/extension-manager' import { DataService } from '@janhq/core' +import { executeSerial } from '@services/pluginService' const CreateBotContainer: React.FC = () => { const { downloadedModels } = useGetDownloadedModels() diff --git a/web/app/_components/HistoryItem/index.tsx b/web/app/_components/HistoryItem/index.tsx index 118ebf501..ebf0a4f84 100644 --- a/web/app/_components/HistoryItem/index.tsx +++ b/web/app/_components/HistoryItem/index.tsx @@ -1,7 +1,6 @@ import React from 'react' import { useAtomValue, useSetAtom } from 'jotai' import { ModelManagementService } from '@janhq/core' -import { executeSerial } from '../../../../electron/core/plugin-manager/execution/extension-manager' import { getActiveConvoIdAtom, setActiveConvoIdAtom, @@ -13,6 +12,7 @@ import { } from '@helpers/atoms/MainView.atom' import { displayDate } from '@utils/datetime' import { twMerge } from 'tailwind-merge' +import { executeSerial } from '@services/pluginService' type Props = { conversation: Conversation diff --git a/web/app/_components/LeftRibbonNav/index.tsx b/web/app/_components/LeftRibbonNav/index.tsx index 327cd730e..c315d0682 100644 --- a/web/app/_components/LeftRibbonNav/index.tsx +++ b/web/app/_components/LeftRibbonNav/index.tsx @@ -59,7 +59,7 @@ const LeftRibbonNav: React.FC = () => { const onBotListClick = async () => { const bots = await getAllBots() - if (bots.length === 0) { + if (bots?.length === 0) { alert('You have no bot') return } diff --git a/web/app/_components/ModelTable/index.tsx b/web/app/_components/ModelTable/index.tsx index eaa6273f2..c3f0d96cf 100644 --- a/web/app/_components/ModelTable/index.tsx +++ b/web/app/_components/ModelTable/index.tsx @@ -20,7 +20,7 @@ const ModelTable: React.FC = ({ models }) => ( - {models.map((model) => ( + {models?.map((model) => ( ))} diff --git a/web/containers/BottomBar/index.tsx b/web/containers/BottomBar/index.tsx index 6526b7137..e10c14d29 100644 --- a/web/containers/BottomBar/index.tsx +++ b/web/containers/BottomBar/index.tsx @@ -5,12 +5,14 @@ import { useAtomValue } from 'jotai' import { modelDownloadStateAtom } from '@helpers/atoms/DownloadState.atom' import { formatDownloadPercentage } from '@utils/converter' import { activeAssistantModelAtom, stateModel } from '@helpers/atoms/Model.atom' +import useGetAppVersion from '@hooks/useGetAppVersion' const BottomBar = () => { const activeModel = useAtomValue(activeAssistantModelAtom) const stateModelStartStop = useAtomValue(stateModel) const { ram, cpu } = useGetSystemResources() const modelDownloadStates = useAtomValue(modelDownloadStateAtom) + const appVersion = useGetAppVersion() const downloadStates: DownloadState[] = [] for (const [, value] of Object.entries(modelDownloadStates)) { @@ -51,7 +53,7 @@ const BottomBar = () => {
-

Jan v0.2.0

+

Jan {appVersion?.version ?? ''}

) diff --git a/web/containers/Providers/index.tsx b/web/containers/Providers/index.tsx index 72a24b9e1..e0d28a8b8 100644 --- a/web/containers/Providers/index.tsx +++ b/web/containers/Providers/index.tsx @@ -13,13 +13,9 @@ import { activationPoints, extensionPoints, } from '../../../electron/core/plugin-manager/execution/index' -import { - isCorePluginInstalled, - setupBasePlugins, -} from '@services/pluginService' import EventListenerWrapper from '@helpers/EventListenerWrapper' import { setupCoreServices } from '@services/coreService' -import { executeSerial } from '../../../electron/core/plugin-manager/execution/extension-manager' +import { executeSerial, isCorePluginInstalled, setupBasePlugins } from '@services/pluginService' const Providers = (props: PropsWithChildren) => { const [setupCore, setSetupCore] = useState(false) diff --git a/web/containers/Sidebar/Left.tsx b/web/containers/Sidebar/Left.tsx index be2d9c0b9..e837058f3 100644 --- a/web/containers/Sidebar/Left.tsx +++ b/web/containers/Sidebar/Left.tsx @@ -36,8 +36,8 @@ export const SidebarLeft = () => { const onBotListClick = async () => { const bots = await getAllBots() - if (bots.length === 0) { - alert('You have no bot') + if (!bots || bots?.length === 0) { + alert('You have not created any bot') return } diff --git a/web/helpers/EventListenerWrapper.tsx b/web/helpers/EventListenerWrapper.tsx index d15c95d13..a75a9bb68 100644 --- a/web/helpers/EventListenerWrapper.tsx +++ b/web/helpers/EventListenerWrapper.tsx @@ -3,7 +3,6 @@ import { useSetAtom } from 'jotai' import { ReactNode, useEffect } from 'react' import { appDownloadProgress } from './JotaiWrapper' -import { executeSerial } from '../../electron/core/plugin-manager/execution/extension-manager' import { ModelManagementService } from '@janhq/core' import { setDownloadStateAtom, @@ -12,6 +11,7 @@ import { import { getDownloadedModels } from '../hooks/useGetDownloadedModels' import { downloadedModelAtom } from './atoms/DownloadedModel.atom' import EventHandler from './EventHandler' +import { executeSerial } from '@services/pluginService' type Props = { children: ReactNode diff --git a/web/hooks/useCreateBot.ts b/web/hooks/useCreateBot.ts index c54db71fe..46503de7b 100644 --- a/web/hooks/useCreateBot.ts +++ b/web/hooks/useCreateBot.ts @@ -1,9 +1,10 @@ -import { executeSerial } from '../../electron/core/plugin-manager/execution/extension-manager' +import { DataService } from '@janhq/core' +import { executeSerial } from '@services/pluginService' export default function useCreateBot() { const createBot = async (bot: Bot) => { try { - await executeSerial('createBot', bot) + await executeSerial(DataService.CreateBot, bot) } catch (err) { alert(err) console.error(err) diff --git a/web/hooks/useDeleteBot.ts b/web/hooks/useDeleteBot.ts index e253970da..8d7f6abed 100644 --- a/web/hooks/useDeleteBot.ts +++ b/web/hooks/useDeleteBot.ts @@ -1,7 +1,8 @@ import { useSetAtom } from 'jotai' -import { executeSerial } from '../../electron/core/plugin-manager/execution/extension-manager' import { activeBotAtom } from '@helpers/atoms/Bot.atom' import { rightSideBarExpandStateAtom } from '@helpers/atoms/SideBarExpand.atom' +import { executeSerial } from '@services/pluginService' +import { DataService } from '@janhq/core' export default function useDeleteBot() { const setActiveBot = useSetAtom(activeBotAtom) @@ -9,7 +10,7 @@ export default function useDeleteBot() { const deleteBot = async (botId: string): Promise<'success' | 'failed'> => { try { - await executeSerial('deleteBot', botId) + await executeSerial(DataService.DeleteBot, botId) setRightPanelVisibility(false) setActiveBot(undefined) return 'success' diff --git a/web/hooks/useGetAppVersion.ts b/web/hooks/useGetAppVersion.ts index e89de231f..cdcd12e3e 100644 --- a/web/hooks/useGetAppVersion.ts +++ b/web/hooks/useGetAppVersion.ts @@ -8,7 +8,7 @@ export default function useGetAppVersion() { }, []) const getAppVersion = () => { - window.electronAPI.appVersion().then((version: string | undefined) => { + window.coreAPI?.appVersion().then((version: string | undefined) => { setVersion(version ?? '') }) } diff --git a/web/hooks/useGetBots.ts b/web/hooks/useGetBots.ts index aa1c02fb4..e35e76478 100644 --- a/web/hooks/useGetBots.ts +++ b/web/hooks/useGetBots.ts @@ -1,9 +1,10 @@ -import { executeSerial } from '../../electron/core/plugin-manager/execution/extension-manager' +import { DataService } from '@janhq/core' +import { executeSerial } from '@services/pluginService' export default function useGetBots() { const getAllBots = async (): Promise => { try { - const bots = await executeSerial('getBots') + const bots = await executeSerial(DataService.GetBots) return bots } catch (err) { alert(`Failed to get bots: ${err}`) @@ -14,7 +15,7 @@ export default function useGetBots() { const getBotById = async (botId: string): Promise => { try { - const bot: Bot = await executeSerial('getBotById', botId) + const bot: Bot = await executeSerial(DataService.GetBotById, botId) return bot } catch (err) { alert(`Failed to get bot ${botId}: ${err}`) diff --git a/web/hooks/useGetDownloadedModels.ts b/web/hooks/useGetDownloadedModels.ts index d77ab810d..1474c55a0 100644 --- a/web/hooks/useGetDownloadedModels.ts +++ b/web/hooks/useGetDownloadedModels.ts @@ -1,8 +1,9 @@ import { useEffect } from 'react' -import { executeSerial } from '../../electron/core/plugin-manager/execution/extension-manager' import { ModelManagementService } from '@janhq/core' import { useAtom } from 'jotai' import { downloadedModelAtom } from '@helpers/atoms/DownloadedModel.atom' +import { extensionPoints } from '../../electron/core/plugin-manager/execution' +import { executeSerial } from '@services/pluginService' export function useGetDownloadedModels() { const [downloadedModels, setDownloadedModels] = useAtom(downloadedModelAtom) @@ -17,6 +18,9 @@ export function useGetDownloadedModels() { } export async function getDownloadedModels(): Promise { + if (!extensionPoints.get(ModelManagementService.GetFinishedDownloadModels)) { + return [] + } const downloadedModels: AssistantModel[] = await executeSerial( ModelManagementService.GetFinishedDownloadModels ) diff --git a/web/hooks/useGetSystemResources.ts b/web/hooks/useGetSystemResources.ts index 0e77882a5..a6f751f76 100644 --- a/web/hooks/useGetSystemResources.ts +++ b/web/hooks/useGetSystemResources.ts @@ -1,9 +1,9 @@ import { useEffect, useState } from 'react' -import { executeSerial } from '../../electron/core/plugin-manager/execution/extension-manager' import { extensionPoints } from '../../electron/core/plugin-manager/execution' import { SystemMonitoringService } from '@janhq/core' import { useSetAtom } from 'jotai' import { totalRamAtom } from '@helpers/atoms/SystemBar.atom' +import { executeSerial } from '@services/pluginService' export default function useGetSystemResources() { const [ram, setRam] = useState(0) const [cpu, setCPU] = useState(0) diff --git a/web/hooks/useUpdateBot.ts b/web/hooks/useUpdateBot.ts index 5eff88e70..b913ab394 100644 --- a/web/hooks/useUpdateBot.ts +++ b/web/hooks/useUpdateBot.ts @@ -1,4 +1,5 @@ -import { executeSerial } from '../../electron/core/plugin-manager/execution/extension-manager' +import { DataService } from '@janhq/core' +import { executeSerial } from '@services/pluginService' export default function useUpdateBot() { const updateBot = async ( @@ -15,7 +16,7 @@ export default function useUpdateBot() { } } - await executeSerial('updateBot', bot) + await executeSerial(DataService.UpdateBot, bot) console.debug('Bot updated', JSON.stringify(bot, null, 2)) } catch (err) { alert(`Update bot error: ${err}`) diff --git a/web/next.config.js b/web/next.config.js index dde766300..318b3108b 100644 --- a/web/next.config.js +++ b/web/next.config.js @@ -21,7 +21,14 @@ const nextConfig = { // do some stuff here config.optimization.minimize = false config.optimization.minimizer = [] - config.plugins = [...config.plugins, new webpack.DefinePlugin({})] + config.plugins = [ + ...config.plugins, + new webpack.DefinePlugin({ + PLUGIN_CATALOG: JSON.stringify( + 'https://cdn.jsdelivr.net/npm/@janhq/plugin-catalog@latest/dist/index.js' + ), + }), + ] return config }, } diff --git a/web/screens/ExploreModels/ExploreModelList/index.tsx b/web/screens/ExploreModels/ExploreModelList/index.tsx index 6c3acee71..0f5f08da8 100644 --- a/web/screens/ExploreModels/ExploreModelList/index.tsx +++ b/web/screens/ExploreModels/ExploreModelList/index.tsx @@ -12,7 +12,7 @@ const ExploreModelList: React.FC = () => { return (
- {models.map((item) => ( + {models?.map((item) => ( ))}
diff --git a/web/screens/Settings/CorePlugins/PluginsCatalog.tsx b/web/screens/Settings/CorePlugins/PluginsCatalog.tsx index 595239ead..53e2d5ff5 100644 --- a/web/screens/Settings/CorePlugins/PluginsCatalog.tsx +++ b/web/screens/Settings/CorePlugins/PluginsCatalog.tsx @@ -25,9 +25,17 @@ const PluginCatalog = () => { * Loads the plugin catalog module from a CDN and sets it as the plugin catalog state. */ useEffect(() => { - executeSerial(DataService.GetPluginManifest).then((data) => { - setPluginCatalog(data) - }) + // Load plugin manifest from plugin if any + if (extensionPoints.get(DataService.GetPluginManifest)) { + executeSerial(DataService.GetPluginManifest).then((data) => { + setPluginCatalog(data) + }) + } else { + // Fallback to app default manifest + import( + /* webpackIgnore: true */ PLUGIN_CATALOG + `?t=${Date.now()}` + ).then((data) => setPluginCatalog(data.default)) + } }, []) /** diff --git a/web/screens/Settings/CorePlugins/PreferencePlugins/index.tsx b/web/screens/Settings/CorePlugins/PreferencePlugins/index.tsx index 841acc38a..fbf5dc625 100644 --- a/web/screens/Settings/CorePlugins/PreferencePlugins/index.tsx +++ b/web/screens/Settings/CorePlugins/PreferencePlugins/index.tsx @@ -1,4 +1,4 @@ -import React, { Children } from 'react' +import React from 'react' import { execute } from '../../../../../electron/core/plugin-manager/execution/extension-manager' type Props = { diff --git a/web/services/pluginService.ts b/web/services/pluginService.ts index 812bc3a79..d885e6d8d 100644 --- a/web/services/pluginService.ts +++ b/web/services/pluginService.ts @@ -8,10 +8,11 @@ import { DataService, InferenceService, ModelManagementService, + StoreService, } from '@janhq/core' export const isCorePluginInstalled = () => { - if (!extensionPoints.get(DataService.GetConversations)) { + if (!extensionPoints.get(StoreService.CreateCollection)) { return false } if (!extensionPoints.get(InferenceService.InitModel)) { @@ -32,7 +33,7 @@ export const setupBasePlugins = async () => { const basePlugins = await window.electronAPI.basePlugins() if ( - !extensionPoints.get(DataService.GetConversations) || + !extensionPoints.get(StoreService.CreateCollection) || !extensionPoints.get(InferenceService.InitModel) || !extensionPoints.get(ModelManagementService.DownloadModel) ) { @@ -45,7 +46,7 @@ export const setupBasePlugins = async () => { export const execute = (name: CoreService, args?: any) => { if (!extensionPoints.get(name)) { - alert('Missing extension for function: ' + name) + // alert('Missing extension for function: ' + name) return undefined } return extensionPoints.execute(name, args) @@ -53,7 +54,7 @@ export const execute = (name: CoreService, args?: any) => { export const executeSerial = (name: CoreService, args?: any) => { if (!extensionPoints.get(name)) { - alert('Missing extension for function: ' + name) + // alert('Missing extension for function: ' + name) return Promise.resolve(undefined) } return extensionPoints.executeSerial(name, args) diff --git a/web/types/index.d.ts b/web/types/index.d.ts index 07e261a3c..3d19bd540 100644 --- a/web/types/index.d.ts +++ b/web/types/index.d.ts @@ -1,7 +1,7 @@ export {} -declare const PLUGIN_CATALOGS: string[] declare global { + declare const PLUGIN_CATALOG: string interface Window { electronAPI?: any | undefined corePlugin?: any | undefined