mirror of
https://github.com/lordmathis/llamactl.git
synced 2025-12-22 09:04:22 +00:00
Implement ConfigContext for instance defaults
This commit is contained in:
@@ -14,6 +14,7 @@ import ParseCommandDialog from "@/components/ParseCommandDialog";
|
||||
import InstanceSettingsCard from "@/components/instance/InstanceSettingsCard";
|
||||
import BackendConfigurationCard from "@/components/instance/BackendConfigurationCard";
|
||||
import { Upload } from "lucide-react";
|
||||
import { useInstanceDefaults } from "@/contexts/ConfigContext";
|
||||
|
||||
interface InstanceDialogProps {
|
||||
open: boolean;
|
||||
@@ -29,6 +30,7 @@ const InstanceDialog: React.FC<InstanceDialogProps> = ({
|
||||
instance,
|
||||
}) => {
|
||||
const isEditing = !!instance;
|
||||
const instanceDefaults = useInstanceDefaults();
|
||||
|
||||
const [instanceName, setInstanceName] = useState("");
|
||||
const [formData, setFormData] = useState<CreateInstanceOptions>({});
|
||||
@@ -45,17 +47,20 @@ const InstanceDialog: React.FC<InstanceDialogProps> = ({
|
||||
setInstanceName(instance.name);
|
||||
setFormData(instance.options || {});
|
||||
} else {
|
||||
// Reset form for new instance
|
||||
// Reset form for new instance with defaults from config
|
||||
setInstanceName("");
|
||||
setFormData({
|
||||
auto_restart: true, // Default value
|
||||
auto_restart: instanceDefaults?.autoRestart ?? true,
|
||||
max_restarts: instanceDefaults?.maxRestarts,
|
||||
restart_delay: instanceDefaults?.restartDelay,
|
||||
on_demand_start: instanceDefaults?.onDemandStart,
|
||||
backend_type: BackendType.LLAMA_CPP, // Default backend type
|
||||
backend_options: {},
|
||||
});
|
||||
}
|
||||
setNameError(""); // Reset any name errors
|
||||
}
|
||||
}, [open, instance]);
|
||||
}, [open, instance, instanceDefaults]);
|
||||
|
||||
const handleFieldChange = (key: keyof CreateInstanceOptions, value: unknown) => {
|
||||
setFormData((prev) => {
|
||||
|
||||
100
webui/src/contexts/ConfigContext.tsx
Normal file
100
webui/src/contexts/ConfigContext.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
import { type ReactNode, createContext, useCallback, useContext, useEffect, useState } from 'react'
|
||||
import { serverApi } from '@/lib/api'
|
||||
import type { AppConfig } from '@/types/config'
|
||||
|
||||
interface ConfigContextState {
|
||||
config: AppConfig | null
|
||||
isLoading: boolean
|
||||
error: string | null
|
||||
}
|
||||
|
||||
interface ConfigContextActions {
|
||||
refetchConfig: () => Promise<void>
|
||||
}
|
||||
|
||||
type ConfigContextType = ConfigContextState & ConfigContextActions
|
||||
|
||||
const ConfigContext = createContext<ConfigContextType | undefined>(undefined)
|
||||
|
||||
interface ConfigProviderProps {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export const ConfigProvider = ({ children }: ConfigProviderProps) => {
|
||||
const [config, setConfig] = useState<AppConfig | null>(null)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
const fetchConfig = useCallback(async () => {
|
||||
setIsLoading(true)
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
const data = await serverApi.getConfig()
|
||||
setConfig(data)
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to load configuration'
|
||||
setError(errorMessage)
|
||||
console.error('Error loading config:', err)
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Load config on mount
|
||||
useEffect(() => {
|
||||
void fetchConfig()
|
||||
}, [fetchConfig])
|
||||
|
||||
const refetchConfig = useCallback(async () => {
|
||||
await fetchConfig()
|
||||
}, [fetchConfig])
|
||||
|
||||
const value: ConfigContextType = {
|
||||
config,
|
||||
isLoading,
|
||||
error,
|
||||
refetchConfig,
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfigContext.Provider value={value}>
|
||||
{children}
|
||||
</ConfigContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useConfig = (): ConfigContextType => {
|
||||
const context = useContext(ConfigContext)
|
||||
if (context === undefined) {
|
||||
throw new Error('useConfig must be used within a ConfigProvider')
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
// Helper hook to get instance default values from config
|
||||
export const useInstanceDefaults = () => {
|
||||
const { config } = useConfig()
|
||||
|
||||
if (!config) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
autoRestart: config.instances.default_auto_restart,
|
||||
maxRestarts: config.instances.default_max_restarts,
|
||||
restartDelay: config.instances.default_restart_delay,
|
||||
onDemandStart: config.instances.default_on_demand_start,
|
||||
}
|
||||
}
|
||||
|
||||
// Helper hook to get backend settings from config
|
||||
export const useBackendConfig = () => {
|
||||
const { config } = useConfig()
|
||||
|
||||
if (!config) {
|
||||
return null
|
||||
}
|
||||
|
||||
return config.backends
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { CreateInstanceOptions, Instance } from "@/types/instance";
|
||||
import type { AppConfig } from "@/types/config";
|
||||
import { handleApiError } from "./errorUtils";
|
||||
|
||||
// Adding baseURI as a prefix to support being served behind a subpath
|
||||
@@ -73,6 +74,9 @@ export const serverApi = {
|
||||
|
||||
// GET /backends/llama-cpp/devices
|
||||
getDevices: () => apiCall<string>("/backends/llama-cpp/devices", {}, "text"),
|
||||
|
||||
// GET /config
|
||||
getConfig: () => apiCall<AppConfig>("/config"),
|
||||
};
|
||||
|
||||
// Backend API functions
|
||||
|
||||
@@ -4,13 +4,16 @@ import App from './App'
|
||||
import { InstancesProvider } from './contexts/InstancesContext'
|
||||
import './index.css'
|
||||
import { AuthProvider } from './contexts/AuthContext'
|
||||
import { ConfigProvider } from './contexts/ConfigContext'
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
<React.StrictMode>
|
||||
<AuthProvider>
|
||||
<InstancesProvider>
|
||||
<App />
|
||||
</InstancesProvider>
|
||||
<ConfigProvider>
|
||||
<InstancesProvider>
|
||||
<App />
|
||||
</InstancesProvider>
|
||||
</ConfigProvider>
|
||||
</AuthProvider>
|
||||
</React.StrictMode>,
|
||||
)
|
||||
70
webui/src/types/config.ts
Normal file
70
webui/src/types/config.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
export interface BackendSettings {
|
||||
command: string
|
||||
args: string[]
|
||||
environment?: Record<string, string>
|
||||
docker?: DockerSettings
|
||||
response_headers?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface DockerSettings {
|
||||
enabled: boolean
|
||||
image: string
|
||||
args: string[]
|
||||
environment?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface BackendConfig {
|
||||
'llama-cpp': BackendSettings
|
||||
vllm: BackendSettings
|
||||
mlx: BackendSettings
|
||||
}
|
||||
|
||||
export interface ServerConfig {
|
||||
host: string
|
||||
port: number
|
||||
allowed_origins: string[]
|
||||
allowed_headers: string[]
|
||||
enable_swagger: boolean
|
||||
response_headers?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface InstancesConfig {
|
||||
port_range: [number, number]
|
||||
data_dir: string
|
||||
configs_dir: string
|
||||
logs_dir: string
|
||||
auto_create_dirs: boolean
|
||||
max_instances: number
|
||||
max_running_instances: number
|
||||
enable_lru_eviction: boolean
|
||||
default_auto_restart: boolean
|
||||
default_max_restarts: number
|
||||
default_restart_delay: number
|
||||
default_on_demand_start: boolean
|
||||
on_demand_start_timeout: number
|
||||
timeout_check_interval: number
|
||||
}
|
||||
|
||||
export interface AuthConfig {
|
||||
require_inference_auth: boolean
|
||||
inference_keys: string[] // Will be empty in sanitized response
|
||||
require_management_auth: boolean
|
||||
management_keys: string[] // Will be empty in sanitized response
|
||||
}
|
||||
|
||||
export interface NodeConfig {
|
||||
address: string
|
||||
api_key: string // Will be empty in sanitized response
|
||||
}
|
||||
|
||||
export interface AppConfig {
|
||||
server: ServerConfig
|
||||
backends: BackendConfig
|
||||
instances: InstancesConfig
|
||||
auth: AuthConfig
|
||||
local_node: string
|
||||
nodes: Record<string, NodeConfig>
|
||||
version?: string
|
||||
commit_hash?: string
|
||||
build_time?: string
|
||||
}
|
||||
Reference in New Issue
Block a user