mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 09:33:10 -07:00
windows needs special handling for CLI mode
This commit is contained in:
parent
31a1b2485f
commit
a2695109a6
4 changed files with 48 additions and 18 deletions
13
README.md
13
README.md
|
|
@ -22,9 +22,10 @@ A desktop app for running Large Language Models locally. <!-- markdownlint-disab
|
||||||
|
|
||||||
Download the latest release for your platform from the [GitHub Releases page](https://github.com/lone-cloud/friendly-kobold/releases/latest):
|
Download the latest release for your platform from the [GitHub Releases page](https://github.com/lone-cloud/friendly-kobold/releases/latest):
|
||||||
|
|
||||||
- **Windows**: `Friendly-Kobold-X.X.X.exe` (portable executable)
|
- **Windows**: `Friendly Kobold Portable X.X.X.exe` (portable executable)
|
||||||
- **macOS**: `Friendly-Kobold-X.X.X.dmg` (disk image)
|
- **Windows**: `Friendly Kobold Setup X.X.X.exe` (installer executable - **recommended for CLI mode**)
|
||||||
- **Linux**: `Friendly-Kobold-X.X.X.AppImage` (portable application)
|
- **macOS**: `Friendly Kobold-X.X.X.dmg` (disk image)
|
||||||
|
- **Linux**: `Friendly Kobold-X.X.X.AppImage` (portable application)
|
||||||
|
|
||||||
#### Linux - AUR (Arch Linux)
|
#### Linux - AUR (Arch Linux)
|
||||||
|
|
||||||
|
|
@ -93,6 +94,8 @@ You might want to run CLI Mode if you're looking to use a different frontend, su
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
|
**Linux/macOS:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Basic usage - launch KoboldCpp with no arguments
|
# Basic usage - launch KoboldCpp with no arguments
|
||||||
./friendly-kobold --cli
|
./friendly-kobold --cli
|
||||||
|
|
@ -105,6 +108,10 @@ You might want to run CLI Mode if you're looking to use a different frontend, su
|
||||||
./friendly-kobold --cli --model /path/to/model.gguf --port 5001 --host 0.0.0.0 --multiuser 2
|
./friendly-kobold --cli --model /path/to/model.gguf --port 5001 --host 0.0.0.0 --multiuser 2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
|
||||||
|
CLI mode will only work correctly on Windows if you install Friendly Kobold using the Setup.exe from the github releases. Otherwise there is currently a technical limitation with the Windows portable .exe which will cause it to not display the terminal output correctly nor will it be killable through the standard terminal (Ctrl+C) commands.
|
||||||
|
|
||||||
## For Local Dev
|
## For Local Dev
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
|
||||||
17
package.json
17
package.json
|
|
@ -153,6 +153,12 @@
|
||||||
"win": {
|
"win": {
|
||||||
"compression": "normal",
|
"compression": "normal",
|
||||||
"target": [
|
"target": [
|
||||||
|
{
|
||||||
|
"target": "nsis",
|
||||||
|
"arch": [
|
||||||
|
"x64"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"target": "portable",
|
"target": "portable",
|
||||||
"arch": [
|
"arch": [
|
||||||
|
|
@ -161,6 +167,17 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"nsis": {
|
||||||
|
"artifactName": "${productName} Setup ${version}.${ext}",
|
||||||
|
"oneClick": false,
|
||||||
|
"allowToChangeInstallationDirectory": true,
|
||||||
|
"createDesktopShortcut": true,
|
||||||
|
"createStartMenuShortcut": true,
|
||||||
|
"shortcutName": "Friendly Kobold"
|
||||||
|
},
|
||||||
|
"portable": {
|
||||||
|
"artifactName": "${productName} Portable ${version}.${ext}"
|
||||||
|
},
|
||||||
"linux": {
|
"linux": {
|
||||||
"compression": "store",
|
"compression": "store",
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,6 @@ if (isCliMode) {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runCliMode();
|
runCliMode();
|
||||||
} else {
|
} else {
|
||||||
const friendlyKoboldApp = new FriendlyKoboldApp();
|
const friendlyKoboldApp = new FriendlyKoboldApp();
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable no-console */
|
||||||
import { spawn } from 'child_process';
|
import { spawn } from 'child_process';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import { app } from 'electron';
|
import { app } from 'electron';
|
||||||
|
|
@ -27,7 +28,6 @@ export class CliHandler {
|
||||||
const currentBinary = this.configManager.getCurrentKoboldBinary();
|
const currentBinary = this.configManager.getCurrentKoboldBinary();
|
||||||
|
|
||||||
if (!currentBinary) {
|
if (!currentBinary) {
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(
|
console.error(
|
||||||
'Error: No KoboldCpp binary found. Please run the GUI first to download KoboldCpp.'
|
'Error: No KoboldCpp binary found. Please run the GUI first to download KoboldCpp.'
|
||||||
);
|
);
|
||||||
|
|
@ -35,29 +35,38 @@ export class CliHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!existsSync(currentBinary)) {
|
if (!existsSync(currentBinary)) {
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(`Error: KoboldCpp binary not found at: ${currentBinary}`);
|
console.error(`Error: KoboldCpp binary not found at: ${currentBinary}`);
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error('Please run the GUI to download or reconfigure KoboldCpp.');
|
console.error('Please run the GUI to download or reconfigure KoboldCpp.');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Launching KoboldCpp: ${currentBinary}`);
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Arguments: ${args.join(' ')}`);
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log('─'.repeat(60));
|
|
||||||
|
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
const isWindows = process.platform === 'win32';
|
||||||
|
|
||||||
const child = spawn(currentBinary, args, {
|
const child = spawn(currentBinary, args, {
|
||||||
stdio: 'inherit',
|
stdio: isWindows ? 'pipe' : 'inherit',
|
||||||
detached: false,
|
detached: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (isWindows) {
|
||||||
|
child.stdout?.setEncoding('utf8');
|
||||||
|
child.stderr?.setEncoding('utf8');
|
||||||
|
|
||||||
|
child.stdout?.on('data', (data) => {
|
||||||
|
process.stdout.write(data.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
child.stderr?.on('data', (data) => {
|
||||||
|
process.stderr.write(data.toString());
|
||||||
|
});
|
||||||
|
|
||||||
|
if (child.stdin && process.stdin.readable) {
|
||||||
|
process.stdin.pipe(child.stdin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
child.on('exit', (code, signal) => {
|
child.on('exit', (code, signal) => {
|
||||||
if (signal) {
|
if (signal) {
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`\nProcess terminated with signal: ${signal}`);
|
console.log(`\nProcess terminated with signal: ${signal}`);
|
||||||
process.exit(128 + (signal === 'SIGTERM' ? 15 : 2));
|
process.exit(128 + (signal === 'SIGTERM' ? 15 : 2));
|
||||||
} else if (code !== null) {
|
} else if (code !== null) {
|
||||||
|
|
@ -68,13 +77,11 @@ export class CliHandler {
|
||||||
});
|
});
|
||||||
|
|
||||||
child.on('error', (error) => {
|
child.on('error', (error) => {
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(`Failed to start KoboldCpp: ${error.message}`);
|
console.error(`Failed to start KoboldCpp: ${error.message}`);
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleSignal = () => {
|
const handleSignal = () => {
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log('\nReceived termination signal, terminating KoboldCpp...');
|
console.log('\nReceived termination signal, terminating KoboldCpp...');
|
||||||
if (!child.killed) {
|
if (!child.killed) {
|
||||||
child.kill('SIGTERM');
|
child.kill('SIGTERM');
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue