From 1874128dacbae0d7159b406f473dc5a408a7fca1 Mon Sep 17 00:00:00 2001 From: Egor Date: Thu, 4 Sep 2025 17:49:20 -0700 Subject: [PATCH] monkey patch koboldai lite on unpack to make it look better, minor improvements --- .nvmrc | 2 +- package.json | 4 +- src/components/DownloadCard.tsx | 5 +- src/components/screens/Download.tsx | 101 ++++++++++---------- src/components/settings/AboutTab.tsx | 2 +- src/main/managers/KoboldCppManager.ts | 129 ++++++++++++++++++++++++-- yarn.lock | 13 ++- 7 files changed, 187 insertions(+), 69 deletions(-) diff --git a/.nvmrc b/.nvmrc index 91d5f6f..e222811 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.18.0 +22.19.0 diff --git a/package.json b/package.json index 3dee6c4..bc86e1b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "gerbil", "productName": "Gerbil", - "version": "0.9.10", + "version": "0.9.11", "description": "Run Large Language Models locally", "main": "out/main/index.js", "homepage": "./", @@ -39,7 +39,7 @@ "license": "AGPL-3.0-or-later", "devDependencies": { "@eslint/js": "^9.34.0", - "@types/node": "^24.3.0", + "@types/node": "^24.3.1", "@types/react": "^19.1.12", "@types/react-dom": "^19.1.9", "@typescript-eslint/eslint-plugin": "^8.42.0", diff --git a/src/components/DownloadCard.tsx b/src/components/DownloadCard.tsx index 5304be7..50d7588 100644 --- a/src/components/DownloadCard.tsx +++ b/src/components/DownloadCard.tsx @@ -177,7 +177,10 @@ export const DownloadCard = ({ radius="xl" /> - {Math.min(downloadProgress, 100).toFixed(1)}% complete + {Math.min(downloadProgress, 100) === 100 + ? '100%' + : `${Math.min(downloadProgress, 100).toFixed(1)}%`}{' '} + complete )} diff --git a/src/components/screens/Download.tsx b/src/components/screens/Download.tsx index fe86dce..8df19c2 100644 --- a/src/components/screens/Download.tsx +++ b/src/components/screens/Download.tsx @@ -78,59 +78,56 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => { ) : ( <> - {availableDownloads.length > 0 && ( - <> - {availableDownloads.length > 0 ? ( - - {sortedDownloads.map((download) => { - const isDownloading = - Boolean(downloading) && - downloadingAsset === download.name; + {availableDownloads.length > 0 ? ( + + {sortedDownloads.map((download) => { + const isDownloading = + Boolean(downloading) && + downloadingAsset === download.name; - return ( -
- { - e.stopPropagation(); - handleDownload(download); - }} - /> -
- ); - })} -
- ) : ( - - - No downloads available - - No downloads available for your platform ( - {getPlatformDisplayName(platform)}). - - - - )} - + return ( +
+ { + e.stopPropagation(); + handleDownload(download); + }} + /> +
+ ); + })} +
+ ) : ( + + + No downloads available + + Unable to fetch downloads for your platform ( + {getPlatformDisplayName(platform)}). Please check your + internet connection and try again. + + + )} )} diff --git a/src/components/settings/AboutTab.tsx b/src/components/settings/AboutTab.tsx index 29b2f2c..7db3053 100644 --- a/src/components/settings/AboutTab.tsx +++ b/src/components/settings/AboutTab.tsx @@ -54,7 +54,7 @@ export const AboutTab = () => { const copyVersionInfo = async () => { const info = [ - `${PRODUCT_NAME}: v${versionInfo.appVersion}`, + `${PRODUCT_NAME}: ${versionInfo.appVersion}`, `Electron: ${versionInfo.electronVersion}`, `Node.js: ${versionInfo.nodeVersion}`, `Chromium: ${versionInfo.chromeVersion}`, diff --git a/src/main/managers/KoboldCppManager.ts b/src/main/managers/KoboldCppManager.ts index 78dd1dc..030b41d 100644 --- a/src/main/managers/KoboldCppManager.ts +++ b/src/main/managers/KoboldCppManager.ts @@ -1,7 +1,17 @@ import { spawn, ChildProcess } from 'child_process'; import { createWriteStream } from 'fs'; import { join } from 'path'; -import { rm, readdir, stat, unlink, rename, mkdir, chmod } from 'fs/promises'; +import { + rm, + readdir, + stat, + unlink, + rename, + mkdir, + chmod, + readFile, + writeFile, +} from 'fs/promises'; import { dialog } from 'electron'; import axios from 'axios'; @@ -210,6 +220,7 @@ export class KoboldCppManager { await this.downloadFile(asset, tempPackedFilePath); await mkdir(unpackedDirPath, { recursive: true }); await this.unpackKoboldCpp(tempPackedFilePath, unpackedDirPath); + await this.patchKliteEmbd(unpackedDirPath); const launcherPath = await this.setupLauncher( tempPackedFilePath, unpackedDirPath @@ -254,6 +265,113 @@ export class KoboldCppManager { } } + private async patchKliteEmbd(unpackedDir: string): Promise { + try { + const possiblePaths = [ + join(unpackedDir, '_internal', 'klite.embd'), + join(unpackedDir, 'klite.embd'), + ]; + + let kliteEmbdPath: string | null = null; + for (const path of possiblePaths) { + if (await pathExists(path)) { + kliteEmbdPath = path; + break; + } + } + + if (!kliteEmbdPath) { + this.logManager.logError( + 'klite.embd file not found in unpacked directory', + new Error('File not found') + ); + return; + } + + this.windowManager.sendKoboldOutput( + 'Injecting CSS override for better iframe display...' + ); + + const content = await readFile(kliteEmbdPath, 'utf8'); + + const customCssOverride = ` +`; + + if (content.includes('')) { + const patchedContent = content.replace( + '', + `${customCssOverride}\n` + ); + await writeFile(kliteEmbdPath, patchedContent, 'utf8'); + this.windowManager.sendKoboldOutput( + 'Successfully injected CSS override to klite.embd' + ); + } else { + this.windowManager.sendKoboldOutput( + 'Warning: Could not find tag in klite.embd, skipping CSS injection' + ); + } + } catch (error) { + this.logManager.logError('Failed to patch klite.embd:', error as Error); + this.windowManager.sendKoboldOutput( + 'Warning: Failed to patch klite.embd CSS, but continuing with installation...' + ); + } + } + private async getLauncherPath(unpackedDir: string): Promise { const extensions = process.platform === 'win32' ? ['.exe', ''] : ['', '.exe']; @@ -604,15 +722,6 @@ export class KoboldCppManager { } } - isRunning() { - return this.koboldProcess !== null && !this.koboldProcess.killed; - } - - async getInstalledVersion(): Promise { - const currentVersion = await this.getCurrentVersion(); - return currentVersion?.version; - } - async launchKoboldCpp( args: string[] = [] ): Promise<{ success: boolean; pid?: number; error?: string }> { diff --git a/yarn.lock b/yarn.lock index f1f642b..7c2a60e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1280,7 +1280,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^24.3.0": +"@types/node@npm:*": version: 24.3.0 resolution: "@types/node@npm:24.3.0" dependencies: @@ -1298,6 +1298,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^24.3.1": + version: 24.3.1 + resolution: "@types/node@npm:24.3.1" + dependencies: + undici-types: "npm:~7.10.0" + checksum: 10c0/99b86fc32294fcd61136ca1f771026443a1e370e9f284f75e243b29299dd878e18c193deba1ce29a374932db4e30eb80826e1049b9aad02d36f5c30b94b6f928 + languageName: node + linkType: hard + "@types/plist@npm:^3.0.1": version: 3.0.5 resolution: "@types/plist@npm:3.0.5" @@ -3638,7 +3647,7 @@ __metadata: "@eslint/js": "npm:^9.34.0" "@mantine/core": "npm:^8.2.8" "@mantine/hooks": "npm:^8.2.8" - "@types/node": "npm:^24.3.0" + "@types/node": "npm:^24.3.1" "@types/react": "npm:^19.1.12" "@types/react-dom": "npm:^19.1.9" "@typescript-eslint/eslint-plugin": "npm:^8.42.0"