mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 19:54:44 -07:00
monkey patch koboldai lite on unpack to make it look better, minor improvements
This commit is contained in:
parent
2b912cb22e
commit
1874128dac
7 changed files with 187 additions and 69 deletions
2
.nvmrc
2
.nvmrc
|
|
@ -1 +1 @@
|
|||
22.18.0
|
||||
22.19.0
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -177,7 +177,10 @@ export const DownloadCard = ({
|
|||
radius="xl"
|
||||
/>
|
||||
<Text size="xs" c="dimmed" ta="center">
|
||||
{Math.min(downloadProgress, 100).toFixed(1)}% complete
|
||||
{Math.min(downloadProgress, 100) === 100
|
||||
? '100%'
|
||||
: `${Math.min(downloadProgress, 100).toFixed(1)}%`}{' '}
|
||||
complete
|
||||
</Text>
|
||||
</Stack>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -78,59 +78,56 @@ export const DownloadScreen = ({ onDownloadComplete }: DownloadScreenProps) => {
|
|||
</Stack>
|
||||
) : (
|
||||
<>
|
||||
{availableDownloads.length > 0 && (
|
||||
<>
|
||||
{availableDownloads.length > 0 ? (
|
||||
<Stack gap="sm">
|
||||
{sortedDownloads.map((download) => {
|
||||
const isDownloading =
|
||||
Boolean(downloading) &&
|
||||
downloadingAsset === download.name;
|
||||
{availableDownloads.length > 0 ? (
|
||||
<Stack gap="sm">
|
||||
{sortedDownloads.map((download) => {
|
||||
const isDownloading =
|
||||
Boolean(downloading) &&
|
||||
downloadingAsset === download.name;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={download.name}
|
||||
ref={isDownloading ? downloadingItemRef : null}
|
||||
>
|
||||
<DownloadCard
|
||||
name={download.name}
|
||||
size={formatDownloadSize(
|
||||
download.size,
|
||||
download.url
|
||||
)}
|
||||
version={download.version}
|
||||
description={getAssetDescription(download.name)}
|
||||
isDownloading={isDownloading}
|
||||
downloadProgress={
|
||||
isDownloading
|
||||
? downloadProgress[download.name] || 0
|
||||
: 0
|
||||
}
|
||||
disabled={
|
||||
Boolean(downloading) &&
|
||||
downloadingAsset !== download.name
|
||||
}
|
||||
onDownload={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDownload(download);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</Stack>
|
||||
) : (
|
||||
<Card withBorder p="md" bg="yellow.0" c="yellow.9">
|
||||
<Stack gap="xs">
|
||||
<Text fw={500}>No downloads available</Text>
|
||||
<Text size="sm">
|
||||
No downloads available for your platform (
|
||||
{getPlatformDisplayName(platform)}).
|
||||
</Text>
|
||||
</Stack>
|
||||
</Card>
|
||||
)}
|
||||
</>
|
||||
return (
|
||||
<div
|
||||
key={download.name}
|
||||
ref={isDownloading ? downloadingItemRef : null}
|
||||
>
|
||||
<DownloadCard
|
||||
name={download.name}
|
||||
size={formatDownloadSize(
|
||||
download.size,
|
||||
download.url
|
||||
)}
|
||||
version={download.version}
|
||||
description={getAssetDescription(download.name)}
|
||||
isDownloading={isDownloading}
|
||||
downloadProgress={
|
||||
isDownloading
|
||||
? downloadProgress[download.name] || 0
|
||||
: 0
|
||||
}
|
||||
disabled={
|
||||
Boolean(downloading) &&
|
||||
downloadingAsset !== download.name
|
||||
}
|
||||
onDownload={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDownload(download);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</Stack>
|
||||
) : (
|
||||
<Card withBorder p="md" bg="red.0" c="red.9">
|
||||
<Stack gap="xs">
|
||||
<Text fw={500}>No downloads available</Text>
|
||||
<Text size="sm">
|
||||
Unable to fetch downloads for your platform (
|
||||
{getPlatformDisplayName(platform)}). Please check your
|
||||
internet connection and try again.
|
||||
</Text>
|
||||
</Stack>
|
||||
</Card>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -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}`,
|
||||
|
|
|
|||
|
|
@ -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<void> {
|
||||
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 = `
|
||||
<style id="gerbil-css-override">
|
||||
* {
|
||||
transition: 100ms ease all;
|
||||
}
|
||||
.maincontainer {
|
||||
padding-right: 0 !important;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
.adaptivecontainer {
|
||||
width: 100% !important;
|
||||
}
|
||||
#lastreq1 {
|
||||
margin: 0 10px;
|
||||
}
|
||||
#inputrow {
|
||||
padding: 0 10px;
|
||||
}
|
||||
#actionmenuitems {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.topmenu {
|
||||
padding: 10px;
|
||||
}
|
||||
#navbarNavDropdown {
|
||||
padding: 0;
|
||||
}
|
||||
#inputrow > :nth-child(1) {
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
#inputrow.show_mode > :nth-child(1) {
|
||||
flex: 0 0 70px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
#inputrow > :nth-child(3) {
|
||||
flex: 0 0 70px;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
#inputrow.show_mode > :nth-child(3) button {
|
||||
background-color: #129c00;
|
||||
font-size: 14px;
|
||||
}
|
||||
#inputrow.show_mode > :nth-child(3) button:hover {
|
||||
background-color: #058105;
|
||||
}
|
||||
#actionmenuitems + div {
|
||||
margin-right: 10px;
|
||||
}
|
||||
#actionmenuitems button, #actionmenuitems2 button {
|
||||
background-color: #337ab7 !important;
|
||||
}
|
||||
#actionmenuitems button:hover, #actionmenuitems2 button:hover {
|
||||
background-color: #286090 !important;
|
||||
}
|
||||
</style>`;
|
||||
|
||||
if (content.includes('</head>')) {
|
||||
const patchedContent = content.replace(
|
||||
'</head>',
|
||||
`${customCssOverride}\n</head>`
|
||||
);
|
||||
await writeFile(kliteEmbdPath, patchedContent, 'utf8');
|
||||
this.windowManager.sendKoboldOutput(
|
||||
'Successfully injected CSS override to klite.embd'
|
||||
);
|
||||
} else {
|
||||
this.windowManager.sendKoboldOutput(
|
||||
'Warning: Could not find </head> 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<string | null> {
|
||||
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<string | undefined> {
|
||||
const currentVersion = await this.getCurrentVersion();
|
||||
return currentVersion?.version;
|
||||
}
|
||||
|
||||
async launchKoboldCpp(
|
||||
args: string[] = []
|
||||
): Promise<{ success: boolean; pid?: number; error?: string }> {
|
||||
|
|
|
|||
13
yarn.lock
13
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"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue