implement modular backend setup scripts, new frontend components, and expanded server services

This commit is contained in:
techjarves committed 2026-06-22 10:10:29 +05:30
1 parent bd89699994
commit ffec37fd0a
27 files changed
+309 -149

No files matched your search

+1 -1
View File
@@ -7,7 +7,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
APP_DIR="$ROOT_DIR/app"
PLATFORM="$(uname -s)"
if [ "$PLATFORM" = "Darwin" ]; then
File renamed without changes.
@@ -1,8 +1,8 @@
# scripts/reset.ps1
# scripts/reset/reset.ps1
# Resets portable app dependencies/builds while preserving user models and outputs.
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$rootDir = Split-Path -Parent $scriptDir
$rootDir = Split-Path -Parent (Split-Path -Parent $scriptDir)
$appDir = Join-Path $rootDir "app"
Write-Host ""
+1 -1
View File
@@ -7,7 +7,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
APP_DIR="$ROOT_DIR/app"
echo ""
+109 -25
View File
@@ -38,7 +38,7 @@ let PORT_SPEECH = PREFERRED_SPEECH_PORT;
let PORT_TTS = PREFERRED_TTS_PORT;
const MAX_JSON_BODY_BYTES = 64 * 1024 * 1024;
const SERVER_BUILD = "text-image-v1";
const ROOT = path.join(__dirname, "..");
const ROOT = path.join(__dirname, "..", "..");
const DIST = path.join(ROOT, "app", "dist");
const osPlatform = process.platform;
const BACKEND_PATHS = {
@@ -130,12 +130,25 @@ if (!fs.existsSync(TTS_CACHE)) {
fs.mkdirSync(TTS_CACHE, { recursive: true });
}
const TTS_RUNTIME = path.join(ROOT, "app", "tts-runtime");
const TTS_WORKER = path.join(ROOT, "scripts", "tts-kokoro-worker.mjs");
const TTS_WORKER = path.join(ROOT, "scripts", "workers", "tts-kokoro-worker.mjs");
const SPEECH_BACKEND_ROOT = path.join(ROOT, "app", "speech-backend");
const SPEECH_BACKEND_PATHS = {
winVulkanCli: path.join(SPEECH_BACKEND_ROOT, "win", "vulkan", "whisper-cli.exe"),
winVulkanServer: path.join(SPEECH_BACKEND_ROOT, "win", "vulkan", "whisper-server.exe"),
winCpuCli: path.join(SPEECH_BACKEND_ROOT, "win", "cpu", "whisper-cli.exe"),
winCpuServer: path.join(SPEECH_BACKEND_ROOT, "win", "cpu", "whisper-server.exe"),
winCli: path.join(ROOT, "app", "speech-backend", "win", "whisper-cli.exe"),
winServer: path.join(ROOT, "app", "speech-backend", "win", "whisper-server.exe"),
linuxVulkanCli: path.join(SPEECH_BACKEND_ROOT, "linux", "vulkan", "whisper-cli"),
linuxVulkanServer: path.join(SPEECH_BACKEND_ROOT, "linux", "vulkan", "whisper-server"),
linuxCpuCli: path.join(SPEECH_BACKEND_ROOT, "linux", "cpu", "whisper-cli"),
linuxCpuServer: path.join(SPEECH_BACKEND_ROOT, "linux", "cpu", "whisper-server"),
linuxCli: path.join(ROOT, "app", "speech-backend", "linux", "whisper-cli"),
linuxServer: path.join(ROOT, "app", "speech-backend", "linux", "whisper-server"),
macMetalCli: path.join(SPEECH_BACKEND_ROOT, "mac", "metal", "whisper-cli"),
macMetalServer: path.join(SPEECH_BACKEND_ROOT, "mac", "metal", "whisper-server"),
macCpuCli: path.join(SPEECH_BACKEND_ROOT, "mac", "cpu", "whisper-cli"),
macCpuServer: path.join(SPEECH_BACKEND_ROOT, "mac", "cpu", "whisper-server"),
macCli: path.join(ROOT, "app", "speech-backend", "mac", "whisper-cli"),
macServer: path.join(ROOT, "app", "speech-backend", "mac", "whisper-server"),
};
@@ -227,6 +240,7 @@ let speechSettings = {
model: null,
language: "auto",
threads: Math.max(1, Math.min(8, os.cpus().length || 4)),
backendPreference: "auto",
backendBinary: "",
backendMode: "",
};
@@ -1391,8 +1405,8 @@ function getOpenVinoNpuInfo() {
const python = getOpenVinoPython();
if (!python) {
const setupScript = osPlatform === "win32"
? "scripts/setup-openvino-npu.ps1"
: "bash scripts/setup-openvino-npu.sh";
? "scripts/setup/setup-openvino-npu.ps1"
: "bash scripts/setup/setup-openvino-npu.sh";
cachedOpenVinoNpuInfo = {
supported: false,
reason: `OpenVINO GenAI runtime is not installed. Run ${setupScript} first.`,
@@ -1669,25 +1683,86 @@ function findExistingFile(candidates) {
return candidates.find((candidate) => candidate && fs.existsSync(candidate)) || "";
}
function getSpeechBackend() {
function getSpeechBackendCandidates() {
if (osPlatform === "win32") {
return {
cli: findExistingFile([SPEECH_BACKEND_PATHS.winCli, path.join(ROOT, "app", "speech-backend", "win", "main.exe")]),
server: findExistingFile([SPEECH_BACKEND_PATHS.winServer, path.join(ROOT, "app", "speech-backend", "win", "server.exe")]),
mode: "whisper.cpp CPU",
};
return [
{
key: "vulkan",
label: "Vulkan GPU",
mode: "whisper.cpp Vulkan GPU",
cli: findExistingFile([SPEECH_BACKEND_PATHS.winVulkanCli, path.join(SPEECH_BACKEND_ROOT, "win", "vulkan", "main.exe")]),
server: findExistingFile([SPEECH_BACKEND_PATHS.winVulkanServer, path.join(SPEECH_BACKEND_ROOT, "win", "vulkan", "server.exe")]),
pathHint: path.join(SPEECH_BACKEND_ROOT, "win", "vulkan"),
},
{
key: "cpu",
label: "CPU",
mode: "whisper.cpp CPU",
cli: findExistingFile([SPEECH_BACKEND_PATHS.winCpuCli, SPEECH_BACKEND_PATHS.winCli, path.join(SPEECH_BACKEND_ROOT, "win", "cpu", "main.exe"), path.join(SPEECH_BACKEND_ROOT, "win", "main.exe")]),
server: findExistingFile([SPEECH_BACKEND_PATHS.winCpuServer, SPEECH_BACKEND_PATHS.winServer, path.join(SPEECH_BACKEND_ROOT, "win", "cpu", "server.exe"), path.join(SPEECH_BACKEND_ROOT, "win", "server.exe")]),
pathHint: path.join(SPEECH_BACKEND_ROOT, "win", "cpu"),
},
];
}
if (osPlatform === "darwin") {
return {
cli: findExistingFile([SPEECH_BACKEND_PATHS.macCli, path.join(ROOT, "app", "speech-backend", "mac", "main")]),
server: findExistingFile([SPEECH_BACKEND_PATHS.macServer, path.join(ROOT, "app", "speech-backend", "mac", "server")]),
mode: "whisper.cpp Metal/CPU",
};
return [
{
key: "metal",
label: "Metal GPU",
mode: "whisper.cpp Metal GPU",
cli: findExistingFile([SPEECH_BACKEND_PATHS.macMetalCli, path.join(SPEECH_BACKEND_ROOT, "mac", "metal", "main")]),
server: findExistingFile([SPEECH_BACKEND_PATHS.macMetalServer, path.join(SPEECH_BACKEND_ROOT, "mac", "metal", "server")]),
pathHint: path.join(SPEECH_BACKEND_ROOT, "mac", "metal"),
},
{
key: "cpu",
label: "CPU",
mode: "whisper.cpp CPU",
cli: findExistingFile([SPEECH_BACKEND_PATHS.macCpuCli, SPEECH_BACKEND_PATHS.macCli, path.join(SPEECH_BACKEND_ROOT, "mac", "cpu", "main"), path.join(SPEECH_BACKEND_ROOT, "mac", "main")]),
server: findExistingFile([SPEECH_BACKEND_PATHS.macCpuServer, SPEECH_BACKEND_PATHS.macServer, path.join(SPEECH_BACKEND_ROOT, "mac", "cpu", "server"), path.join(SPEECH_BACKEND_ROOT, "mac", "server")]),
pathHint: path.join(SPEECH_BACKEND_ROOT, "mac", "cpu"),
},
];
}
return [
{
key: "vulkan",
label: "Vulkan GPU",
mode: "whisper.cpp Vulkan GPU",
cli: findExistingFile([SPEECH_BACKEND_PATHS.linuxVulkanCli, path.join(SPEECH_BACKEND_ROOT, "linux", "vulkan", "main")]),
server: findExistingFile([SPEECH_BACKEND_PATHS.linuxVulkanServer, path.join(SPEECH_BACKEND_ROOT, "linux", "vulkan", "server")]),
pathHint: path.join(SPEECH_BACKEND_ROOT, "linux", "vulkan"),
},
{
key: "cpu",
label: "CPU",
mode: "whisper.cpp CPU",
cli: findExistingFile([SPEECH_BACKEND_PATHS.linuxCpuCli, SPEECH_BACKEND_PATHS.linuxCli, path.join(SPEECH_BACKEND_ROOT, "linux", "cpu", "main"), path.join(SPEECH_BACKEND_ROOT, "linux", "main")]),
server: findExistingFile([SPEECH_BACKEND_PATHS.linuxCpuServer, SPEECH_BACKEND_PATHS.linuxServer, path.join(SPEECH_BACKEND_ROOT, "linux", "cpu", "server"), path.join(SPEECH_BACKEND_ROOT, "linux", "server")]),
pathHint: path.join(SPEECH_BACKEND_ROOT, "linux", "cpu"),
},
];
}
function normalizeSpeechBackendPreference(value) {
const raw = String(value || "auto").trim().toLowerCase();
if (["auto", "cpu", "vulkan", "metal"].includes(raw)) return raw;
return "auto";
}
function getSpeechBackend(preference = speechSettings.backendPreference) {
const candidates = getSpeechBackendCandidates().map((candidate) => ({
...candidate,
installed: Boolean(candidate.cli),
}));
const preferred = normalizeSpeechBackendPreference(preference);
const selected = preferred === "auto"
? candidates.find((candidate) => candidate.installed) || candidates[candidates.length - 1]
: candidates.find((candidate) => candidate.key === preferred) || candidates.find((candidate) => candidate.installed) || candidates[candidates.length - 1];
return {
cli: findExistingFile([SPEECH_BACKEND_PATHS.linuxCli, path.join(ROOT, "app", "speech-backend", "linux", "main")]),
server: findExistingFile([SPEECH_BACKEND_PATHS.linuxServer, path.join(ROOT, "app", "speech-backend", "linux", "server")]),
mode: "whisper.cpp CPU",
...(selected || { key: "cpu", label: "CPU", mode: "whisper.cpp CPU", cli: "", server: "" }),
preference: preferred,
candidates,
};
}
@@ -1846,7 +1921,7 @@ function runExclusiveTtsOperation(operation) {
async function startTts(settings = {}) {
const runtime = getTtsRuntimeStatus();
if (!runtime.installed) {
throw new Error("Kokoro TTS runtime is not installed. Run scripts/setup-tts for this platform.");
throw new Error("Kokoro TTS runtime is not installed. Run scripts/setup/setup-tts for this platform.");
}
const model = resolveTtsModel(settings.model || ttsSettings.model);
await killBackend();
@@ -2041,9 +2116,10 @@ function runExclusiveSpeechOperation(operation) {
}
async function startSpeech(settings = {}) {
const backend = getSpeechBackend();
const backendPreference = normalizeSpeechBackendPreference(settings.backendPreference || speechSettings.backendPreference);
const backend = getSpeechBackend(backendPreference);
if (!backend.cli) {
throw new Error("whisper.cpp is not installed. Run the platform setup script to install the speech backend.");
throw new Error(`${backend.label || "Selected"} whisper.cpp backend is not installed. Run setup or copy a compatible binary to ${backend.pathHint || "app/speech-backend"}.`);
}
const model = resolveSpeechModel(settings.model);
await killBackend();
@@ -2057,6 +2133,7 @@ async function startSpeech(settings = {}) {
model: model.filename,
language: settings.language || speechSettings.language || "auto",
threads: Math.max(1, Math.min(32, Number(settings.threads) || speechSettings.threads || 4)),
backendPreference,
backendBinary: path.basename(backend.cli),
backendMode: backend.mode,
};
@@ -2146,9 +2223,10 @@ function transcribeWavBuffer(buffer, options = {}) {
reject(new Error("Speech transcription currently accepts WAV audio only."));
return;
}
const backend = getSpeechBackend();
const backendPreference = normalizeSpeechBackendPreference(options.backendPreference || speechSettings.backendPreference);
const backend = getSpeechBackend(backendPreference);
if (!backend.cli) {
reject(new Error("whisper.cpp CLI backend is not installed."));
reject(new Error(`${backend.label || "Selected"} whisper.cpp CLI backend is not installed.`));
return;
}
const model = resolveSpeechModel(options.model || speechSettings.model);
@@ -2192,6 +2270,7 @@ function transcribeWavBuffer(buffer, options = {}) {
windowsHide: true,
env: {
...process.env,
...(osPlatform === "win32" ? { PATH: path.dirname(backend.cli) + (process.env.PATH ? `;${process.env.PATH}` : "") } : {}),
...(osPlatform === "linux" ? { LD_LIBRARY_PATH: path.dirname(backend.cli) + (process.env.LD_LIBRARY_PATH ? `:${process.env.LD_LIBRARY_PATH}` : "") } : {}),
...(osPlatform === "darwin" ? { DYLD_LIBRARY_PATH: path.dirname(backend.cli) + (process.env.DYLD_LIBRARY_PATH ? `:${process.env.DYLD_LIBRARY_PATH}` : "") } : {}),
},
@@ -2229,6 +2308,8 @@ function transcribeWavBuffer(buffer, options = {}) {
model: model.filename,
modelName: model.name,
language,
backend: backend.key,
backendMode: backend.mode,
sourceFilename,
durationMs: Date.now() - startedAt,
raw,
@@ -2656,7 +2737,7 @@ function getCoreMLNpuInfo() {
return {
supported: true,
ready: false,
reason: "CoreML Python environment is not set up. Run scripts/setup-coreml-npu.sh first.",
reason: "CoreML Python environment is not set up. Run scripts/setup/setup-coreml-npu.sh first.",
};
}
@@ -3307,7 +3388,7 @@ async function startOpenVinoWorker(settings = {}) {
device: currentSettings.backendDevice,
};
const workerPath = path.join(ROOT, "scripts", "openvino_npu_worker.py");
const workerPath = path.join(ROOT, "scripts", "workers", "openvino_npu_worker.py");
const cacheDir = path.join(ROOT, "app", "tools", "openvino-cache", "512x512");
console.log(` [openvino-npu] Starting 512x512 worker on port ${openvinoPort}`);
openvinoProc = spawn(npuInfo.python, [
@@ -5030,6 +5111,8 @@ const server = http.createServer(async (req, res) => {
backendPath: backend.cli || "",
serverPath: backend.server || "",
backendMode: backend.mode,
backendPreference: backend.preference,
backends: backend.candidates,
error: speechError,
settings: speechSettings,
transcription: speechTranscriptionState,
@@ -5066,6 +5149,7 @@ const server = http.createServer(async (req, res) => {
language: parsed.searchParams.get("language") || "auto",
filename: parsed.searchParams.get("filename") || req.headers["x-filename"] || "recording.wav",
threads: parsed.searchParams.get("threads") || speechSettings.threads,
backendPreference: parsed.searchParams.get("backendPreference") || speechSettings.backendPreference,
translate: parsed.searchParams.get("translate") === "true",
}));
return json(res, 200, { ok: true, transcription: result });
-64
View File
@@ -1,64 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
APP_DIR="$ROOT_DIR/app"
TOOLS_DIR="$APP_DIR/tools"
RELEASE="${WHISPER_RELEASE:-v1.9.1}"
PLATFORM="$(uname -s)"
ARCH="$(uname -m)"
download_and_extract() {
local asset="$1"
local dest="$2"
local archive="$TOOLS_DIR/$asset"
local url="https://github.com/ggml-org/whisper.cpp/releases/download/$RELEASE/$asset"
if [[ -x "$dest/whisper-cli" ]]; then
echo " OK whisper.cpp speech backend already ready: $dest"
return 0
fi
mkdir -p "$TOOLS_DIR" "$dest"
rm -f "$archive" "$archive.part"
echo " >> Downloading $asset"
curl -fSL --progress-bar "$url" -o "$archive.part"
mv "$archive.part" "$archive"
tar -xzf "$archive" -C "$dest" --strip-components=1
rm -f "$archive"
chmod +x "$dest"/whisper-* "$dest"/main "$dest"/server 2>/dev/null || true
if [[ ! -x "$dest/whisper-cli" && -x "$dest/main" ]]; then
cp "$dest/main" "$dest/whisper-cli"
chmod +x "$dest/whisper-cli"
fi
if [[ ! -x "$dest/whisper-server" && -x "$dest/server" ]]; then
cp "$dest/server" "$dest/whisper-server"
chmod +x "$dest/whisper-server"
fi
if [[ ! -x "$dest/whisper-cli" ]]; then
echo " XX whisper-cli was not found after extracting $asset" >&2
return 1
fi
}
if [[ "$PLATFORM" == "Linux" ]]; then
if [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then
download_and_extract "whisper-bin-ubuntu-arm64.tar.gz" "$APP_DIR/speech-backend/linux"
else
download_and_extract "whisper-bin-ubuntu-x64.tar.gz" "$APP_DIR/speech-backend/linux"
fi
elif [[ "$PLATFORM" == "Darwin" ]]; then
mkdir -p "$APP_DIR/speech-backend/mac"
if [[ -x "$APP_DIR/speech-backend/mac/whisper-cli" ]]; then
echo " OK whisper.cpp macOS speech backend already ready."
else
echo " !! No official portable macOS whisper.cpp CLI archive is available for this setup script yet."
echo " Build whisper.cpp manually and copy whisper-cli to app/speech-backend/mac/whisper-cli."
fi
else
echo "Unsupported platform: $PLATFORM" >&2
exit 1
fi
+1 -1
View File
@@ -7,7 +7,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
VENV_DIR="$ROOT_DIR/app/backend/mac/coreml_venv"
PYTHON_BIN="$VENV_DIR/bin/python"
@@ -2,7 +2,7 @@ param([string]$Release = "b9668")
$ErrorActionPreference = "Stop"
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$rootDir = Split-Path -Parent $scriptDir
$rootDir = Split-Path -Parent (Split-Path -Parent $scriptDir)
$appDir = Join-Path $rootDir "app"
$toolsDir = Join-Path $appDir "tools"
$llmRoot = Join-Path $appDir "llm-backend\win"
@@ -2,7 +2,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
APP_DIR="$ROOT_DIR/app"
TOOLS_DIR="$APP_DIR/tools"
RELEASE="${LLAMA_RELEASE:-b9668}"
@@ -4,7 +4,7 @@
$ErrorActionPreference = "Stop"
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$rootDir = Split-Path -Parent $scriptDir
$rootDir = Split-Path -Parent (Split-Path -Parent $scriptDir)
$venvDir = Join-Path $rootDir "app\tools\openvino-venv-win"
$pythonExe = Join-Path $venvDir "Scripts\python.exe"
@@ -6,7 +6,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
VENV_DIR="$ROOT_DIR/app/tools/openvino-venv-linux"
PYTHON_BIN="$VENV_DIR/bin/python"
@@ -1,7 +1,7 @@
# Local AI Studio - Kokoro TTS setup for Windows
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$rootDir = Split-Path -Parent $scriptDir
$rootDir = Split-Path -Parent (Split-Path -Parent $scriptDir)
$appDir = Join-Path $rootDir "app"
$toolsDir = Join-Path $appDir "tools"
$nodeDir = Join-Path $toolsDir "node-win"
@@ -25,7 +25,7 @@ Write-Host ""
New-Item -ItemType Directory -Force -Path $runtimeDir, $modelsDir, $outputsDir, $cacheDir | Out-Null
if (-not (Test-Path $nodeExe) -or -not (Test-Path $npmCmd)) {
Print-Fail "Portable Node.js is missing. Run scripts/setup.ps1 first."
Print-Fail "Portable Node.js is missing. Run scripts/setup/setup.ps1 first."
exit 1
}
@@ -6,7 +6,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
APP_DIR="$ROOT_DIR/app"
TOOLS_DIR="$APP_DIR/tools"
PLATFORM="$(uname -s)"
@@ -37,7 +37,7 @@ echo ""
mkdir -p "$RUNTIME_DIR" "$MODELS_DIR" "$OUTPUTS_DIR" "$CACHE_DIR"
if [[ ! -x "$NODE_BIN" || ! -x "$NPM_BIN" ]]; then
print_fail "Portable Node.js is missing. Run scripts/setup.sh first."
print_fail "Portable Node.js is missing. Run scripts/setup/setup.sh first."
exit 1
fi
@@ -2,10 +2,12 @@ param([string]$Release = "v1.9.1")
$ErrorActionPreference = "Stop"
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$rootDir = Split-Path -Parent $scriptDir
$rootDir = Split-Path -Parent (Split-Path -Parent $scriptDir)
$appDir = Join-Path $rootDir "app"
$toolsDir = Join-Path $appDir "tools"
$speechRoot = Join-Path $appDir "speech-backend\win"
$speechWinRoot = Join-Path $appDir "speech-backend\win"
$speechRoot = Join-Path $speechWinRoot "cpu"
$speechVulkanRoot = Join-Path $speechWinRoot "vulkan"
function Enable-Tls12 {
try {
@@ -41,11 +43,29 @@ function Find-FirstFile {
return $null
}
New-Item -ItemType Directory -Force -Path $toolsDir, $speechRoot | Out-Null
New-Item -ItemType Directory -Force -Path $toolsDir, $speechRoot, $speechVulkanRoot | Out-Null
$cliPath = Join-Path $speechRoot "whisper-cli.exe"
if (Test-Path $cliPath) {
Write-Host " OK whisper.cpp speech backend already ready."
if (-not (Test-Path (Join-Path $speechVulkanRoot "whisper-cli.exe"))) {
Write-Host " .. Optional Vulkan GPU backend slot: app/speech-backend/win/vulkan"
}
exit 0
}
$legacyCli = Join-Path $speechWinRoot "whisper-cli.exe"
$legacyServer = Join-Path $speechWinRoot "whisper-server.exe"
if (Test-Path $legacyCli) {
Copy-Item $legacyCli $cliPath -Force
if (Test-Path $legacyServer) {
Copy-Item $legacyServer (Join-Path $speechRoot "whisper-server.exe") -Force
}
Get-ChildItem $speechWinRoot -File -ErrorAction SilentlyContinue |
Where-Object { $_.Name -notin @("whisper-cli.exe", "whisper-server.exe") } |
ForEach-Object { Copy-Item $_.FullName (Join-Path $speechRoot $_.Name) -Force }
Write-Host " OK migrated existing whisper.cpp CPU backend to app/speech-backend/win/cpu."
Write-Host " .. For GPU transcription, place a Vulkan-enabled whisper.cpp build in app/speech-backend/win/vulkan."
exit 0
}
@@ -81,3 +101,5 @@ if (-not (Test-Path $cliPath)) {
throw "whisper-cli.exe was not installed."
}
Write-Host " OK whisper.cpp speech backend installed."
Write-Host " .. CPU backend path: app/speech-backend/win/cpu"
Write-Host " .. Optional Vulkan GPU backend path: app/speech-backend/win/vulkan"
+81
View File
@@ -0,0 +1,81 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
APP_DIR="$ROOT_DIR/app"
TOOLS_DIR="$APP_DIR/tools"
RELEASE="${WHISPER_RELEASE:-v1.9.1}"
PLATFORM="$(uname -s)"
ARCH="$(uname -m)"
download_and_extract() {
local asset="$1"
local dest="$2"
local archive="$TOOLS_DIR/$asset"
local url="https://github.com/ggml-org/whisper.cpp/releases/download/$RELEASE/$asset"
if [[ -x "$dest/whisper-cli" ]]; then
echo " OK whisper.cpp speech backend already ready: $dest"
return 0
fi
mkdir -p "$TOOLS_DIR" "$dest"
rm -f "$archive" "$archive.part"
echo " >> Downloading $asset"
curl -fSL --progress-bar "$url" -o "$archive.part"
mv "$archive.part" "$archive"
tar -xzf "$archive" -C "$dest" --strip-components=1
rm -f "$archive"
chmod +x "$dest"/whisper-* "$dest"/main "$dest"/server 2>/dev/null || true
if [[ ! -x "$dest/whisper-cli" && -x "$dest/main" ]]; then
cp "$dest/main" "$dest/whisper-cli"
chmod +x "$dest/whisper-cli"
fi
if [[ ! -x "$dest/whisper-server" && -x "$dest/server" ]]; then
cp "$dest/server" "$dest/whisper-server"
chmod +x "$dest/whisper-server"
fi
if [[ ! -x "$dest/whisper-cli" ]]; then
echo " XX whisper-cli was not found after extracting $asset" >&2
return 1
fi
}
if [[ "$PLATFORM" == "Linux" ]]; then
mkdir -p "$APP_DIR/speech-backend/linux/cpu" "$APP_DIR/speech-backend/linux/vulkan"
if [[ ! -x "$APP_DIR/speech-backend/linux/cpu/whisper-cli" && -x "$APP_DIR/speech-backend/linux/whisper-cli" ]]; then
cp "$APP_DIR/speech-backend/linux"/whisper-* "$APP_DIR/speech-backend/linux/cpu/" 2>/dev/null || true
cp "$APP_DIR/speech-backend/linux"/main "$APP_DIR/speech-backend/linux/cpu/" 2>/dev/null || true
cp "$APP_DIR/speech-backend/linux"/server "$APP_DIR/speech-backend/linux/cpu/" 2>/dev/null || true
chmod +x "$APP_DIR/speech-backend/linux/cpu"/whisper-* "$APP_DIR/speech-backend/linux/cpu"/main "$APP_DIR/speech-backend/linux/cpu"/server 2>/dev/null || true
echo " OK migrated existing whisper.cpp CPU backend to app/speech-backend/linux/cpu."
fi
if [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then
download_and_extract "whisper-bin-ubuntu-arm64.tar.gz" "$APP_DIR/speech-backend/linux/cpu"
else
download_and_extract "whisper-bin-ubuntu-x64.tar.gz" "$APP_DIR/speech-backend/linux/cpu"
fi
echo " .. CPU backend path: app/speech-backend/linux/cpu"
echo " .. Optional Vulkan GPU backend path: app/speech-backend/linux/vulkan"
elif [[ "$PLATFORM" == "Darwin" ]]; then
mkdir -p "$APP_DIR/speech-backend/mac/cpu" "$APP_DIR/speech-backend/mac/metal"
if [[ ! -x "$APP_DIR/speech-backend/mac/cpu/whisper-cli" && -x "$APP_DIR/speech-backend/mac/whisper-cli" ]]; then
cp "$APP_DIR/speech-backend/mac"/whisper-* "$APP_DIR/speech-backend/mac/cpu/" 2>/dev/null || true
cp "$APP_DIR/speech-backend/mac"/main "$APP_DIR/speech-backend/mac/cpu/" 2>/dev/null || true
cp "$APP_DIR/speech-backend/mac"/server "$APP_DIR/speech-backend/mac/cpu/" 2>/dev/null || true
chmod +x "$APP_DIR/speech-backend/mac/cpu"/whisper-* "$APP_DIR/speech-backend/mac/cpu"/main "$APP_DIR/speech-backend/mac/cpu"/server 2>/dev/null || true
echo " OK migrated existing whisper.cpp backend to app/speech-backend/mac/cpu."
fi
if [[ -x "$APP_DIR/speech-backend/mac/cpu/whisper-cli" || -x "$APP_DIR/speech-backend/mac/metal/whisper-cli" ]]; then
echo " OK whisper.cpp macOS speech backend already ready."
else
echo " !! No official portable macOS whisper.cpp CLI archive is available for this setup script yet."
echo " Build whisper.cpp manually and copy whisper-cli to app/speech-backend/mac/cpu or app/speech-backend/mac/metal."
fi
else
echo "Unsupported platform: $PLATFORM" >&2
exit 1
fi
@@ -1,8 +1,8 @@
# Local AI Image Generator - Setup Script
# scripts/ lives at root, app/ is a sibling folder
# scripts/setup/ lives under root, app/ is a root sibling of scripts/
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$rootDir = Split-Path -Parent $scriptDir
$rootDir = Split-Path -Parent (Split-Path -Parent $scriptDir)
$appDir = Join-Path $rootDir "app"
$frontendDir = Join-Path $appDir "frontend"
$toolsDir = Join-Path $appDir "tools"
+2 -2
View File
@@ -7,7 +7,7 @@
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
ROOT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
APP_DIR="$ROOT_DIR/app"
FRONTEND_DIR="$APP_DIR/frontend"
TOOLS_DIR="$APP_DIR/tools"
@@ -680,6 +680,6 @@ echo ""
if [[ "$PLATFORM" == "Linux" && $MAX_PERF -eq 0 ]] && [[ "$VENDOR" == "nvidia" || "$VENDOR" == "amd" ]]; then
echo " Tip: For maximum GPU performance, re-run with:"
echo " ./scripts/setup.sh --max-perf"
echo " ./scripts/setup/setup.sh --max-perf"
echo ""
fi
File renamed without changes.
File renamed without changes.