import { ipcMain, shell, app } from 'electron'; import type { KoboldCppManager } from '@/main/managers/KoboldCppManager'; import type { ConfigManager } from '@/main/managers/ConfigManager'; import type { LogManager } from '@/main/managers/LogManager'; import type { SillyTavernManager } from '@/main/managers/SillyTavernManager'; import { HardwareService } from '@/main/services/HardwareService'; import { BinaryService } from '@/main/services/BinaryService'; export class IPCHandlers { private koboldManager: KoboldCppManager; private configManager: ConfigManager; private logManager: LogManager; private sillyTavernManager: SillyTavernManager; private hardwareService: HardwareService; private binaryService: BinaryService; constructor( koboldManager: KoboldCppManager, configManager: ConfigManager, hardwareService: HardwareService, binaryService: BinaryService, logManager: LogManager, sillyTavernManager: SillyTavernManager ) { this.koboldManager = koboldManager; this.configManager = configManager; this.logManager = logManager; this.sillyTavernManager = sillyTavernManager; this.hardwareService = hardwareService; this.binaryService = binaryService; } private async launchKoboldCppWithCustomFrontends( args: string[] = [] ): Promise<{ success: boolean; pid?: number; error?: string; }> { try { const frontendPreference = await this.configManager.get('frontendPreference'); if (frontendPreference === 'sillytavern') { await this.sillyTavernManager.startFrontend(args); } return await this.koboldManager.launchKoboldCpp(args); } catch (error) { this.logManager.logError('Error in enhanced launch:', error as Error); return { success: false, error: (error as Error).message, }; } } setupHandlers() { ipcMain.handle('kobold:downloadRelease', async (_event, asset) => { try { const mainWindow = this.koboldManager .getWindowManager() .getMainWindow(); const filePath = await this.koboldManager.downloadRelease( asset, (progress: number) => { if (mainWindow) { mainWindow.webContents.send('download-progress', progress); } } ); return { success: true, path: filePath }; } catch (error) { return { success: false, error: (error as Error).message }; } }); ipcMain.handle('kobold:getInstalledVersions', () => this.koboldManager.getInstalledVersions() ); ipcMain.handle('kobold:getConfigFiles', () => this.koboldManager.getConfigFiles() ); ipcMain.handle( 'kobold:saveConfigFile', async (_event, configName, configData) => this.koboldManager.saveConfigFile(configName, configData) ); ipcMain.handle('kobold:getSelectedConfig', () => this.configManager.getSelectedConfig() ); ipcMain.handle('kobold:setSelectedConfig', (_event, configName) => this.configManager.setSelectedConfig(configName) ); ipcMain.handle('kobold:setCurrentVersion', (_event, version) => this.koboldManager.setCurrentVersion(version) ); ipcMain.handle('kobold:getCurrentInstallDir', () => this.koboldManager.getCurrentInstallDir() ); ipcMain.handle('kobold:selectInstallDirectory', () => this.koboldManager.selectInstallDirectory() ); ipcMain.handle('kobold:detectGPU', () => this.hardwareService.detectGPU()); ipcMain.handle('kobold:detectCPU', () => this.hardwareService.detectCPU()); ipcMain.handle('kobold:detectGPUCapabilities', () => this.hardwareService.detectGPUCapabilities() ); ipcMain.handle('kobold:detectGPUMemory', () => this.hardwareService.detectGPUMemory() ); ipcMain.handle('kobold:detectROCm', () => this.hardwareService.detectROCm() ); ipcMain.handle('kobold:detectBackendSupport', () => this.binaryService.detectBackendSupport() ); ipcMain.handle( 'kobold:getAvailableBackends', (_, includeDisabled = false) => this.binaryService.getAvailableBackends(includeDisabled) ); ipcMain.handle('kobold:getPlatform', () => ({ platform: process.platform, arch: process.arch, })); ipcMain.handle('kobold:downloadROCm', async () => { try { const mainWindow = this.koboldManager .getWindowManager() .getMainWindow(); return await this.koboldManager.downloadROCm((progress: number) => { if (mainWindow) { mainWindow.webContents.send('download-progress', progress); } }); } catch (error) { return { success: false, error: (error as Error).message }; } }); ipcMain.handle('kobold:launchKoboldCpp', (_event, args) => this.launchKoboldCppWithCustomFrontends(args) ); ipcMain.handle('kobold:stopKoboldCpp', async () => { try { this.koboldManager.stopKoboldCpp(); await this.sillyTavernManager.cleanup(); } catch (error) { this.logManager.logError('Error during stop/cleanup:', error as Error); throw error; } }); ipcMain.handle('kobold:parseConfigFile', (_event, filePath) => this.koboldManager.parseConfigFile(filePath) ); ipcMain.handle('kobold:selectModelFile', () => this.koboldManager.selectModelFile() ); ipcMain.handle('config:get', (_event, key) => this.configManager.get(key)); ipcMain.handle('config:set', (_event, key, value) => this.configManager.set(key, value) ); ipcMain.handle('app:getVersion', () => app.getVersion()); ipcMain.handle('app:openExternal', async (_event, url) => { try { await shell.openExternal(url); return { success: true }; } catch (error) { return { success: false, error: (error as Error).message }; } }); ipcMain.handle( 'logs:logError', (_event, message: string, error?: Error) => { this.logManager.logError(message, error); } ); ipcMain.handle('sillytavern:isNpxAvailable', () => this.sillyTavernManager.isNpxAvailable() ); } }