import { createFileRoute } from '@tanstack/react-router' import { route } from '@/constants/routes' import HeaderPage from '@/containers/HeaderPage' import SettingsMenu from '@/containers/SettingsMenu' import { Card, CardItem } from '@/containers/Card' import { Switch } from '@/components/ui/switch' import { Button } from '@/components/ui/button' import { useTranslation } from 'react-i18next' import { ServerHostSwitcher } from '@/containers/ServerHostSwitcher' import { PortInput } from '@/containers/PortInput' import { ApiPrefixInput } from '@/containers/ApiPrefixInput' import { TrustedHostsInput } from '@/containers/TrustedHostsInput' import { useLocalApiServer } from '@/hooks/useLocalApiServer' import { WebviewWindow } from '@tauri-apps/api/webviewWindow' import { useAppState } from '@/hooks/useAppState' import { windowKey } from '@/constants/windows' import { IconLogs } from '@tabler/icons-react' import { cn } from '@/lib/utils' import { ApiKeyInput } from '@/containers/ApiKeyInput' import { useEffect, useState } from 'react' import { invoke } from '@tauri-apps/api/core' // eslint-disable-next-line @typescript-eslint/no-explicit-any export const Route = createFileRoute(route.settings.local_api_server as any)({ component: LocalAPIServer, }) function LocalAPIServer() { const { t } = useTranslation() const { corsEnabled, setCorsEnabled, verboseLogs, setVerboseLogs, serverHost, serverPort, apiPrefix, apiKey, trustedHosts, } = useLocalApiServer() const { serverStatus, setServerStatus } = useAppState() const [showApiKeyError, setShowApiKeyError] = useState(false) const [isApiKeyEmpty, setIsApiKeyEmpty] = useState( !apiKey || apiKey.toString().trim().length === 0 ) useEffect(() => { const checkServerStatus = async () => { invoke('get_server_status').then((running) => { if (running) { setServerStatus('running') } }) } checkServerStatus() }, [setServerStatus]) const handleApiKeyValidation = (isValid: boolean) => { setIsApiKeyEmpty(!isValid) } const toggleAPIServer = async () => { // Validate API key before starting server if (serverStatus === 'stopped') { if (!apiKey || apiKey.toString().trim().length === 0) { setShowApiKeyError(true) return } setShowApiKeyError(false) } setServerStatus('pending') if (serverStatus === 'stopped') { window.core?.api ?.startServer({ host: serverHost, port: serverPort, prefix: apiPrefix, apiKey, trustedHosts, isCorsEnabled: corsEnabled, isVerboseEnabled: verboseLogs, }) .then(() => { setServerStatus('running') }) .catch((error: unknown) => { console.error('Error starting server:', error) setServerStatus('stopped') }) } else { window.core?.api ?.stopServer() .then(() => { setServerStatus('stopped') }) .catch((error: unknown) => { console.error('Error stopping server:', error) setServerStatus('stopped') }) } } const handleOpenLogs = async () => { try { // Check if logs window already exists const existingWindow = await WebviewWindow.getByLabel( windowKey.logsWindowLocalApiServer ) if (existingWindow) { // If window exists, focus it await existingWindow.setFocus() console.log('Focused existing logs window') } else { // Create a new logs window using Tauri v2 WebviewWindow API const logsWindow = new WebviewWindow( windowKey.logsWindowLocalApiServer, { url: route.localApiServerlogs, title: 'Local API server Logs - Jan', width: 800, height: 600, resizable: true, center: true, } ) // Listen for window creation logsWindow.once('tauri://created', () => { console.log('Logs window created') }) // Listen for window errors logsWindow.once('tauri://error', (e) => { console.error('Error creating logs window:', e) }) } } catch (error) { console.error('Failed to open logs window:', error) } } const isServerRunning = serverStatus === 'running' return (
Run an OpenAI-compatible server locally.