major clean up

This commit is contained in:
Egor 2025-08-21 00:43:48 -07:00
parent a856010a55
commit d5323d8b3e
20 changed files with 6 additions and 392 deletions

View file

@ -4,7 +4,6 @@ import { DownloadScreen } from '@/components/screens/Download';
import { LaunchScreen } from '@/components/screens/Launch';
import { InterfaceScreen } from '@/components/screens/Interface';
import { WelcomeScreen } from '@/components/screens/Welcome';
import { UpdateDialog } from '@/components/UpdateDialog';
import { UpdateAvailableModal } from '@/components/UpdateAvailableModal';
import { SettingsModal } from '@/components/settings/SettingsModal';
import { EjectConfirmDialog } from '@/components/EjectConfirmDialog';
@ -13,15 +12,12 @@ import { AppHeader } from '@/components/AppHeader';
import { useUpdateChecker } from '@/hooks/useUpdateChecker';
import { useKoboldVersions } from '@/hooks/useKoboldVersions';
import { UI } from '@/constants';
import type { UpdateInfo } from '@/types';
import type { DownloadItem } from '@/types/electron';
type Screen = 'welcome' | 'download' | 'launch' | 'interface';
export const App = () => {
const [currentScreen, setCurrentScreen] = useState<Screen | null>(null);
const [updateInfo, setUpdateInfo] = useState<UpdateInfo | null>(null);
const [showUpdateDialog, setShowUpdateDialog] = useState(false);
const [settingsOpened, setSettingsOpened] = useState(false);
const [hasInitialized, setHasInitialized] = useState(false);
const [showEjectDialog, setShowEjectDialog] = useState(false);
@ -100,11 +96,6 @@ export const App = () => {
checkInstallation();
window.electronAPI.kobold.onUpdateAvailable((info) => {
setUpdateInfo(info);
setShowUpdateDialog(true);
});
const cleanupInstallDirListener =
window.electronAPI.kobold.onInstallDirChanged(() => {
checkInstallation();
@ -117,7 +108,6 @@ export const App = () => {
);
return () => {
window.electronAPI.kobold.removeAllListeners('update-available');
cleanupInstallDirListener();
cleanupVersionsListener();
};
@ -224,15 +214,6 @@ export const App = () => {
}
};
const handleUpdateIgnore = () => {
setShowUpdateDialog(false);
};
const handleUpdateAccept = () => {
setShowUpdateDialog(false);
setCurrentScreenWithTransition('download');
};
return (
<>
<AppShell
@ -307,14 +288,6 @@ export const App = () => {
</>
)}
{showUpdateDialog && updateInfo && (
<UpdateDialog
updateInfo={updateInfo}
onIgnore={handleUpdateIgnore}
onAccept={handleUpdateAccept}
/>
)}
{showUpdateModal && binaryUpdateInfo && (
<UpdateAvailableModal
opened={showUpdateModal}

View file

@ -14,7 +14,7 @@ import { Settings, ArrowLeft } from 'lucide-react';
import { StyledTooltip } from '@/components/StyledTooltip';
import { soundAssets, playSound, initializeAudio } from '@/utils';
import iconUrl from '/icon.png';
import './AppHeader.css';
import '@/styles/AppHeader.css';
type Screen = 'welcome' | 'download' | 'launch' | 'interface';

View file

@ -1,43 +0,0 @@
import { Modal, Text, Button, Group, Stack } from '@mantine/core';
import type { GitHubRelease } from '@/types';
interface UpdateDialogProps {
updateInfo: {
currentVersion: string;
latestVersion: string;
releaseInfo: GitHubRelease;
};
onIgnore: () => void;
onAccept: () => void;
}
export const UpdateDialog = ({
updateInfo,
onIgnore,
onAccept,
}: UpdateDialogProps) => (
<Modal
opened
onClose={onIgnore}
title="Update Available"
centered
radius="md"
>
<Stack gap="md">
<Text>
A new version of KoboldCpp is available: {updateInfo.latestVersion}
</Text>
<Text size="sm" c="dimmed">
Current version: {updateInfo.currentVersion}
</Text>
<Group justify="flex-end" gap="sm">
<Button variant="default" onClick={onIgnore} radius="md">
Ignore
</Button>
<Button onClick={onAccept} radius="md">
Update
</Button>
</Group>
</Stack>
</Modal>
);

View file

@ -8,7 +8,7 @@ import { AdvancedTab } from '@/components/screens/Launch/AdvancedTab';
import { NetworkTab } from '@/components/screens/Launch/NetworkTab';
import { ImageGenerationTab } from '@/components/screens/Launch/ImageGenerationTab';
import { WarningDisplay } from '@/components/WarningDisplay';
import { ConfigFileManager } from '@/components/ConfigFileManager';
import { ConfigFileManager } from '@/components/screens/Launch/ConfigFileManager';
import { DEFAULT_MODEL_URL } from '@/constants';
import type { ConfigFile } from '@/types';

View file

@ -4,21 +4,3 @@ export const DEFAULT_MODEL_URL =
'https://huggingface.co/MaziyarPanahi/gemma-3-4b-it-GGUF/resolve/main/gemma-3-4b-it.Q8_0.gguf?download=true';
export const DEFAULT_HOST = '';
export const DEFAULT_VOLUME = 0.5;
export const DEFAULT_SKIP_EJECT_CONFIRMATION = false;
export const DEFAULT_HAS_SEEN_WELCOME = false;
export const DEFAULT_FLUX_MODELS = {
T5XXL:
'https://huggingface.co/camenduru/FLUX.1-dev/resolve/main/t5xxl_fp8_e4m3fn.safetensors?download=true',
CLIP_L:
'https://huggingface.co/camenduru/FLUX.1-dev/resolve/main/clip_l.safetensors?download=true',
VAE: 'https://huggingface.co/camenduru/FLUX.1-dev/resolve/main/ae.safetensors?download=true',
U_NET: '',
CLIP: '',
LORA: '',
AESTHETIC: '',
} as const;

View file

@ -1,13 +0,0 @@
import { useCallback } from 'react';
export const useChangeTracker = <T extends unknown[]>(
handler: (...args: T) => void,
setHasUnsavedChanges: (value: boolean) => void
) =>
useCallback(
(...args: T) => {
handler(...args);
setHasUnsavedChanges(true);
},
[handler, setHasUnsavedChanges]
);

View file

@ -1,188 +0,0 @@
import { useChangeTracker } from '@/hooks/useChangeTracker';
interface TrackedConfigHandlersProps {
setHasUnsavedChanges: (value: boolean) => void;
handlers: {
handleModelPathChange: (path: string) => void;
handleGpuLayersChange: (layers: number) => void;
handleAutoGpuLayersChange: (auto: boolean) => void;
handleContextSizeChangeWithStep: (size: number) => void;
handleAdditionalArgumentsChange: (args: string) => void;
handlePortChange: (port: number | undefined) => void;
handleHostChange: (host: string) => void;
handleMultiuserChange: (enabled: boolean) => void;
handleMultiplayerChange: (enabled: boolean) => void;
handleRemotetunnelChange: (enabled: boolean) => void;
handleNocertifyChange: (enabled: boolean) => void;
handleWebsearchChange: (enabled: boolean) => void;
handleNoshiftChange: (enabled: boolean) => void;
handleFlashattentionChange: (enabled: boolean) => void;
handleNoavx2Change: (enabled: boolean) => void;
handleFailsafeChange: (enabled: boolean) => void;
handleLowvramChange: (enabled: boolean) => void;
handleQuantmatmulChange: (enabled: boolean) => void;
handleBackendChange: (backend: string) => void;
handleGpuDeviceChange: (device: number) => void;
handleGpuPlatformChange: (platform: number) => void;
handleSdmodelChange: (path: string) => void;
handleSdt5xxlChange: (path: string) => void;
handleSdcliplChange: (path: string) => void;
handleSdclipgChange: (path: string) => void;
handleSdphotomakerChange: (path: string) => void;
handleSdvaeChange: (path: string) => void;
handleSdloraChange: (path: string) => void;
};
}
export const useTrackedConfigHandlers = ({
setHasUnsavedChanges,
handlers,
}: TrackedConfigHandlersProps) => {
const createChangeTracker = useChangeTracker;
const {
handleModelPathChange,
handleGpuLayersChange,
handleAutoGpuLayersChange,
handleContextSizeChangeWithStep,
handleAdditionalArgumentsChange,
handlePortChange,
handleHostChange,
handleMultiuserChange,
handleMultiplayerChange,
handleRemotetunnelChange,
handleNocertifyChange,
handleWebsearchChange,
handleNoshiftChange,
handleFlashattentionChange,
handleNoavx2Change,
handleFailsafeChange,
handleLowvramChange,
handleQuantmatmulChange,
handleBackendChange,
handleGpuDeviceChange,
handleGpuPlatformChange,
handleSdmodelChange,
handleSdt5xxlChange,
handleSdcliplChange,
handleSdclipgChange,
handleSdphotomakerChange,
handleSdvaeChange,
handleSdloraChange,
} = handlers;
return {
handleModelPathChangeWithTracking: createChangeTracker(
handleModelPathChange,
setHasUnsavedChanges
),
handleGpuLayersChangeWithTracking: createChangeTracker(
handleGpuLayersChange,
setHasUnsavedChanges
),
handleAutoGpuLayersChangeWithTracking: createChangeTracker(
handleAutoGpuLayersChange,
setHasUnsavedChanges
),
handleContextSizeChangeWithTracking: createChangeTracker(
handleContextSizeChangeWithStep,
setHasUnsavedChanges
),
handleAdditionalArgumentsChangeWithTracking: createChangeTracker(
handleAdditionalArgumentsChange,
setHasUnsavedChanges
),
handlePortChangeWithTracking: createChangeTracker(
handlePortChange,
setHasUnsavedChanges
),
handleHostChangeWithTracking: createChangeTracker(
handleHostChange,
setHasUnsavedChanges
),
handleNoshiftChangeWithTracking: createChangeTracker(
handleNoshiftChange,
setHasUnsavedChanges
),
handleFlashattentionChangeWithTracking: createChangeTracker(
handleFlashattentionChange,
setHasUnsavedChanges
),
handleNoavx2ChangeWithTracking: createChangeTracker(
handleNoavx2Change,
setHasUnsavedChanges
),
handleFailsafeChangeWithTracking: createChangeTracker(
handleFailsafeChange,
setHasUnsavedChanges
),
handleLowvramChangeWithTracking: createChangeTracker(
handleLowvramChange,
setHasUnsavedChanges
),
handleQuantmatmulChangeWithTracking: createChangeTracker(
handleQuantmatmulChange,
setHasUnsavedChanges
),
handleMultiuserChangeWithTracking: createChangeTracker(
handleMultiuserChange,
setHasUnsavedChanges
),
handleMultiplayerChangeWithTracking: createChangeTracker(
handleMultiplayerChange,
setHasUnsavedChanges
),
handleRemotetunnelChangeWithTracking: createChangeTracker(
handleRemotetunnelChange,
setHasUnsavedChanges
),
handleNocertifyChangeWithTracking: createChangeTracker(
handleNocertifyChange,
setHasUnsavedChanges
),
handleWebsearchChangeWithTracking: createChangeTracker(
handleWebsearchChange,
setHasUnsavedChanges
),
handleBackendChangeWithTracking: createChangeTracker(
handleBackendChange,
setHasUnsavedChanges
),
handleGpuDeviceChangeWithTracking: createChangeTracker(
handleGpuDeviceChange,
setHasUnsavedChanges
),
handleGpuPlatformChangeWithTracking: createChangeTracker(
handleGpuPlatformChange,
setHasUnsavedChanges
),
handleSdmodelChangeWithTracking: createChangeTracker(
handleSdmodelChange,
setHasUnsavedChanges
),
handleSdt5xxlChangeWithTracking: createChangeTracker(
handleSdt5xxlChange,
setHasUnsavedChanges
),
handleSdcliplChangeWithTracking: createChangeTracker(
handleSdcliplChange,
setHasUnsavedChanges
),
handleSdclipgChangeWithTracking: createChangeTracker(
handleSdclipgChange,
setHasUnsavedChanges
),
handleSdphotomakerChangeWithTracking: createChangeTracker(
handleSdphotomakerChange,
setHasUnsavedChanges
),
handleSdvaeChangeWithTracking: createChangeTracker(
handleSdvaeChange,
setHasUnsavedChanges
),
handleSdloraChangeWithTracking: createChangeTracker(
handleSdloraChange,
setHasUnsavedChanges
),
};
};

View file

@ -1,32 +1,8 @@
import { useState, useCallback } from 'react';
import { getDisplayNameFromPath } from '@/utils/versionUtils';
import { compareVersions } from '@/utils';
import type { InstalledVersion, DownloadItem } from '@/types/electron';
const compareVersions = (versionA: string, versionB: string): number => {
const cleanVersion = (version: string): string =>
version.replace(/^v/, '').replace(/[^0-9.]/g, '');
const parseVersion = (version: string): number[] =>
cleanVersion(version)
.split('.')
.map((num) => parseInt(num, 10) || 0);
const a = parseVersion(versionA);
const b = parseVersion(versionB);
const maxLength = Math.max(a.length, b.length);
for (let i = 0; i < maxLength; i++) {
const aVal = a[i] || 0;
const bVal = b[i] || 0;
if (aVal !== bVal) {
return aVal - bVal;
}
}
return 0;
};
interface UpdateInfo {
currentVersion: InstalledVersion;
availableUpdate: DownloadItem;

View file

@ -19,6 +19,7 @@ import { LogManager } from '@/main/managers/LogManager';
import { WindowManager } from '@/main/managers/WindowManager';
import { ROCM } from '@/constants';
import { stripAssetExtensions } from '@/utils/versionUtils';
import { compareVersions } from '@/utils';
import type { DownloadItem } from '@/types/electron';
interface GitHubAsset {
@ -846,7 +847,7 @@ export class KoboldCppManager {
const latestVersion = latestRelease.tag_name.replace(/^v/, '');
const current = currentVersion.version.replace(/^v/, '');
const hasUpdate = this.compareVersions(current, latestVersion) < 0;
const hasUpdate = compareVersions(current, latestVersion) < 0;
return {
currentVersion: current,
@ -859,21 +860,6 @@ export class KoboldCppManager {
}
}
private compareVersions(a: string, b: string): number {
const aParts = a.split('.').map(Number);
const bParts = b.split('.').map(Number);
for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
const aPart = aParts[i] || 0;
const bPart = bParts[i] || 0;
if (aPart < bPart) return -1;
if (aPart > bPart) return 1;
}
return 0;
}
async getLatestReleaseWithDownloadStatus(): Promise<ReleaseWithStatus | null> {
try {
const latestRelease = await this.githubService.getRawLatestRelease();

View file

@ -1,11 +1,5 @@
import { contextBridge, ipcRenderer, type IpcRendererEvent } from 'electron';
import type {
KoboldAPI,
AppAPI,
ConfigAPI,
LogsAPI,
UpdateInfo,
} from '@/types/electron';
import type { KoboldAPI, AppAPI, ConfigAPI, LogsAPI } from '@/types/electron';
const koboldAPI: KoboldAPI = {
getInstalledVersion: () => ipcRenderer.invoke('kobold:getInstalledVersion'),
@ -83,12 +77,6 @@ const koboldAPI: KoboldAPI = {
(_: IpcRendererEvent, progress: number) => callback(progress)
);
},
onUpdateAvailable: (callback) => {
ipcRenderer.on(
'update-available',
(_: IpcRendererEvent, updateInfo: UpdateInfo) => callback(updateInfo)
);
},
onInstallDirChanged: (callback: (newPath: string) => void) => {
const handler = (_: IpcRendererEvent, newPath: string) => callback(newPath);
ipcRenderer.on('install-dir-changed', handler);

View file

@ -145,7 +145,6 @@ export interface KoboldAPI {
selectModelFile: () => Promise<string | null>;
stopKoboldCpp: () => void;
onDownloadProgress: (callback: (progress: number) => void) => void;
onUpdateAvailable: (callback: (updateInfo: UpdateInfo) => void) => void;
onInstallDirChanged: (callback: (newPath: string) => void) => () => void;
onVersionsUpdated: (callback: () => void) => () => void;
onKoboldOutput: (callback: (data: string) => void) => () => void;

15
src/types/index.d.ts vendored
View file

@ -26,15 +26,6 @@ export interface UpdateInfo {
hasUpdate: boolean;
}
export interface ReleaseWithStatus {
release: GitHubRelease;
availableAssets: Array<{
asset: GitHubAsset;
isDownloaded: boolean;
installedVersion?: string;
}>;
}
export interface InstalledVersion {
version: string;
path: string;
@ -42,12 +33,6 @@ export interface InstalledVersion {
size?: number;
}
export interface ROCmDownload {
name: string;
url: string;
size: number;
}
export type {
CPUCapabilities,
GPUCapabilities,

View file

@ -11,15 +11,3 @@ export function parseCLBlastDevice(deviceString: string): {
}
return null;
}
export function formatCLBlastArgs(
deviceIndex: number,
platformIndex: number
): [string, string] {
return [deviceIndex.toString(), platformIndex.toString()];
}
export function getCLBlastDeviceName(deviceString: string): string {
const match = deviceString.match(/^(.+?)\s+\(Platform:/);
return match ? match[1].trim() : deviceString;
}

View file

@ -1,13 +1,3 @@
export const formatFileSize = (bytes: number) => {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
const sizeUnit = sizes[Math.min(i, sizes.length - 1)] || 'Bytes';
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizeUnit;
};
export const formatFileSizeInMB = (bytes: number) => {
if (bytes === 0) return '0 MB';
const mb = bytes / (1024 * 1024);

View file

@ -49,6 +49,3 @@ export const IMAGE_MODEL_PRESETS: ImageModelPreset[] = [
sdvae: '',
},
];
export const getPresetByName = (name: string): ImageModelPreset | undefined =>
IMAGE_MODEL_PRESETS.find((preset) => preset.name === name);

View file

@ -4,7 +4,6 @@ export * from './downloadUtils';
export * from './fileSize';
export * from './hardware';
export * from './imageModelPresets';
export * from './nullish';
export * from './platform';
export * from './sounds';
export * from './validation';

View file

@ -1,5 +0,0 @@
export const isNotNullish = <T>(value: T | null | undefined): value is T =>
value != null;
export const isNullish = (value: unknown): value is null | undefined =>
value == null;