mirror of
https://github.com/wiseguru/ReWrite-Voice-Notes.git
synced 2026-07-22 07:49:19 +00:00
Added a whisper.cpp auto lookup
This commit is contained in:
parent
c74f74abc9
commit
7ab2bc287d
2 changed files with 50 additions and 3 deletions
|
|
@ -120,7 +120,9 @@ Per-adapter behavior: [src/transcription/assemblyai.ts](src/transcription/assemb
|
|||
|
||||
## Local whisper.cpp host (desktop)
|
||||
|
||||
[src/whisper-host.ts](src/whisper-host.ts) exposes the `WhisperHost` class. The plugin instantiates one in `onload` and stops it in `onunload`. Configuration lives at `GlobalSettings.localWhisper = { binaryPath, modelPath, port, extraArgs }` — all user-supplied. No discovery, no PATH lookup, no auto-download.
|
||||
[src/whisper-host.ts](src/whisper-host.ts) exposes the `WhisperHost` class. The plugin instantiates one in `onload` and stops it in `onunload`. Configuration lives at `GlobalSettings.localWhisper = { binaryPath, modelPath, port, extraArgs }` — all user-supplied. No automatic discovery, no PATH lookup at runtime, no auto-download. The one (user-initiated) convenience is the **Auto-detect** button beside the Binary path field in settings: `detectWhisperBinary()` in [src/settings/tab.ts](src/settings/tab.ts) lazy-requires `fs`/`os`/`path` (same `window.require` + `Platform.isDesktop` guard as `whisper-host.ts`) and returns the first existing candidate from the build script's install locations (`~/.local/bin/whisper-server`, then `~/.local/share/whisper.cpp/build/bin/whisper-server`) followed by common system/Homebrew paths (`/usr/local/bin`, `/opt/homebrew/bin`, `/usr/bin`); `.exe` suffix on Windows. It only checks existence when clicked and never runs the binary. The `binaryPath` default stays `''` (the setup-card gating depends on it), so this is a fill-in helper, not a baked default.
|
||||
|
||||
The companion CLI installer is [scripts/build-whisper-linux.sh](scripts/build-whisper-linux.sh): it clones/builds whisper.cpp into `~/.local/share/whisper.cpp` (override `--source-dir`), symlinks the binary to `~/.local/bin/whisper-server` (override `--prefix`, skip with `--no-symlink`), and prints the final Binary path to paste into settings. Keep the Auto-detect candidate list in sync with this script's default paths.
|
||||
|
||||
`start()` validates the binary and model paths exist via `fs.existsSync`, probes the port via `net.createServer().listen(port)` to detect conflicts, spawns the user's whisper-server with `child_process.spawn`, captures stdout/stderr into a 1 MB ring buffer, then polls `net.createConnection` against the port every 250 ms for up to 5 s before declaring `'running'`. Any failure transitions status to `'crashed'` with the log tail surfaced in the error message. `stop()` sends SIGTERM, waits up to 3 s, then SIGKILL.
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,38 @@ import { PassphraseModal } from '../ui/passphrase-modal';
|
|||
// Sentinel value for the "Custom..." entry in a model dropdown; never written to config.model.
|
||||
const CUSTOM_MODEL_OPTION = '__rewrite_custom__';
|
||||
|
||||
// Probe the locations scripts/build-whisper-linux.sh installs whisper-server to,
|
||||
// plus the common system/Homebrew paths, and return the first that exists.
|
||||
// Desktop-only (lazy-requires fs/os via the same window.require pattern as whisper-host.ts);
|
||||
// returns null on mobile, when require is unavailable, or when nothing is found.
|
||||
function detectWhisperBinary(): string | null {
|
||||
if (!Platform.isDesktop) return null;
|
||||
try {
|
||||
const req = (window as unknown as { require?: (m: string) => unknown }).require;
|
||||
if (typeof req !== 'function') return null;
|
||||
const fs = req('fs') as { existsSync(p: string): boolean };
|
||||
const os = req('os') as { homedir(): string };
|
||||
const path = req('path') as { join(...parts: string[]): string };
|
||||
const home = os.homedir();
|
||||
const exe = Platform.isWin ? 'whisper-server.exe' : 'whisper-server';
|
||||
const candidates = [
|
||||
// Build-script defaults: symlink first, then the built binary.
|
||||
path.join(home, '.local', 'bin', exe),
|
||||
path.join(home, '.local', 'share', 'whisper.cpp', 'build', 'bin', exe),
|
||||
// Common system / Homebrew locations.
|
||||
path.join('/usr', 'local', 'bin', exe),
|
||||
path.join('/opt', 'homebrew', 'bin', exe),
|
||||
path.join('/usr', 'bin', exe),
|
||||
];
|
||||
for (const candidate of candidates) {
|
||||
if (fs.existsSync(candidate)) return candidate;
|
||||
}
|
||||
return null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup output runs ~256 tokens per minute of speech (≈150 wpm × ~1.3 tokens/word,
|
||||
// padded ~20% for headings, bullets, and Speaker labels in structured/diarized notes).
|
||||
// The "Maximum note length" dropdown maps these minute presets onto config.maxTokens;
|
||||
|
|
@ -718,14 +750,27 @@ export class ReWriteSettingTab extends PluginSettingTab {
|
|||
|
||||
new Setting(parent)
|
||||
.setName('Binary path')
|
||||
.setDesc('Absolute path to whisper-server (or whisper-server.exe on Windows).')
|
||||
.setDesc('Absolute path to whisper-server (or whisper-server.exe on Windows). The Linux build script (scripts/build-whisper-linux.sh) installs it to ~/.local/bin/whisper-server by default; use Auto-detect to fill this in.')
|
||||
.addText((t) => {
|
||||
t.setValue(cfg.binaryPath);
|
||||
t.setPlaceholder('/usr/local/bin/whisper-server');
|
||||
t.setPlaceholder('~/.local/bin/whisper-server');
|
||||
t.onChange(async (v) => {
|
||||
cfg.binaryPath = v;
|
||||
await this.commit();
|
||||
});
|
||||
})
|
||||
.addExtraButton((b) => {
|
||||
b.setIcon('search').setTooltip('Look for whisper-server in the build script\'s install locations').onClick(() => void this.runGuardedButton(b, async () => {
|
||||
const found = detectWhisperBinary();
|
||||
if (found) {
|
||||
cfg.binaryPath = found;
|
||||
await this.commit();
|
||||
new Notice(`ReWrite: found whisper-server at ${found}`);
|
||||
this.display();
|
||||
} else {
|
||||
new Notice('ReWrite: no whisper-server found in the usual install locations. Set the path manually.');
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
new Setting(parent)
|
||||
|
|
|
|||
Loading…
Reference in a new issue