@chatpanel/gateway 0.6.93 → 0.6.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/pocket-tts-engine.js +8 -0
- package/src/server.js +8 -3
- package/src/service.js +17 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatpanel/gateway",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.95",
|
|
4
4
|
"description": "Local privacy gateway — redacts PII out of OpenAI/Anthropic API traffic before it reaches a model, then restores it in the reply. Point opencode, codex, aider, Claude Code, etc. at it.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/pocket-tts-engine.js
CHANGED
|
@@ -275,6 +275,14 @@ export class PocketTTS {
|
|
|
275
275
|
|
|
276
276
|
async load(bundle = DEFAULT_BUNDLE, { quant = '_int8', onProgress, log = () => {} } = {}) {
|
|
277
277
|
const dir = await ensureBundle(bundle, quant, { onProgress, log });
|
|
278
|
+
// The built-in speakers come WITH the model. `ensureVoicesBin` existed and nothing called
|
|
279
|
+
// it: the eight names were listed as "downloads on first use", the default voice was one
|
|
280
|
+
// of them, and picking any of them failed with "unknown built-in voice" on every machine
|
|
281
|
+
// but the one where the file had been fetched by hand. Best-effort — a failed download
|
|
282
|
+
// costs the stock voices and leaves cloning untouched.
|
|
283
|
+
if (!voicesBinOnDisk(bundle)) {
|
|
284
|
+
try { await ensureVoicesBin(bundle, { onProgress, log }); } catch (e) { log(`[pocket-tts] built-in voices not downloaded (${e.message}) — cloning still works`); }
|
|
285
|
+
}
|
|
278
286
|
const ort = await getOrt();
|
|
279
287
|
this.meta = JSON.parse(readFileSync(join(dir, 'bundle.json'), 'utf8'));
|
|
280
288
|
this.tok = new SentencePieceUnigram(new Uint8Array(readFileSync(join(dir, 'tokenizer.model'))));
|
package/src/server.js
CHANGED
|
@@ -63,7 +63,7 @@ import * as openai from './openai.js';
|
|
|
63
63
|
import * as responses from './responses.js';
|
|
64
64
|
import * as anthropic from './anthropic.js';
|
|
65
65
|
|
|
66
|
-
export const VERSION = '0.6.
|
|
66
|
+
export const VERSION = '0.6.95';
|
|
67
67
|
|
|
68
68
|
// WARM search tier — SQLite + FTS5 record store (falls back to an encrypted-JSON
|
|
69
69
|
// store if SQLite can't load), fed by the extension's ingest sync + backup-ingest.
|
|
@@ -1502,6 +1502,7 @@ export function createGateway(cfg = loadConfig()) {
|
|
|
1502
1502
|
// A model needing the native runtime is still LISTED on the binary, with the
|
|
1503
1503
|
// reason — hiding it makes "why can't I clone my voice?" unanswerable.
|
|
1504
1504
|
const nativeOk = rawOrtAvailable();
|
|
1505
|
+
const activeEntry = TTS_MODEL_CATALOG.find((m) => m.id === active) || null;
|
|
1505
1506
|
const available = /** @type {any[]} */ (TTS_MODEL_CATALOG.map((m) => ({
|
|
1506
1507
|
...m,
|
|
1507
1508
|
installed: ttsEngine.modelOnDisk(m.id),
|
|
@@ -1524,8 +1525,12 @@ export function createGateway(cfg = loadConfig()) {
|
|
|
1524
1525
|
// a style bank, VITS/MMS is single-speaker. An empty list tells the UI to
|
|
1525
1526
|
// hide the picker rather than offer choices that cannot take effect.
|
|
1526
1527
|
arch: ttsEngine.arch(),
|
|
1527
|
-
|
|
1528
|
-
|
|
1528
|
+
// Until a model is LOADED the engine knows nothing, and answering "no voices"
|
|
1529
|
+
// for a model that has eight made the client hide its picker on every fresh
|
|
1530
|
+
// install (state 'off' → supportsVoices false → the single-speaker branch). Before
|
|
1531
|
+
// the first load, the catalog answers for the active model.
|
|
1532
|
+
supportsVoices: ttsEngine.arch() ? ttsEngine.supportsVoices() : (activeEntry ? activeEntry.arch === 'style-tts2' && !!activeEntry.voices : true),
|
|
1533
|
+
supportsCustomVoices: ttsEngine.arch() ? ttsEngine.supportsCustomVoices() : !!activeEntry?.customVoices,
|
|
1529
1534
|
sampleRate: ttsEngine.sampleRate(),
|
|
1530
1535
|
// Built-in voices belong to Kokoro alone. VITS is single-speaker and
|
|
1531
1536
|
// SpeechT5 speaks only in a RECORDED voice, so offering Kokoro's list
|
package/src/service.js
CHANGED
|
@@ -81,6 +81,19 @@ const WIN_RUN_KEY = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run';
|
|
|
81
81
|
const WIN_RUN_NAME = 'ChatPanelGateway';
|
|
82
82
|
const winVbs = () => path.join(os.homedir(), '.chatpanel', 'gateway-launch.vbs');
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Stop every running gateway process — the exe, the npm build under node, and the embedded
|
|
86
|
+
* bridge child (`--bridge`) — except this one. Matched on the command line, because on the
|
|
87
|
+
* npm path the process is `node.exe` and `taskkill /IM chatpanel-gateway.exe` never saw it.
|
|
88
|
+
* launchd restarts the macOS service for us; Windows has no supervisor, so `--install` after an
|
|
89
|
+
* update used to launch a second instance that died on the busy port while the OLD build kept
|
|
90
|
+
* answering /health with its old version.
|
|
91
|
+
*/
|
|
92
|
+
function winStopRunning() {
|
|
93
|
+
const ps = `Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -match 'chatpanel-gateway' -and $_.ProcessId -ne ${process.pid} } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }`;
|
|
94
|
+
run('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', ps], { timeout: 15000 });
|
|
95
|
+
run('taskkill', ['/IM', 'chatpanel-gateway.exe', '/F']); // belt and braces for the exe
|
|
96
|
+
}
|
|
84
97
|
function winInstall() {
|
|
85
98
|
const { program, args } = resolveLaunch();
|
|
86
99
|
const parts = [program, ...args].map((p) => `""${p}""`).join(' ');
|
|
@@ -89,11 +102,14 @@ function winInstall() {
|
|
|
89
102
|
writeFileSync(vbs, `CreateObject("WScript.Shell").Run "${parts}", 0, False\r\n`);
|
|
90
103
|
const r = run('reg', ['add', WIN_RUN_KEY, '/v', WIN_RUN_NAME, '/t', 'REG_SZ', '/d', `wscript.exe "${vbs}"`, '/f']);
|
|
91
104
|
if (r.status !== 0) throw new Error((r.stderr || '').trim() || 'reg add failed');
|
|
105
|
+
winStopRunning();
|
|
106
|
+
// Give the port a moment to be released before the new instance binds it.
|
|
107
|
+
run('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', 'Start-Sleep -Milliseconds 800']);
|
|
92
108
|
run('wscript.exe', [vbs]);
|
|
93
109
|
}
|
|
94
110
|
function winUninstall() {
|
|
95
111
|
run('reg', ['delete', WIN_RUN_KEY, '/v', WIN_RUN_NAME, '/f']);
|
|
96
|
-
|
|
112
|
+
winStopRunning();
|
|
97
113
|
}
|
|
98
114
|
function winStatus() {
|
|
99
115
|
return run('reg', ['query', WIN_RUN_KEY, '/v', WIN_RUN_NAME]).status === 0;
|