diff --git a/src-ui/logics/_useBackendErrorHandling.js b/src-ui/logics/_useBackendErrorHandling.js index f224686c..eb8bcae0 100644 --- a/src-ui/logics/_useBackendErrorHandling.js +++ b/src-ui/logics/_useBackendErrorHandling.js @@ -2,6 +2,7 @@ import { useI18n } from "@useI18n"; import { useNotificationStatus, + useLLMConnection, } from "@logics_common"; import { @@ -46,6 +47,11 @@ export const _useBackendErrorHandling = () => { updateWebsocketPort, } = useAdvancedSettings(); + const { + updateIsOllamaConnected, + updateIsLMStudioConnected, + } = useLLMConnection(); + const errorHandling_Backend = ({message, data, endpoint, result}) => { switch (endpoint) { case "/run/error_device": @@ -221,6 +227,18 @@ export const _useBackendErrorHandling = () => { } return; + case "/run/lmstudio_connection": + updateIsLMStudioConnected(data); + showNotification_Error(message); + console.error(message); + return; + + case "/run/ollama_connection": + updateIsOllamaConnected(data); + showNotification_Error(message); + console.error(message); + return; + default: console.error(`Invalid endpoint or message: ${endpoint}\nmessage: ${message}\nresult: ${JSON.stringify(result)}`); return; diff --git a/src-ui/logics/common/index.js b/src-ui/logics/common/index.js index 7cac177c..5975f52f 100644 --- a/src-ui/logics/common/index.js +++ b/src-ui/logics/common/index.js @@ -14,4 +14,5 @@ export { useHandleNetworkConnection } from "./useHandleNetworkConnection"; export { useHandleOscQuery } from "./useHandleOscQuery"; export { useIsOscAvailable } from "./useIsOscAvailable"; export { useIsVrctAvailable } from "./useIsVrctAvailable"; -export { useFetch } from "./useFetch"; \ No newline at end of file +export { useFetch } from "./useFetch"; +export { useLLMConnection } from "./useLLMConnection"; \ No newline at end of file diff --git a/src-ui/logics/common/useLLMConnection.js b/src-ui/logics/common/useLLMConnection.js new file mode 100644 index 00000000..70bd350a --- /dev/null +++ b/src-ui/logics/common/useLLMConnection.js @@ -0,0 +1,47 @@ +import { useStdoutToPython } from "@useStdoutToPython"; +import { + useStore_IsLMStudioConnected, + useStore_IsOllamaConnected, +} from "@store"; + +export const useLLMConnection = () => { + const { asyncStdoutToPython } = useStdoutToPython(); + const { + currentIsLMStudioConnected, + updateIsLMStudioConnected, + pendingIsLMStudioConnected, + } = useStore_IsLMStudioConnected(); + const { + currentIsOllamaConnected, + updateIsOllamaConnected, + pendingIsOllamaConnected, + } = useStore_IsOllamaConnected(); + + const checkConnection_LMStudio = () => { + pendingIsLMStudioConnected(); + asyncStdoutToPython("/run/lmstudio_connection"); + }; + const setConnectionStatus_LMStudio = (is_connected) => { + updateIsLMStudioConnected(is_connected); + }; + + const checkConnection_Ollama = () => { + pendingIsOllamaConnected(); + asyncStdoutToPython("/run/ollama_connection"); + }; + const setConnectionStatus_Ollama = (is_connected) => { + updateIsOllamaConnected(is_connected); + }; + + return { + currentIsLMStudioConnected, + updateIsLMStudioConnected, + setConnectionStatus_LMStudio, + checkConnection_LMStudio, + + currentIsOllamaConnected, + updateIsOllamaConnected, + setConnectionStatus_Ollama, + checkConnection_Ollama, + }; +}; \ No newline at end of file diff --git a/src-ui/logics/store.js b/src-ui/logics/store.js index 8f332a6e..831d63da 100644 --- a/src-ui/logics/store.js +++ b/src-ui/logics/store.js @@ -167,6 +167,8 @@ export const { atomInstance: Atom_NotificationStatus, useHook: useStore_Notifica key: 0, message: "", }, "NotificationStatus"); +export const { atomInstance: Atom_IsLMStudioConnected, useHook: useStore_IsLMStudioConnected } = createAtomWithHook(false, "IsLMStudioConnected", {is_state_ok: true}); +export const { atomInstance: Atom_IsOllamaConnected, useHook: useStore_IsOllamaConnected } = createAtomWithHook(false, "IsOllamaConnected", {is_state_ok: true}); // Main Page // Common diff --git a/src-ui/logics/useReceiveRoutes.js b/src-ui/logics/useReceiveRoutes.js index e9936936..c3368c96 100644 --- a/src-ui/logics/useReceiveRoutes.js +++ b/src-ui/logics/useReceiveRoutes.js @@ -20,6 +20,9 @@ export const STATIC_ROUTE_META_LIST = [ { endpoint: "/run/open_filepath_logs", ns: common, hook_name: "useOpenFolder", method_name: "openedFolder_MessageLogs" }, { endpoint: "/run/open_filepath_config_file", ns: common, hook_name: "useOpenFolder", method_name: "openedFolder_ConfigFile" }, + { endpoint: "/run/lmstudio_connection", ns: common, hook_name: "useLLMConnection", method_name: "setConnectionStatus_LMStudio" }, + { endpoint: "/run/ollama_connection", ns: common, hook_name: "useLLMConnection", method_name: "setConnectionStatus_Ollama" }, + // Software Version { endpoint: "/get/data/version", ns: common, hook_name: "useSoftwareVersion", method_name: "updateSoftwareVersion" }, // Latest Software Version Info diff --git a/src-ui/views/app/config_page/setting_section/setting_box/_components/connection_check_button/ConnectionCheckButton.jsx b/src-ui/views/app/config_page/setting_section/setting_box/_components/connection_check_button/ConnectionCheckButton.jsx new file mode 100644 index 00000000..075a0e10 --- /dev/null +++ b/src-ui/views/app/config_page/setting_section/setting_box/_components/connection_check_button/ConnectionCheckButton.jsx @@ -0,0 +1,19 @@ +import styles from "./ConnectionCheckButton.module.scss"; + +export const ConnectionCheckButton = (props) => { + const label = props.state === "pending" + ? "Checking... 🌀" + : props.variable === true + ? "Connected ✅" + : "Disconnected ❌"; + + return ( +
+

{label}

+

{`UI Status: ${props.state}`}

+ +
+ ); +}; \ No newline at end of file diff --git a/src-ui/views/app/config_page/setting_section/setting_box/_components/connection_check_button/ConnectionCheckButton.module.scss b/src-ui/views/app/config_page/setting_section/setting_box/_components/connection_check_button/ConnectionCheckButton.module.scss new file mode 100644 index 00000000..116feab4 --- /dev/null +++ b/src-ui/views/app/config_page/setting_section/setting_box/_components/connection_check_button/ConnectionCheckButton.module.scss @@ -0,0 +1,15 @@ +.button_wrapper { + padding: 1.6rem; + border-radius: 0.4rem; + &:hover { + background-color: var(--dark_825_color); + } + &:active { + background-color: var(--dark_900_color); + } +} + +.button_svg { + width: 2.4rem; + color: var(--dark_400_color); +} \ No newline at end of file diff --git a/src-ui/views/app/config_page/setting_section/setting_box/_components/index.js b/src-ui/views/app/config_page/setting_section/setting_box/_components/index.js index 2e7b54ca..d28f063d 100644 --- a/src-ui/views/app/config_page/setting_section/setting_box/_components/index.js +++ b/src-ui/views/app/config_page/setting_section/setting_box/_components/index.js @@ -13,4 +13,5 @@ export { SwitchBox } from "./switch_box/SwitchBox"; export { ThresholdComponent } from "./threshold_component/ThresholdComponent"; export { WordFilter, WordFilterListToggleComponent } from "./word_filter/WordFilter"; export { DownloadModels } from "./download_models/DownloadModels"; -export { MessageFormat } from "./message_format/MessageFormat"; \ No newline at end of file +export { MessageFormat } from "./message_format/MessageFormat"; +export { ConnectionCheckButton } from "./connection_check_button/ConnectionCheckButton"; \ No newline at end of file diff --git a/src-ui/views/app/config_page/setting_section/setting_box/_templates/Templates.jsx b/src-ui/views/app/config_page/setting_section/setting_box/_templates/Templates.jsx index 0c0845e1..b4952c99 100644 --- a/src-ui/views/app/config_page/setting_section/setting_box/_templates/Templates.jsx +++ b/src-ui/views/app/config_page/setting_section/setting_box/_templates/Templates.jsx @@ -19,6 +19,7 @@ import { WordFilterListToggleComponent, DownloadModels, MessageFormat, + ConnectionCheckButton, } from "../_components"; import { Checkbox } from "@common_components"; @@ -181,6 +182,10 @@ export const DownloadModelsContainer = (props) => ( ); +export const ConnectionCheckButtonContainer = (props) => ( + +); + export const MessageFormatContainer = (props) => { return ( <> diff --git a/src-ui/views/app/config_page/setting_section/setting_box/translation/Translation.jsx b/src-ui/views/app/config_page/setting_section/setting_box/translation/Translation.jsx index 7ad243ff..5a496206 100644 --- a/src-ui/views/app/config_page/setting_section/setting_box/translation/Translation.jsx +++ b/src-ui/views/app/config_page/setting_section/setting_box/translation/Translation.jsx @@ -17,6 +17,7 @@ import { EntryWithSaveButtonContainer, RadioButtonContainer, DropdownMenuContainer, + ConnectionCheckButtonContainer, useOnMouseLeaveDropdownMenu, } from "../_templates/Templates"; @@ -25,9 +26,11 @@ import { DropdownMenu, MultiDropdownMenu, LabelComponent, + ConnectionCheckButton, } from "../_components"; import { deepl_auth_key_url } from "@ui_configs"; +import { useLLMConnection } from "@logics_common"; export const Translation = () => { return ( @@ -46,9 +49,11 @@ export const Translation = () => { + + ); @@ -422,6 +427,23 @@ const OpenAIModelContainer = () => { +const LMStudioConnectionCheck_Box = () => { + const { t } = useI18n(); + const { currentIsLMStudioConnected, checkConnection_LMStudio } = useLLMConnection(); + + return ( + <> + + + ); +}; const LMStudioURL_Box = () => { const { t } = useI18n(); const { currentLMStudioURL, setLMStudioURL, deleteLMStudioURL } = useTranslation(); @@ -475,6 +497,23 @@ const LMStudioModelContainer = () => { ); }; +const OllamaConnectionCheck_Box = () => { + const { t } = useI18n(); + const { currentIsOllamaConnected, checkConnection_Ollama } = useLLMConnection(); + + return ( + <> + + + ); +}; const OllamaModelContainer = () => { const { t } = useI18n(); const {