Fix dev runner entry and sherpa TTS initialization

This commit is contained in:
Mohamed Boudra
2026-02-12 14:05:46 +07:00
parent bb93fc2a61
commit 3319c2d40c
3 changed files with 35 additions and 43 deletions
@@ -687,7 +687,7 @@ const styles = StyleSheet.create((theme) => ({
marginBottom: theme.spacing[1], marginBottom: theme.spacing[1],
}, },
agentItemUnselected: { agentItemUnselected: {
opacity: 0.75, opacity: 1,
}, },
agentItemSelected: { agentItemSelected: {
backgroundColor: theme.colors.surface2, backgroundColor: theme.colors.surface2,
+6 -22
View File
@@ -2,35 +2,19 @@ import { fileURLToPath } from "url";
import { existsSync } from "node:fs"; import { existsSync } from "node:fs";
import { runSupervisor } from "./supervisor.js"; import { runSupervisor } from "./supervisor.js";
function resolveWorkerEntry(): string { const WORKER_ENTRY = fileURLToPath(new URL("../src/server/index.ts", import.meta.url));
const candidates = [ if (!existsSync(WORKER_ENTRY)) {
fileURLToPath(new URL("../server/server/index.js", import.meta.url)), throw new Error(`Dev worker entry not found: ${WORKER_ENTRY}`);
fileURLToPath(new URL("../dist/server/server/index.js", import.meta.url)),
fileURLToPath(new URL("../src/server/index.ts", import.meta.url)),
fileURLToPath(new URL("../../src/server/index.ts", import.meta.url)),
];
for (const candidate of candidates) {
if (existsSync(candidate)) {
return candidate;
}
}
return candidates[0];
}
function resolveWorkerExecArgv(): string[] {
const workerEntry = resolveWorkerEntry();
return workerEntry.endsWith(".ts") ? ["--import", "tsx"] : [];
} }
runSupervisor({ runSupervisor({
name: "DevRunner", name: "DevRunner",
startupMessage: "Starting server worker (crash restarts enabled)", startupMessage: "Starting server worker (crash restarts enabled)",
resolveWorkerEntry, resolveWorkerEntry: () => WORKER_ENTRY,
workerArgs: process.argv.slice(2), workerArgs: process.argv.slice(2),
workerEnv: process.env, workerEnv: process.env,
workerExecArgv: resolveWorkerExecArgv(), // Always run worker with tsx so dev server uses TypeScript sources directly.
workerExecArgv: ["--import", "tsx"],
restartOnCrash: true, restartOnCrash: true,
shutdownReasons: ["cli_shutdown"], shutdownReasons: ["cli_shutdown"],
}); });
@@ -4,7 +4,7 @@ import { existsSync } from "node:fs";
import type { SpeechStreamResult, TextToSpeechProvider } from "../../../speech-provider.js"; import type { SpeechStreamResult, TextToSpeechProvider } from "../../../speech-provider.js";
import { chunkBuffer, float32ToPcm16le } from "../../../audio.js"; import { chunkBuffer, float32ToPcm16le } from "../../../audio.js";
import { loadSherpaOnnx } from "./sherpa-onnx-loader.js"; import { loadSherpaOnnxNode } from "./sherpa-onnx-node-loader.js";
export type SherpaTtsPreset = "kokoro-en-v0_19" | "kitten-nano-en-v0_1-fp16"; export type SherpaTtsPreset = "kokoro-en-v0_19" | "kitten-nano-en-v0_1-fp16";
@@ -37,7 +37,10 @@ export class SherpaOnnxTTS implements TextToSpeechProvider {
this.speakerId = config.speakerId ?? 0; this.speakerId = config.speakerId ?? 0;
this.speed = config.speed ?? 1.0; this.speed = config.speed ?? 1.0;
const sherpa = loadSherpaOnnx(); const sherpa = loadSherpaOnnxNode();
if (typeof sherpa.OfflineTts !== "function") {
throw new Error("sherpa-onnx-node OfflineTts is unavailable");
}
const modelFile = config.preset === "kokoro-en-v0_19" ? "model.onnx" : "model.fp16.onnx"; const modelFile = config.preset === "kokoro-en-v0_19" ? "model.onnx" : "model.fp16.onnx";
const modelPath = `${config.modelDir}/${modelFile}`; const modelPath = `${config.modelDir}/${modelFile}`;
@@ -50,30 +53,35 @@ export class SherpaOnnxTTS implements TextToSpeechProvider {
assertFileExists(tokensPath, "TTS tokens"); assertFileExists(tokensPath, "TTS tokens");
assertFileExists(dataDir, "TTS espeak-ng dataDir"); assertFileExists(dataDir, "TTS espeak-ng dataDir");
const modelConfigKey = const modelConfig =
config.preset === "kokoro-en-v0_19" config.preset === "kokoro-en-v0_19"
? "offlineTtsKokoroModelConfig" ? {
: "offlineTtsKittenModelConfig"; kokoro: {
model: modelPath,
const modelConfig = { voices: voicesPath,
[modelConfigKey]: { tokens: tokensPath,
model: modelPath, dataDir,
voices: voicesPath, lengthScale: config.lengthScale ?? 1.0,
tokens: tokensPath, },
dataDir, }
lengthScale: config.lengthScale ?? 1.0, : {
}, kitten: {
numThreads: config.numThreads ?? 2, model: modelPath,
debug: 0, voices: voicesPath,
provider: "cpu", tokens: tokensPath,
}; dataDir,
lengthScale: config.lengthScale ?? 1.0,
},
};
const offlineTtsConfig = { const offlineTtsConfig = {
offlineTtsModelConfig: modelConfig, model: modelConfig,
numThreads: config.numThreads ?? 2,
provider: "cpu",
maxNumSentences: 1, maxNumSentences: 1,
}; };
this.tts = sherpa.createOfflineTts(offlineTtsConfig); this.tts = new sherpa.OfflineTts(offlineTtsConfig);
this.logger.info({ preset: config.preset, modelDir: config.modelDir }, "Sherpa offline TTS initialized"); this.logger.info({ preset: config.preset, modelDir: config.modelDir }, "Sherpa offline TTS initialized");
} }