mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 09:33:10 -07:00
refactoring out duplicate code
This commit is contained in:
parent
ded8acb436
commit
95dafe66f8
7 changed files with 290 additions and 309 deletions
|
|
@ -1,44 +1,40 @@
|
|||
AMDGPU
|
||||
APPIMAGE
|
||||
BLAS
|
||||
CUDA
|
||||
GGUF
|
||||
KOBOLDAI
|
||||
KOBOLDCPP
|
||||
OLDPC
|
||||
ROCM
|
||||
SDXL
|
||||
SPACEBAR
|
||||
Consolas
|
||||
Cooldown
|
||||
Dolfino
|
||||
Flashattention
|
||||
KoboldCpp
|
||||
Lowvram
|
||||
Segoe
|
||||
Tauri
|
||||
asar
|
||||
Autoencoder
|
||||
BLAS
|
||||
clblast
|
||||
clinfo
|
||||
Consolas
|
||||
contextsize
|
||||
Cooldown
|
||||
cublas
|
||||
cuda
|
||||
CUDA
|
||||
Dolfino
|
||||
finetuned
|
||||
flashattention
|
||||
Flashattention
|
||||
friendlykobold
|
||||
geforce
|
||||
ggml
|
||||
gguf
|
||||
GGUF
|
||||
gpulayers
|
||||
hipblas
|
||||
kcpps
|
||||
kcppt
|
||||
koboldai
|
||||
KOBOLDAI
|
||||
koboldcpp
|
||||
KoboldCpp
|
||||
KOBOLDCPP
|
||||
lora
|
||||
lowvram
|
||||
Lowvram
|
||||
maximizable
|
||||
minimizable
|
||||
MMAP
|
||||
mmproj
|
||||
mmq
|
||||
multiuser
|
||||
|
|
@ -51,12 +47,14 @@ noshift
|
|||
nsis
|
||||
nvidia
|
||||
oldpc
|
||||
OLDPC
|
||||
opencl
|
||||
pkexec
|
||||
quantmatmul
|
||||
radeon
|
||||
remotetunnel
|
||||
rocm
|
||||
ROCM
|
||||
rocminfo
|
||||
safetensors
|
||||
sdclipg
|
||||
|
|
@ -66,8 +64,12 @@ sdmodel
|
|||
sdphotomaker
|
||||
sdui
|
||||
sdvae
|
||||
SDXL
|
||||
Segoe
|
||||
sonarjs
|
||||
SPACEBAR
|
||||
taskkill
|
||||
Tauri
|
||||
togglefullscreen
|
||||
treemap
|
||||
trycloudflare
|
||||
|
|
@ -81,4 +83,3 @@ vulkan
|
|||
vulkaninfo
|
||||
wayland
|
||||
websearch
|
||||
MMAP
|
||||
|
|
|
|||
31
src/components/CheckboxWithTooltip.tsx
Normal file
31
src/components/CheckboxWithTooltip.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { Checkbox, Group } from '@mantine/core';
|
||||
import { InfoTooltip } from '@/components/InfoTooltip';
|
||||
import styles from '@/styles/layout.module.css';
|
||||
|
||||
interface CheckboxWithTooltipProps {
|
||||
checked: boolean;
|
||||
onChange: (checked: boolean) => void;
|
||||
label: string;
|
||||
tooltip: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const CheckboxWithTooltip = ({
|
||||
checked,
|
||||
onChange,
|
||||
label,
|
||||
tooltip,
|
||||
disabled = false,
|
||||
}: CheckboxWithTooltipProps) => (
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={checked}
|
||||
onChange={(event) => onChange(event.currentTarget.checked)}
|
||||
label={label}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<InfoTooltip label={tooltip} />
|
||||
</Group>
|
||||
</div>
|
||||
);
|
||||
90
src/components/ModelFileField.tsx
Normal file
90
src/components/ModelFileField.tsx
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import { Group, TextInput, Button } from '@mantine/core';
|
||||
import { File, Search } from 'lucide-react';
|
||||
import { SectionHeader } from '@/components/SectionHeader';
|
||||
import { getInputValidationState } from '@/utils';
|
||||
import styles from '@/styles/layout.module.css';
|
||||
|
||||
interface ModelFileFieldProps {
|
||||
label: string;
|
||||
value: string;
|
||||
placeholder: string;
|
||||
tooltip?: string;
|
||||
onChange: (value: string) => void;
|
||||
onSelectFile: () => void;
|
||||
showSearchHF?: boolean;
|
||||
searchUrl?: string;
|
||||
}
|
||||
|
||||
export const ModelFileField = ({
|
||||
label,
|
||||
value,
|
||||
placeholder,
|
||||
tooltip,
|
||||
onChange,
|
||||
onSelectFile,
|
||||
showSearchHF = false,
|
||||
searchUrl = 'https://huggingface.co/models?pipeline_tag=text-to-image&library=gguf&sort=trending',
|
||||
}: ModelFileFieldProps) => {
|
||||
const validationState = getInputValidationState(value);
|
||||
|
||||
const getInputColor = () => {
|
||||
switch (validationState) {
|
||||
case 'valid':
|
||||
return 'green';
|
||||
case 'invalid':
|
||||
return 'red';
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const getHelperText = () => {
|
||||
if (!value.trim()) return undefined;
|
||||
|
||||
if (validationState === 'invalid') {
|
||||
return 'Enter a valid URL or file path';
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SectionHeader
|
||||
title={label}
|
||||
tooltip={tooltip}
|
||||
fontWeight={500}
|
||||
marginBottom="xs"
|
||||
/>
|
||||
<Group gap="xs" align="flex-start">
|
||||
<div className={styles.flex1}>
|
||||
<TextInput
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onChange={(event) => onChange(event.currentTarget.value)}
|
||||
color={getInputColor()}
|
||||
error={validationState === 'invalid' ? getHelperText() : undefined}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
onClick={onSelectFile}
|
||||
variant="light"
|
||||
leftSection={<File size={16} />}
|
||||
>
|
||||
Browse
|
||||
</Button>
|
||||
{showSearchHF && (
|
||||
<Button
|
||||
onClick={() => {
|
||||
window.electronAPI.app.openExternal(searchUrl);
|
||||
}}
|
||||
variant="outline"
|
||||
leftSection={<Search size={16} />}
|
||||
>
|
||||
Search HF
|
||||
</Button>
|
||||
)}
|
||||
</Group>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
23
src/components/SectionHeader.tsx
Normal file
23
src/components/SectionHeader.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import { Group, Text } from '@mantine/core';
|
||||
import { InfoTooltip } from '@/components/InfoTooltip';
|
||||
|
||||
interface SectionHeaderProps {
|
||||
title: string;
|
||||
tooltip?: string;
|
||||
fontWeight?: number;
|
||||
marginBottom?: string;
|
||||
}
|
||||
|
||||
export const SectionHeader = ({
|
||||
title,
|
||||
tooltip,
|
||||
fontWeight = 600,
|
||||
marginBottom = 'md',
|
||||
}: SectionHeaderProps) => (
|
||||
<Group gap="xs" align="center" mb={marginBottom}>
|
||||
<Text size="sm" fw={fontWeight}>
|
||||
{title}
|
||||
</Text>
|
||||
{tooltip && <InfoTooltip label={tooltip} />}
|
||||
</Group>
|
||||
);
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import { Stack, Checkbox, Group, Text, TextInput } from '@mantine/core';
|
||||
import { Stack, Group, Text, TextInput } from '@mantine/core';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { InfoTooltip } from '@/components/InfoTooltip';
|
||||
import { CheckboxWithTooltip } from '@/components/CheckboxWithTooltip';
|
||||
import { useLaunchConfig } from '@/hooks/useLaunchConfig';
|
||||
import styles from '@/styles/layout.module.css';
|
||||
|
||||
export const AdvancedTab = () => {
|
||||
const {
|
||||
|
|
@ -68,101 +68,61 @@ export const AdvancedTab = () => {
|
|||
</Group>
|
||||
<Stack gap="md">
|
||||
<Group gap="lg" align="flex-start" wrap="nowrap">
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={!noshift}
|
||||
onChange={(event) =>
|
||||
handleNoshiftChange(!event.currentTarget.checked)
|
||||
}
|
||||
label="Context Shift"
|
||||
/>
|
||||
<InfoTooltip label="Use Context Shifting to reduce reprocessing." />
|
||||
</Group>
|
||||
</div>
|
||||
<CheckboxWithTooltip
|
||||
checked={!noshift}
|
||||
onChange={(checked) => handleNoshiftChange(!checked)}
|
||||
label="Context Shift"
|
||||
tooltip="Use Context Shifting to reduce reprocessing."
|
||||
/>
|
||||
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={noshift}
|
||||
onChange={(event) =>
|
||||
handleNoshiftChange(event.currentTarget.checked)
|
||||
}
|
||||
label="No Shift"
|
||||
/>
|
||||
<InfoTooltip label="Don't use GPU layer shifting for incomplete offloads, which may reduce model performance." />
|
||||
</Group>
|
||||
</div>
|
||||
<CheckboxWithTooltip
|
||||
checked={noshift}
|
||||
onChange={handleNoshiftChange}
|
||||
label="No Shift"
|
||||
tooltip="Don't use GPU layer shifting for incomplete offloads, which may reduce model performance."
|
||||
/>
|
||||
</Group>
|
||||
|
||||
<Group gap="lg" align="flex-start" wrap="nowrap">
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={flashattention}
|
||||
onChange={(event) =>
|
||||
handleFlashattentionChange(event.currentTarget.checked)
|
||||
}
|
||||
label="Flash Attention"
|
||||
/>
|
||||
<InfoTooltip label="Enable flash attention to reduce memory usage. May produce incorrect answers for some prompts, but improves performance." />
|
||||
</Group>
|
||||
</div>
|
||||
<CheckboxWithTooltip
|
||||
checked={flashattention}
|
||||
onChange={handleFlashattentionChange}
|
||||
label="Flash Attention"
|
||||
tooltip="Enable flash attention to reduce memory usage. May produce incorrect answers for some prompts, but improves performance."
|
||||
/>
|
||||
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={lowvram}
|
||||
onChange={(event) =>
|
||||
handleLowvramChange(event.currentTarget.checked)
|
||||
}
|
||||
label="Low VRAM"
|
||||
disabled={backend !== 'cuda' && backend !== 'rocm'}
|
||||
/>
|
||||
<InfoTooltip
|
||||
label={
|
||||
backend !== 'cuda' && backend !== 'rocm'
|
||||
? 'Low VRAM mode is only available for CUDA and ROCm backends.'
|
||||
: 'Avoid offloading KV Cache or scratch buffers to VRAM. Allows more layers to fit, but may result in a speed loss.'
|
||||
}
|
||||
/>
|
||||
</Group>
|
||||
</div>
|
||||
<CheckboxWithTooltip
|
||||
checked={usemmap}
|
||||
onChange={handleUsemmapChange}
|
||||
label="MMAP"
|
||||
tooltip="Use MMAP to load models when enabled."
|
||||
/>
|
||||
|
||||
<CheckboxWithTooltip
|
||||
checked={lowvram}
|
||||
onChange={handleLowvramChange}
|
||||
label="Low VRAM"
|
||||
tooltip={
|
||||
backend !== 'cuda' && backend !== 'rocm'
|
||||
? 'Low VRAM mode is only available for CUDA and ROCm backends.'
|
||||
: 'Avoid offloading KV Cache or scratch buffers to VRAM. Allows more layers to fit, but may result in a speed loss.'
|
||||
}
|
||||
disabled={backend !== 'cuda' && backend !== 'rocm'}
|
||||
/>
|
||||
</Group>
|
||||
|
||||
<Group gap="lg" align="flex-start" wrap="nowrap">
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={quantmatmul}
|
||||
onChange={(event) =>
|
||||
handleQuantmatmulChange(event.currentTarget.checked)
|
||||
}
|
||||
label="QuantMatMul"
|
||||
disabled={backend !== 'cuda' && backend !== 'rocm'}
|
||||
/>
|
||||
<InfoTooltip
|
||||
label={
|
||||
backend !== 'cuda' && backend !== 'rocm'
|
||||
? 'QuantMatMul is only available for CUDA and ROCm backends.'
|
||||
: 'Enable MMQ mode to use finetuned kernels instead of default CuBLAS/HipBLAS for prompt processing.'
|
||||
}
|
||||
/>
|
||||
</Group>
|
||||
</div>
|
||||
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={usemmap}
|
||||
onChange={(event) =>
|
||||
handleUsemmapChange(event.currentTarget.checked)
|
||||
}
|
||||
label="MMAP"
|
||||
/>
|
||||
<InfoTooltip label="Use MMAP to load models when enabled." />
|
||||
</Group>
|
||||
</div>
|
||||
<CheckboxWithTooltip
|
||||
checked={quantmatmul}
|
||||
onChange={handleQuantmatmulChange}
|
||||
label="QuantMatMul"
|
||||
tooltip={
|
||||
backend !== 'cuda' && backend !== 'rocm'
|
||||
? 'QuantMatMul is only available for CUDA and ROCm backends.'
|
||||
: 'Enable MMQ mode to use finetuned kernels instead of default CuBLAS/HipBLAS for prompt processing.'
|
||||
}
|
||||
disabled={backend !== 'cuda' && backend !== 'rocm'}
|
||||
/>
|
||||
</Group>
|
||||
</Stack>
|
||||
</div>
|
||||
|
|
@ -175,45 +135,29 @@ export const AdvancedTab = () => {
|
|||
</Group>
|
||||
<Stack gap="md">
|
||||
<Group gap="lg" align="flex-start" wrap="nowrap">
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={noavx2}
|
||||
onChange={(event) =>
|
||||
handleNoavx2Change(event.currentTarget.checked)
|
||||
}
|
||||
label="Disable AVX2"
|
||||
disabled={isLoading || !backendSupport?.noavx2}
|
||||
/>
|
||||
<InfoTooltip
|
||||
label={
|
||||
!backendSupport?.noavx2 && !isLoading
|
||||
? 'This binary does not support the no-AVX2 mode.'
|
||||
: 'Do not use AVX2 instructions, a slower compatibility mode for older devices.'
|
||||
}
|
||||
/>
|
||||
</Group>
|
||||
</div>
|
||||
<CheckboxWithTooltip
|
||||
checked={noavx2}
|
||||
onChange={handleNoavx2Change}
|
||||
label="Disable AVX2"
|
||||
tooltip={
|
||||
!backendSupport?.noavx2 && !isLoading
|
||||
? 'This binary does not support the no-AVX2 mode.'
|
||||
: 'Do not use AVX2 instructions, a slower compatibility mode for older devices.'
|
||||
}
|
||||
disabled={isLoading || !backendSupport?.noavx2}
|
||||
/>
|
||||
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={failsafe}
|
||||
onChange={(event) =>
|
||||
handleFailsafeChange(event.currentTarget.checked)
|
||||
}
|
||||
label="Failsafe"
|
||||
disabled={isLoading || !backendSupport?.failsafe}
|
||||
/>
|
||||
<InfoTooltip
|
||||
label={
|
||||
!backendSupport?.failsafe && !isLoading
|
||||
? 'This binary does not support failsafe mode.'
|
||||
: 'Use failsafe mode, extremely slow CPU only compatibility mode that should work on all devices. Can be combined with useclblast if your device supports OpenCL.'
|
||||
}
|
||||
/>
|
||||
</Group>
|
||||
</div>
|
||||
<CheckboxWithTooltip
|
||||
checked={failsafe}
|
||||
onChange={handleFailsafeChange}
|
||||
label="Failsafe"
|
||||
tooltip={
|
||||
!backendSupport?.failsafe && !isLoading
|
||||
? 'This binary does not support failsafe mode.'
|
||||
: 'Use failsafe mode, extremely slow CPU only compatibility mode that should work on all devices. Can be combined with useclblast if your device supports OpenCL.'
|
||||
}
|
||||
disabled={isLoading || !backendSupport?.failsafe}
|
||||
/>
|
||||
</Group>
|
||||
</Stack>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import { Stack, Text, Group, TextInput, Button, Select } from '@mantine/core';
|
||||
import { Stack, Select } from '@mantine/core';
|
||||
import { useState } from 'react';
|
||||
import { File, Search } from 'lucide-react';
|
||||
import { InfoTooltip } from '@/components/InfoTooltip';
|
||||
import { getInputValidationState, IMAGE_MODEL_PRESETS } from '@/utils';
|
||||
import { SectionHeader } from '@/components/SectionHeader';
|
||||
import { ModelFileField } from '@/components/ModelFileField';
|
||||
import { IMAGE_MODEL_PRESETS } from '@/utils';
|
||||
import { useLaunchConfig } from '@/hooks/useLaunchConfig';
|
||||
import styles from '@/styles/layout.module.css';
|
||||
|
||||
export const ImageGenerationTab = () => {
|
||||
const {
|
||||
|
|
@ -34,100 +33,15 @@ export const ImageGenerationTab = () => {
|
|||
|
||||
const [selectedPreset, setSelectedPreset] = useState<string | null>(null);
|
||||
|
||||
const ModelField = ({
|
||||
label,
|
||||
value,
|
||||
placeholder,
|
||||
tooltip,
|
||||
onChange,
|
||||
onSelectFile,
|
||||
showSearchHF = false,
|
||||
}: {
|
||||
label: string;
|
||||
value: string;
|
||||
placeholder: string;
|
||||
tooltip?: string;
|
||||
onChange: (value: string) => void;
|
||||
onSelectFile: () => void;
|
||||
showSearchHF?: boolean;
|
||||
}) => {
|
||||
const validationState = getInputValidationState(value);
|
||||
|
||||
const getInputColor = () => {
|
||||
switch (validationState) {
|
||||
case 'valid':
|
||||
return 'green';
|
||||
case 'invalid':
|
||||
return 'red';
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const getHelperText = () => {
|
||||
if (!value.trim()) return undefined;
|
||||
|
||||
if (validationState === 'invalid') {
|
||||
return 'Enter a valid URL or file path';
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Group gap="xs" align="center" mb="xs">
|
||||
<Text size="sm" fw={500}>
|
||||
{label}
|
||||
</Text>
|
||||
{tooltip && <InfoTooltip label={tooltip} />}
|
||||
</Group>
|
||||
<Group gap="xs" align="flex-start">
|
||||
<div className={styles.flex1}>
|
||||
<TextInput
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onChange={(event) => onChange(event.currentTarget.value)}
|
||||
color={getInputColor()}
|
||||
error={
|
||||
validationState === 'invalid' ? getHelperText() : undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
onClick={onSelectFile}
|
||||
variant="light"
|
||||
leftSection={<File size={16} />}
|
||||
>
|
||||
Browse
|
||||
</Button>
|
||||
{showSearchHF && (
|
||||
<Button
|
||||
onClick={() => {
|
||||
window.electronAPI.app.openExternal(
|
||||
'https://huggingface.co/models?pipeline_tag=text-to-image&library=gguf&sort=trending'
|
||||
);
|
||||
}}
|
||||
variant="outline"
|
||||
leftSection={<Search size={16} />}
|
||||
>
|
||||
Search HF
|
||||
</Button>
|
||||
)}
|
||||
</Group>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<div>
|
||||
<Group gap="xs" align="center" mb="xs">
|
||||
<Text size="sm" fw={500}>
|
||||
Model Preset
|
||||
</Text>
|
||||
<InfoTooltip label="Quick presets for popular image generation models with pre-configured encoders." />
|
||||
</Group>
|
||||
<SectionHeader
|
||||
title="Model Preset"
|
||||
tooltip="Quick presets for popular image generation models with pre-configured encoders."
|
||||
fontWeight={500}
|
||||
marginBottom="xs"
|
||||
/>
|
||||
<Select
|
||||
placeholder="Choose a preset..."
|
||||
data={IMAGE_MODEL_PRESETS.map((preset) => ({
|
||||
|
|
@ -145,40 +59,45 @@ export const ImageGenerationTab = () => {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<ModelField
|
||||
<ModelFileField
|
||||
label="Image Gen. Model File"
|
||||
value={sdmodel}
|
||||
placeholder="Select a model file or enter a direct URL"
|
||||
tooltip="The primary image generation model. This is the main model that will generate images."
|
||||
onChange={handleSdmodelChange}
|
||||
onSelectFile={handleSelectSdmodelFile}
|
||||
showSearchHF
|
||||
searchUrl="https://huggingface.co/models?pipeline_tag=text-to-image&library=gguf&sort=trending"
|
||||
/>
|
||||
|
||||
<ModelField
|
||||
<ModelFileField
|
||||
label="T5-XXL File"
|
||||
value={sdt5xxl}
|
||||
placeholder="Select a T5-XXL file or enter a direct URL"
|
||||
tooltip="T5-XXL text encoder model for enhanced text understanding."
|
||||
onChange={handleSdt5xxlChange}
|
||||
onSelectFile={handleSelectSdt5xxlFile}
|
||||
/>
|
||||
|
||||
<ModelField
|
||||
<ModelFileField
|
||||
label="Clip-L File"
|
||||
value={sdclipl}
|
||||
placeholder="Select a Clip-L file or enter a direct URL"
|
||||
tooltip="CLIP-L text encoder model for text-image understanding."
|
||||
onChange={handleSdcliplChange}
|
||||
onSelectFile={handleSelectSdcliplFile}
|
||||
/>
|
||||
|
||||
<ModelField
|
||||
<ModelFileField
|
||||
label="Clip-G File"
|
||||
value={sdclipg}
|
||||
placeholder="Select a Clip-G file or enter a direct URL"
|
||||
tooltip="CLIP-G text encoder model for enhanced text-image understanding."
|
||||
onChange={handleSdclipgChange}
|
||||
onSelectFile={handleSelectSdclipgFile}
|
||||
/>
|
||||
|
||||
<ModelField
|
||||
<ModelFileField
|
||||
label="PhotoMaker"
|
||||
value={sdphotomaker}
|
||||
placeholder="Select a PhotoMaker file or enter a direct URL"
|
||||
|
|
@ -187,15 +106,16 @@ export const ImageGenerationTab = () => {
|
|||
onSelectFile={handleSelectSdphotomakerFile}
|
||||
/>
|
||||
|
||||
<ModelField
|
||||
<ModelFileField
|
||||
label="Image VAE"
|
||||
value={sdvae}
|
||||
placeholder="Select a VAE file or enter a direct URL"
|
||||
tooltip="Variational Autoencoder model for improved image quality."
|
||||
onChange={handleSdvaeChange}
|
||||
onSelectFile={handleSelectSdvaeFile}
|
||||
/>
|
||||
|
||||
<ModelField
|
||||
<ModelFileField
|
||||
label="Image LoRa"
|
||||
value={sdlora}
|
||||
placeholder="Select a LoRa file or enter a direct URL"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { Stack, Text, TextInput, Group, Checkbox } from '@mantine/core';
|
||||
import { Stack, Text, TextInput, Group } from '@mantine/core';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { InfoTooltip } from '@/components/InfoTooltip';
|
||||
import { CheckboxWithTooltip } from '@/components/CheckboxWithTooltip';
|
||||
import { useLaunchConfig } from '@/hooks/useLaunchConfig';
|
||||
import styles from '@/styles/layout.module.css';
|
||||
|
||||
export const NetworkTab = () => {
|
||||
const {
|
||||
|
|
@ -85,71 +85,43 @@ export const NetworkTab = () => {
|
|||
<div>
|
||||
<Stack gap="md">
|
||||
<Group gap="lg" align="flex-start" wrap="nowrap">
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={multiuser}
|
||||
onChange={(event) =>
|
||||
handleMultiuserChange(event.currentTarget.checked)
|
||||
}
|
||||
label="Multiuser Mode"
|
||||
/>
|
||||
<InfoTooltip label="Allows requests by multiple different clients to be queued and handled in sequence." />
|
||||
</Group>
|
||||
</div>
|
||||
<CheckboxWithTooltip
|
||||
checked={multiuser}
|
||||
onChange={handleMultiuserChange}
|
||||
label="Multiuser Mode"
|
||||
tooltip="Allows requests by multiple different clients to be queued and handled in sequence."
|
||||
/>
|
||||
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={multiplayer}
|
||||
onChange={(event) =>
|
||||
handleMultiplayerChange(event.currentTarget.checked)
|
||||
}
|
||||
label="Shared Multiplayer"
|
||||
/>
|
||||
<InfoTooltip label="Hosts a shared multiplayer session" />
|
||||
</Group>
|
||||
</div>
|
||||
<CheckboxWithTooltip
|
||||
checked={multiplayer}
|
||||
onChange={handleMultiplayerChange}
|
||||
label="Shared Multiplayer"
|
||||
tooltip="Hosts a shared multiplayer session"
|
||||
/>
|
||||
</Group>
|
||||
|
||||
<Group gap="lg" align="flex-start" wrap="nowrap">
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={remotetunnel}
|
||||
onChange={(event) =>
|
||||
handleRemotetunnelChange(event.currentTarget.checked)
|
||||
}
|
||||
label="Remote Tunnel"
|
||||
/>
|
||||
<InfoTooltip label="Creates a trycloudflare tunnel. Allows you to access koboldcpp from other devices over an internet URL." />
|
||||
</Group>
|
||||
</div>
|
||||
|
||||
<div className={styles.minWidth200}>
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={nocertify}
|
||||
onChange={(event) =>
|
||||
handleNocertifyChange(event.currentTarget.checked)
|
||||
}
|
||||
label="No Certify Mode (Insecure)"
|
||||
/>
|
||||
<InfoTooltip label="Allows insecure SSL connections. Use this if you have SSL cert errors and need to bypass certificate restrictions." />
|
||||
</Group>
|
||||
</div>
|
||||
</Group>
|
||||
|
||||
<Group gap="xs" align="center">
|
||||
<Checkbox
|
||||
checked={websearch}
|
||||
onChange={(event) =>
|
||||
handleWebsearchChange(event.currentTarget.checked)
|
||||
}
|
||||
label="Enable WebSearch"
|
||||
<CheckboxWithTooltip
|
||||
checked={remotetunnel}
|
||||
onChange={handleRemotetunnelChange}
|
||||
label="Remote Tunnel"
|
||||
tooltip="Creates a trycloudflare tunnel. Allows you to access koboldcpp from other devices over an internet URL."
|
||||
/>
|
||||
|
||||
<CheckboxWithTooltip
|
||||
checked={nocertify}
|
||||
onChange={handleNocertifyChange}
|
||||
label="No Certify Mode (Insecure)"
|
||||
tooltip="Allows insecure SSL connections. Use this if you have SSL cert errors and need to bypass certificate restrictions."
|
||||
/>
|
||||
<InfoTooltip label="Enable the local search engine proxy so Web Searches can be done." />
|
||||
</Group>
|
||||
|
||||
<CheckboxWithTooltip
|
||||
checked={websearch}
|
||||
onChange={handleWebsearchChange}
|
||||
label="Enable WebSearch"
|
||||
tooltip="Enable the local search engine proxy so Web Searches can be done."
|
||||
/>
|
||||
</Stack>
|
||||
</div>
|
||||
</Stack>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue