mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
487 lines
14 KiB
TypeScript
487 lines
14 KiB
TypeScript
import { create } from 'zustand';
|
|
import type { ConfigFile, SdConvDirectMode } from '@/types';
|
|
import type { ImageModelPreset } from '@/constants/imageModelPresets';
|
|
import { DEFAULT_CONTEXT_SIZE } from '@/constants';
|
|
|
|
interface LaunchConfigState {
|
|
gpuLayers: number;
|
|
autoGpuLayers: boolean;
|
|
contextSize: number;
|
|
model: string;
|
|
additionalArguments: string;
|
|
port?: number;
|
|
host: string;
|
|
multiuser: boolean;
|
|
multiplayer: boolean;
|
|
remotetunnel: boolean;
|
|
nocertify: boolean;
|
|
websearch: boolean;
|
|
noshift: boolean;
|
|
flashattention: boolean;
|
|
noavx2: boolean;
|
|
failsafe: boolean;
|
|
lowvram: boolean;
|
|
quantmatmul: boolean;
|
|
usemmap: boolean;
|
|
backend: string;
|
|
gpuDeviceSelection: string;
|
|
tensorSplit: string;
|
|
gpuPlatform: number;
|
|
sdmodel: string;
|
|
sdt5xxl: string;
|
|
sdclipl: string;
|
|
sdclipg: string;
|
|
sdphotomaker: string;
|
|
sdvae: string;
|
|
sdlora: string;
|
|
sdconvdirect: SdConvDirectMode;
|
|
moecpu: number;
|
|
moeexperts: number;
|
|
isImageGenerationMode: boolean;
|
|
|
|
setGpuLayers: (layers: number) => void;
|
|
setAutoGpuLayers: (auto: boolean) => void;
|
|
setContextSize: (size: number) => void;
|
|
setModel: (path: string) => void;
|
|
setAdditionalArguments: (args: string) => void;
|
|
setPort: (port?: number) => void;
|
|
setHost: (host: string) => void;
|
|
setMultiuser: (multiuser: boolean) => void;
|
|
setMultiplayer: (multiplayer: boolean) => void;
|
|
setRemotetunnel: (remotetunnel: boolean) => void;
|
|
setNocertify: (nocertify: boolean) => void;
|
|
setWebsearch: (websearch: boolean) => void;
|
|
setNoshift: (noshift: boolean) => void;
|
|
setFlashattention: (flashattention: boolean) => void;
|
|
setNoavx2: (noavx2: boolean) => void;
|
|
setFailsafe: (failsafe: boolean) => void;
|
|
setLowvram: (lowvram: boolean) => void;
|
|
setQuantmatmul: (quantmatmul: boolean) => void;
|
|
setUsemmap: (usemmap: boolean) => void;
|
|
setBackend: (backend: string) => void;
|
|
setGpuDeviceSelection: (selection: string) => void;
|
|
setTensorSplit: (split: string) => void;
|
|
setGpuPlatform: (platform: number) => void;
|
|
setSdmodel: (model: string) => void;
|
|
setSdt5xxl: (model: string) => void;
|
|
setSdclipl: (model: string) => void;
|
|
setSdclipg: (model: string) => void;
|
|
setSdphotomaker: (model: string) => void;
|
|
setSdvae: (vae: string) => void;
|
|
setSdlora: (loraModel: string) => void;
|
|
setSdconvdirect: (mode: SdConvDirectMode) => void;
|
|
setMoecpu: (moecpu: number) => void;
|
|
setMoeexperts: (moeexperts: number) => void;
|
|
|
|
parseAndApplyConfigFile: (configPath: string) => Promise<void>;
|
|
loadConfigFromFile: (
|
|
configFiles: ConfigFile[],
|
|
savedConfig: string | null
|
|
) => Promise<string | null>;
|
|
selectModelFile: () => Promise<void>;
|
|
selectSdmodelFile: () => Promise<void>;
|
|
selectSdt5xxlFile: () => Promise<void>;
|
|
selectSdcliplFile: () => Promise<void>;
|
|
selectSdclipgFile: () => Promise<void>;
|
|
selectSdphotomakerFile: () => Promise<void>;
|
|
selectSdvaeFile: () => Promise<void>;
|
|
selectSdloraFile: () => Promise<void>;
|
|
contextSizeChangeWithStep: (size: number) => void;
|
|
applyImageModelPreset: (preset: ImageModelPreset) => void;
|
|
}
|
|
|
|
export const useLaunchConfigStore = create<LaunchConfigState>((set, get) => ({
|
|
gpuLayers: 0,
|
|
autoGpuLayers: true,
|
|
contextSize: DEFAULT_CONTEXT_SIZE,
|
|
model: '',
|
|
additionalArguments: '',
|
|
port: undefined,
|
|
host: '',
|
|
multiuser: false,
|
|
multiplayer: false,
|
|
remotetunnel: false,
|
|
nocertify: false,
|
|
websearch: false,
|
|
noshift: false,
|
|
flashattention: true,
|
|
noavx2: false,
|
|
failsafe: false,
|
|
lowvram: false,
|
|
quantmatmul: true,
|
|
usemmap: true,
|
|
backend: '',
|
|
gpuDeviceSelection: '0',
|
|
tensorSplit: '',
|
|
gpuPlatform: 0,
|
|
sdmodel: '',
|
|
sdt5xxl: '',
|
|
sdclipl: '',
|
|
sdclipg: '',
|
|
sdphotomaker: '',
|
|
sdvae: '',
|
|
sdlora: '',
|
|
sdconvdirect: 'off' as const,
|
|
moecpu: 0,
|
|
moeexperts: -1,
|
|
|
|
isImageGenerationMode: false,
|
|
|
|
setGpuLayers: (layers) => set({ gpuLayers: layers }),
|
|
setAutoGpuLayers: (auto) => set({ autoGpuLayers: auto }),
|
|
setContextSize: (size) => set({ contextSize: size }),
|
|
setModel: (path) => set({ model: path }),
|
|
setAdditionalArguments: (args) => set({ additionalArguments: args }),
|
|
setPort: (port) => set({ port }),
|
|
setHost: (host) => set({ host }),
|
|
setMultiuser: (multiuser) => set({ multiuser }),
|
|
setMultiplayer: (multiplayer) => set({ multiplayer }),
|
|
setRemotetunnel: (remotetunnel) => set({ remotetunnel }),
|
|
setNocertify: (nocertify) => set({ nocertify }),
|
|
setWebsearch: (websearch) => set({ websearch }),
|
|
setNoshift: (noshift) => set({ noshift }),
|
|
setFlashattention: (flashattention) => set({ flashattention }),
|
|
setNoavx2: (noavx2) => set({ noavx2 }),
|
|
setFailsafe: (failsafe) => set({ failsafe }),
|
|
setLowvram: (lowvram) => set({ lowvram }),
|
|
setQuantmatmul: (quantmatmul) => set({ quantmatmul }),
|
|
setUsemmap: (usemmap) => set({ usemmap }),
|
|
setBackend: (backend) =>
|
|
set({
|
|
backend,
|
|
gpuDeviceSelection: '0',
|
|
tensorSplit: '',
|
|
}),
|
|
setGpuDeviceSelection: (selection) => set({ gpuDeviceSelection: selection }),
|
|
setTensorSplit: (split) => set({ tensorSplit: split }),
|
|
setGpuPlatform: (platform) => set({ gpuPlatform: platform }),
|
|
setSdmodel: (model) =>
|
|
set({
|
|
sdmodel: model,
|
|
isImageGenerationMode: Boolean(model?.trim()),
|
|
}),
|
|
setSdt5xxl: (model) => set({ sdt5xxl: model }),
|
|
setSdclipl: (model) => set({ sdclipl: model }),
|
|
setSdclipg: (model) => set({ sdclipg: model }),
|
|
setSdphotomaker: (model) => set({ sdphotomaker: model }),
|
|
setSdvae: (vae) => set({ sdvae: vae }),
|
|
setSdlora: (loraModel) => set({ sdlora: loraModel }),
|
|
setSdconvdirect: (mode) => set({ sdconvdirect: mode }),
|
|
setMoecpu: (moeCpu) => set({ moecpu: moeCpu }),
|
|
setMoeexperts: (moeExperts) => set({ moeexperts: moeExperts }),
|
|
|
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
parseAndApplyConfigFile: async (configPath: string) => {
|
|
const configData =
|
|
await window.electronAPI.kobold.parseConfigFile(configPath);
|
|
|
|
if (configData) {
|
|
const updates: Partial<LaunchConfigState> = {};
|
|
|
|
if (typeof configData.autoGpuLayers === 'boolean') {
|
|
updates.autoGpuLayers = configData.autoGpuLayers;
|
|
} else {
|
|
updates.autoGpuLayers = true;
|
|
}
|
|
|
|
if (typeof configData.gpulayers === 'number') {
|
|
updates.gpuLayers = configData.gpulayers;
|
|
} else {
|
|
updates.gpuLayers = 0;
|
|
}
|
|
|
|
if (typeof configData.contextsize === 'number') {
|
|
updates.contextSize = configData.contextsize;
|
|
} else {
|
|
updates.contextSize = DEFAULT_CONTEXT_SIZE;
|
|
}
|
|
|
|
if (typeof configData.model === 'string') {
|
|
updates.model = configData.model;
|
|
}
|
|
|
|
if (typeof configData.additionalArguments === 'string') {
|
|
updates.additionalArguments = configData.additionalArguments;
|
|
} else {
|
|
updates.additionalArguments = '';
|
|
}
|
|
|
|
if (typeof configData.port === 'number') {
|
|
updates.port = configData.port;
|
|
} else {
|
|
updates.port = undefined;
|
|
}
|
|
|
|
if (typeof configData.host === 'string') {
|
|
updates.host = configData.host;
|
|
} else {
|
|
updates.host = '';
|
|
}
|
|
|
|
if (typeof configData.multiuser === 'number') {
|
|
updates.multiuser = configData.multiuser === 1;
|
|
} else {
|
|
updates.multiuser = false;
|
|
}
|
|
|
|
if (typeof configData.multiplayer === 'boolean') {
|
|
updates.multiplayer = configData.multiplayer;
|
|
} else {
|
|
updates.multiplayer = false;
|
|
}
|
|
|
|
if (typeof configData.remotetunnel === 'boolean') {
|
|
updates.remotetunnel = configData.remotetunnel;
|
|
} else {
|
|
updates.remotetunnel = false;
|
|
}
|
|
|
|
if (typeof configData.nocertify === 'boolean') {
|
|
updates.nocertify = configData.nocertify;
|
|
} else {
|
|
updates.nocertify = false;
|
|
}
|
|
|
|
if (typeof configData.websearch === 'boolean') {
|
|
updates.websearch = configData.websearch;
|
|
} else {
|
|
updates.websearch = false;
|
|
}
|
|
|
|
if (typeof configData.noshift === 'boolean') {
|
|
updates.noshift = configData.noshift;
|
|
} else {
|
|
updates.noshift = false;
|
|
}
|
|
|
|
if (typeof configData.flashattention === 'boolean') {
|
|
updates.flashattention = configData.flashattention;
|
|
} else {
|
|
updates.flashattention = true;
|
|
}
|
|
|
|
if (typeof configData.noavx2 === 'boolean') {
|
|
updates.noavx2 = configData.noavx2;
|
|
} else {
|
|
updates.noavx2 = false;
|
|
}
|
|
|
|
if (typeof configData.failsafe === 'boolean') {
|
|
updates.failsafe = configData.failsafe;
|
|
} else {
|
|
updates.failsafe = false;
|
|
}
|
|
|
|
if (typeof configData.lowvram === 'boolean') {
|
|
updates.lowvram = configData.lowvram;
|
|
}
|
|
|
|
if (typeof configData.quantmatmul === 'boolean') {
|
|
updates.quantmatmul = configData.quantmatmul;
|
|
}
|
|
|
|
if (typeof configData.usemmap === 'boolean') {
|
|
updates.usemmap = configData.usemmap;
|
|
} else {
|
|
updates.usemmap = true;
|
|
}
|
|
|
|
if (configData.usecuda === true) {
|
|
const gpuInfo = await window.electronAPI.kobold.detectGPU();
|
|
updates.backend = gpuInfo.hasNVIDIA ? 'cuda' : 'rocm';
|
|
|
|
if (
|
|
Array.isArray(configData.usecuda) &&
|
|
configData.usecuda.length >= 3
|
|
) {
|
|
const [vramMode, deviceId, mmqMode] = configData.usecuda;
|
|
updates.lowvram = vramMode === 'lowvram';
|
|
updates.gpuDeviceSelection = deviceId || '0';
|
|
updates.quantmatmul = mmqMode === 'mmq';
|
|
}
|
|
} else if (configData.usevulkan === true) {
|
|
updates.backend = 'vulkan';
|
|
} else if (
|
|
Array.isArray(configData.useclblast) &&
|
|
configData.useclblast.length === 2
|
|
) {
|
|
updates.backend = 'clblast';
|
|
const [deviceIndex, platformIndex] = configData.useclblast;
|
|
updates.gpuDeviceSelection = deviceIndex.toString();
|
|
updates.gpuPlatform = platformIndex;
|
|
} else {
|
|
updates.backend = 'cpu';
|
|
}
|
|
|
|
if (typeof configData.gpuDeviceSelection === 'string') {
|
|
updates.gpuDeviceSelection = configData.gpuDeviceSelection;
|
|
}
|
|
|
|
if (typeof configData.tensorSplit === 'string') {
|
|
updates.tensorSplit = configData.tensorSplit;
|
|
}
|
|
|
|
if (typeof configData.sdmodel === 'string') {
|
|
updates.sdmodel = configData.sdmodel;
|
|
updates.isImageGenerationMode = Boolean(configData.sdmodel?.trim());
|
|
}
|
|
|
|
if (typeof configData.sdt5xxl === 'string') {
|
|
updates.sdt5xxl = configData.sdt5xxl;
|
|
}
|
|
|
|
if (typeof configData.sdclipl === 'string') {
|
|
updates.sdclipl = configData.sdclipl;
|
|
}
|
|
|
|
if (typeof configData.sdclipg === 'string') {
|
|
updates.sdclipg = configData.sdclipg;
|
|
}
|
|
|
|
if (typeof configData.sdphotomaker === 'string') {
|
|
updates.sdphotomaker = configData.sdphotomaker;
|
|
}
|
|
|
|
if (typeof configData.sdvae === 'string') {
|
|
updates.sdvae = configData.sdvae;
|
|
}
|
|
|
|
if (typeof configData.sdlora === 'string') {
|
|
updates.sdlora = configData.sdlora;
|
|
}
|
|
if (
|
|
typeof configData.sdconvdirect === 'string' &&
|
|
['off', 'vaeonly', 'full'].includes(configData.sdconvdirect)
|
|
) {
|
|
updates.sdconvdirect = configData.sdconvdirect as SdConvDirectMode;
|
|
}
|
|
|
|
if (typeof configData.moecpu === 'number') {
|
|
updates.moecpu = configData.moecpu;
|
|
} else {
|
|
updates.moecpu = 0;
|
|
}
|
|
|
|
if (typeof configData.moeexperts === 'number') {
|
|
updates.moeexperts = configData.moeexperts;
|
|
} else {
|
|
updates.moeexperts = -1;
|
|
}
|
|
|
|
set(updates);
|
|
}
|
|
},
|
|
|
|
loadConfigFromFile: async (
|
|
configFiles: ConfigFile[],
|
|
savedConfig: string | null
|
|
): Promise<string | null> => {
|
|
let currentSelectedFile = null;
|
|
|
|
if (savedConfig) {
|
|
currentSelectedFile = configFiles.find((f) => f.name === savedConfig);
|
|
}
|
|
|
|
if (!currentSelectedFile && configFiles.length > 0) {
|
|
currentSelectedFile = configFiles[0];
|
|
}
|
|
|
|
if (currentSelectedFile) {
|
|
await get().parseAndApplyConfigFile(currentSelectedFile.path);
|
|
return currentSelectedFile.name;
|
|
}
|
|
|
|
return null;
|
|
},
|
|
|
|
selectModelFile: async () => {
|
|
const result = await window.electronAPI.kobold.selectModelFile(
|
|
'Select a Text Model File'
|
|
);
|
|
if (result) {
|
|
set({ model: result });
|
|
}
|
|
},
|
|
|
|
selectSdmodelFile: async () => {
|
|
const result = await window.electronAPI.kobold.selectModelFile(
|
|
'Select a Image Gen. Model File'
|
|
);
|
|
if (result) {
|
|
set({
|
|
sdmodel: result,
|
|
isImageGenerationMode: Boolean(result?.trim()),
|
|
});
|
|
}
|
|
},
|
|
|
|
selectSdt5xxlFile: async () => {
|
|
const result = await window.electronAPI.kobold.selectModelFile(
|
|
'Select a T5XXL Model File'
|
|
);
|
|
if (result) {
|
|
set({ sdt5xxl: result });
|
|
}
|
|
},
|
|
|
|
selectSdcliplFile: async () => {
|
|
const result = await window.electronAPI.kobold.selectModelFile(
|
|
'Select a CLIP-L Model File'
|
|
);
|
|
if (result) {
|
|
set({ sdclipl: result });
|
|
}
|
|
},
|
|
|
|
selectSdclipgFile: async () => {
|
|
const result = await window.electronAPI.kobold.selectModelFile(
|
|
'Select a CLIP-G Model File'
|
|
);
|
|
if (result) {
|
|
set({ sdclipg: result });
|
|
}
|
|
},
|
|
|
|
selectSdphotomakerFile: async () => {
|
|
const result = await window.electronAPI.kobold.selectModelFile(
|
|
'Select a PhotoMaker Model File'
|
|
);
|
|
if (result) {
|
|
set({ sdphotomaker: result });
|
|
}
|
|
},
|
|
|
|
selectSdvaeFile: async () => {
|
|
const result = await window.electronAPI.kobold.selectModelFile(
|
|
'Select a VAE Model File'
|
|
);
|
|
if (result) {
|
|
set({ sdvae: result });
|
|
}
|
|
},
|
|
|
|
selectSdloraFile: async () => {
|
|
const result = await window.electronAPI.kobold.selectModelFile(
|
|
'Select a LORA Model File'
|
|
);
|
|
if (result) {
|
|
set({ sdlora: result });
|
|
}
|
|
},
|
|
|
|
contextSizeChangeWithStep: (size: number) => {
|
|
const roundedSize = Math.round(size / 256) * 256;
|
|
set({ contextSize: Math.max(256, Math.min(131072, roundedSize)) });
|
|
},
|
|
|
|
applyImageModelPreset: (preset: ImageModelPreset) => {
|
|
set({
|
|
sdmodel: preset.sdmodel,
|
|
isImageGenerationMode: Boolean(preset.sdmodel?.trim()),
|
|
sdt5xxl: preset.sdt5xxl,
|
|
sdclipl: preset.sdclipl,
|
|
sdclipg: preset.sdclipg || '',
|
|
sdvae: preset.sdvae,
|
|
});
|
|
},
|
|
}));
|