[Update] UI: Implement LLM connection handling and add connection check UI components.(Test UI)

This commit is contained in:
Sakamoto Shiina
2025-11-19 17:19:39 +09:00
parent e1125ae241
commit ef06cd1c7a
10 changed files with 152 additions and 2 deletions

View File

@@ -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;

View File

@@ -14,4 +14,5 @@ export { useHandleNetworkConnection } from "./useHandleNetworkConnection";
export { useHandleOscQuery } from "./useHandleOscQuery";
export { useIsOscAvailable } from "./useIsOscAvailable";
export { useIsVrctAvailable } from "./useIsVrctAvailable";
export { useFetch } from "./useFetch";
export { useFetch } from "./useFetch";
export { useLLMConnection } from "./useLLMConnection";

View File

@@ -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,
};
};

View File

@@ -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

View File

@@ -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

View File

@@ -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 (
<div className={styles.container}>
<p>{label}</p>
<p>{`UI Status: ${props.state}`}</p>
<button className={styles.button_wrapper} onClick={props.checkFunction}>
<p className={styles.button_label}>Connection Check</p>
</button>
</div>
);
};

View File

@@ -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);
}

View File

@@ -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";
export { MessageFormat } from "./message_format/MessageFormat";
export { ConnectionCheckButton } from "./connection_check_button/ConnectionCheckButton";

View File

@@ -19,6 +19,7 @@ import {
WordFilterListToggleComponent,
DownloadModels,
MessageFormat,
ConnectionCheckButton,
} from "../_components";
import { Checkbox } from "@common_components";
@@ -181,6 +182,10 @@ export const DownloadModelsContainer = (props) => (
<CommonContainer Component={DownloadModels} {...props} />
);
export const ConnectionCheckButtonContainer = (props) => (
<CommonContainer Component={ConnectionCheckButton} {...props} />
);
export const MessageFormatContainer = (props) => {
return (
<>

View File

@@ -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 = () => {
<OpenAIAuthKey_Box />
<OpenAIModelContainer />
<LMStudioConnectionCheck_Box />
<LMStudioURL_Box />
<LMStudioModelContainer />
<OllamaConnectionCheck_Box />
<OllamaModelContainer />
</>
);
@@ -422,6 +427,23 @@ const OpenAIModelContainer = () => {
const LMStudioConnectionCheck_Box = () => {
const { t } = useI18n();
const { currentIsLMStudioConnected, checkConnection_LMStudio } = useLLMConnection();
return (
<>
<ConnectionCheckButtonContainer
label="Check LM Studio Connection"
variable={currentIsLMStudioConnected.data}
state={currentIsLMStudioConnected.state}
checkFunction={checkConnection_LMStudio}
remove_border_bottom={true}
// width="10rem"
/>
</>
);
};
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 (
<>
<ConnectionCheckButtonContainer
label="Check Ollama Connection"
variable={currentIsOllamaConnected.data}
state={currentIsOllamaConnected.state}
checkFunction={checkConnection_Ollama}
remove_border_bottom={true}
// width="10rem"
/>
</>
);
};
const OllamaModelContainer = () => {
const { t } = useI18n();
const {