From edf05759259f28132334c181361dd727584e3b70 Mon Sep 17 00:00:00 2001 From: LordMathis Date: Tue, 23 Sep 2025 21:44:04 +0200 Subject: [PATCH] Replace SystemInfoDialog with BackendInfoDialog and update related references --- webui/src/App.tsx | 16 +- webui/src/components/BackendInfoDialog.tsx | 274 +++++++++++++++++++++ webui/src/components/SystemInfoDialog.tsx | 203 --------------- webui/src/lib/api.ts | 2 +- 4 files changed, 283 insertions(+), 212 deletions(-) create mode 100644 webui/src/components/BackendInfoDialog.tsx delete mode 100644 webui/src/components/SystemInfoDialog.tsx diff --git a/webui/src/App.tsx b/webui/src/App.tsx index 04c8c01..b58e54f 100644 --- a/webui/src/App.tsx +++ b/webui/src/App.tsx @@ -3,7 +3,7 @@ import Header from "@/components/Header"; import InstanceList from "@/components/InstanceList"; import InstanceDialog from "@/components/InstanceDialog"; import LoginDialog from "@/components/LoginDialog"; -import SystemInfoDialog from "./components/SystemInfoDialog"; +import BackendInfoDialog from "./components/BackendInfoDialog"; import { type CreateInstanceOptions, type Instance } from "@/types/instance"; import { useInstances } from "@/contexts/InstancesContext"; import { useAuth } from "@/contexts/AuthContext"; @@ -13,7 +13,7 @@ import { Toaster } from "sonner"; function App() { const { isAuthenticated, isLoading: authLoading } = useAuth(); const [isInstanceModalOpen, setIsInstanceModalOpen] = useState(false); - const [isSystemInfoModalOpen, setIsSystemInfoModalOpen] = useState(false); + const [isBackendInfoModalOpen, setIsBackendInfoModalOpen] = useState(false); const [editingInstance, setEditingInstance] = useState( undefined ); @@ -37,8 +37,8 @@ function App() { } }; - const handleShowSystemInfo = () => { - setIsSystemInfoModalOpen(true); + const handleShowBackendInfo = () => { + setIsBackendInfoModalOpen(true); }; // Show loading spinner while checking auth @@ -70,7 +70,7 @@ function App() { return (
-
+
@@ -82,9 +82,9 @@ function App() { instance={editingInstance} /> - diff --git a/webui/src/components/BackendInfoDialog.tsx b/webui/src/components/BackendInfoDialog.tsx new file mode 100644 index 0000000..9ce0881 --- /dev/null +++ b/webui/src/components/BackendInfoDialog.tsx @@ -0,0 +1,274 @@ +import React, { useState, useEffect } from 'react' +import { Button } from '@/components/ui/button' +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog' +import SelectInput from '@/components/form/SelectInput' +import { + RefreshCw, + AlertCircle, + Loader2, + ChevronDown, + ChevronRight, + Monitor, + HelpCircle, + Info +} from 'lucide-react' +import { serverApi } from '@/lib/api' + +// Helper to get version from environment +const getAppVersion = (): string => { + try { + return (import.meta.env as Record).VITE_APP_VERSION || 'unknown' + } catch { + return 'unknown' + } +} + +interface BackendInfoDialogProps { + open: boolean + onOpenChange: (open: boolean) => void +} + +interface BackendInfo { + version: string + devices: string + help: string +} + +type BackendType = 'llama-cpp' | 'mlx' | 'vllm' + +const BACKEND_OPTIONS = [ + { value: 'llama-cpp', label: 'Llama.cpp' }, + { value: 'mlx', label: 'MLX' }, + { value: 'vllm', label: 'vLLM' }, +] as const + +const BackendInfoDialog: React.FC = ({ + open, + onOpenChange +}) => { + const [selectedBackend, setSelectedBackend] = useState('llama-cpp') + const [backendInfo, setBackendInfo] = useState(null) + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + const [showHelp, setShowHelp] = useState(false) + + // Fetch backend info + const fetchBackendInfo = async (backend: BackendType) => { + if (backend !== 'llama-cpp') { + setBackendInfo(null) + setError(null) + return + } + + setLoading(true) + setError(null) + + try { + const [version, devices, help] = await Promise.all([ + serverApi.getVersion(), + serverApi.getDevices(), + serverApi.getHelp() + ]) + + setBackendInfo({ version, devices, help }) + } catch (err) { + setError(err instanceof Error ? err.message : 'Failed to fetch backend info') + } finally { + setLoading(false) + } + } + + // Load data when dialog opens or backend changes + useEffect(() => { + if (open) { + fetchBackendInfo(selectedBackend) + } + }, [open, selectedBackend]) + + const handleBackendChange = (value: string) => { + setSelectedBackend(value as BackendType) + setShowHelp(false) // Reset help section when switching backends + } + + const renderBackendContent = () => { + if (selectedBackend !== 'llama-cpp') { + return ( +
+
+ +
+

Backend Info Not Available

+

+ Information for {BACKEND_OPTIONS.find(b => b.value === selectedBackend)?.label} backend is not yet implemented. +

+
+
+
+ ) + } + + if (loading && !backendInfo) { + return ( +
+ + Loading backend information... +
+ ) + } + + if (error) { + return ( +
+ + {error} +
+ ) + } + + if (!backendInfo) { + return null + } + + return ( +
+ {/* Llamactl Version Section */} +
+

Llamactl Version

+ +
+
+              {getAppVersion()}
+            
+
+
+ + {/* Backend Version Section */} +
+

+ {BACKEND_OPTIONS.find(b => b.value === selectedBackend)?.label} Version +

+ +
+
+ $ llama-server --version +
+
+              {backendInfo.version}
+            
+
+
+ + {/* Devices Section */} +
+
+

Available Devices

+
+ +
+
+ $ llama-server --list-devices +
+
+              {backendInfo.devices}
+            
+
+
+ + {/* Help Section */} +
+ + + {showHelp && ( +
+
+ $ llama-server --help +
+
+                {backendInfo.help}
+              
+
+ )} +
+
+ ) + } + + return ( + + + +
+
+ + + Backend Information + + + View backend-specific environment and capabilities + +
+ +
+
+ handleBackendChange(value || 'llama-cpp')} + options={BACKEND_OPTIONS} + className="text-sm" + /> +
+ + {selectedBackend === 'llama-cpp' && ( + + )} +
+
+
+ +
+ {renderBackendContent()} +
+ + + + +
+
+ ) +} + +export default BackendInfoDialog \ No newline at end of file diff --git a/webui/src/components/SystemInfoDialog.tsx b/webui/src/components/SystemInfoDialog.tsx deleted file mode 100644 index 8eb03f5..0000000 --- a/webui/src/components/SystemInfoDialog.tsx +++ /dev/null @@ -1,203 +0,0 @@ -import React, { useState, useEffect } from 'react' -import { Button } from '@/components/ui/button' -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, -} from '@/components/ui/dialog' -import { - RefreshCw, - AlertCircle, - Loader2, - ChevronDown, - ChevronRight, - Monitor, - HelpCircle -} from 'lucide-react' -import { serverApi } from '@/lib/api' - -// Helper to get version from environment -const getAppVersion = (): string => { - try { - return (import.meta.env as Record).VITE_APP_VERSION || 'unknown' - } catch { - return 'unknown' - } -} - -interface SystemInfoModalProps { - open: boolean - onOpenChange: (open: boolean) => void -} - -interface SystemInfo { - version: string - devices: string - help: string -} - -const SystemInfoDialog: React.FC = ({ - open, - onOpenChange -}) => { - const [systemInfo, setSystemInfo] = useState(null) - const [loading, setLoading] = useState(false) - const [error, setError] = useState(null) - const [showHelp, setShowHelp] = useState(false) - - // Fetch system info - const fetchSystemInfo = async () => { - setLoading(true) - setError(null) - - try { - const [version, devices, help] = await Promise.all([ - serverApi.getVersion(), - serverApi.getDevices(), - serverApi.getHelp() - ]) - - setSystemInfo({ version, devices, help }) - } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to fetch system info') - } finally { - setLoading(false) - } - } - - // Load data when dialog opens - useEffect(() => { - if (open) { - fetchSystemInfo() - } - }, [open]) - - return ( - - - -
-
- - - System Information - - - Llama.cpp server environment and capabilities - -
- - -
-
- -
- {loading && !systemInfo ? ( -
- - Loading system information... -
- ) : error ? ( -
- - {error} -
- ) : systemInfo ? ( -
- {/* Llamactl Version Section */} -
-

Llamactl Version

- -
-
-                    {getAppVersion()}
-                  
-
-
- - {/* Llama Server Version Section */} -
-

Llama Server Version

- -
-
- $ llama-server --version -
-
-                    {systemInfo.version}
-                  
-
-
- - {/* Devices Section */} -
-
-

Available Devices

-
- -
-
- $ llama-server --list-devices -
-
-                    {systemInfo.devices}
-                  
-
-
- - {/* Help Section */} -
- - - {showHelp && ( -
-
- $ llama-server --help -
-
-                      {systemInfo.help}
-                    
-
- )} -
-
- ) : null} -
- - - - -
-
- ) -} - -export default SystemInfoDialog \ No newline at end of file diff --git a/webui/src/lib/api.ts b/webui/src/lib/api.ts index be9ab80..5bd7991 100644 --- a/webui/src/lib/api.ts +++ b/webui/src/lib/api.ts @@ -156,5 +156,5 @@ export const instancesApi = { }, // GET /instances/{name}/proxy/health - getHealth: (name: string) => apiCall(`/instances/${name}/proxy/health`), + getHealth: (name: string) => apiCall>(`/instances/${name}/proxy/health`), };