@tritard/waterbrother 0.14.16 → 0.14.18
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/cli.js +4 -2
- package/src/voice.js +15 -6
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -4140,6 +4140,8 @@ async function runTextTurnInteractive({
|
|
|
4140
4140
|
context.voiceSession.speakFull(renderedAssistantText, {
|
|
4141
4141
|
apiKey: context.runtime.apiKey,
|
|
4142
4142
|
baseUrl: context.runtime.baseUrl,
|
|
4143
|
+
}).catch((err) => {
|
|
4144
|
+
console.log(`[speak] TTS failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4143
4145
|
});
|
|
4144
4146
|
}
|
|
4145
4147
|
|
|
@@ -4447,7 +4449,7 @@ function normalizeInteractiveInput(line) {
|
|
|
4447
4449
|
function summarizePromptInput(inputText, maxWidth) {
|
|
4448
4450
|
const raw = String(inputText || "");
|
|
4449
4451
|
const lines = raw.split("\n");
|
|
4450
|
-
const singleLine = raw.replace(/\s+/g, " ").
|
|
4452
|
+
const singleLine = raw.replace(/\s+/g, " ").trimStart();
|
|
4451
4453
|
if (lines.length <= 1) {
|
|
4452
4454
|
return truncateTail(singleLine, maxWidth);
|
|
4453
4455
|
}
|
|
@@ -6449,7 +6451,7 @@ Be concrete about surfaces — name actual pages/flows. Choose the best stack fo
|
|
|
6449
6451
|
if (line === "/close") {
|
|
6450
6452
|
const task = context.runtime.activeTask || await getActiveTask({ cwd: context.cwd });
|
|
6451
6453
|
if (!task) { console.log("no active task to close"); continue; }
|
|
6452
|
-
if (task.state === "review-ready" && !task.accepted) {
|
|
6454
|
+
if (task.state === "review-ready" && !task.accepted && !task._closeWarned) {
|
|
6453
6455
|
console.log(`warning: task "${task.name}" has unaccepted changes (state=${task.state})`);
|
|
6454
6456
|
console.log("use /accept first, or /close again to force close");
|
|
6455
6457
|
task._closeWarned = true;
|
package/src/voice.js
CHANGED
|
@@ -657,8 +657,9 @@ export async function setupVoice(onStatus) {
|
|
|
657
657
|
// Speak full text via xAI TTS API. Streams MP3 to temp file, plays via sox.
|
|
658
658
|
// Can be cancelled via stopSpeaking(). Requires grokConfig with apiKey.
|
|
659
659
|
async speakFull(text, { apiKey, baseUrl } = {}) {
|
|
660
|
-
if (!text || !apiKey) return;
|
|
660
|
+
if (!text || !apiKey) { process.stderr.write(`[speak] skipped: text=${!!text} apiKey=${!!apiKey}\n`); return; }
|
|
661
661
|
_ttsCancelled = false;
|
|
662
|
+
process.stderr.write(`[speak] starting TTS for ${text.length} chars\n`);
|
|
662
663
|
|
|
663
664
|
// Strip ANSI, markdown, code blocks, emojis
|
|
664
665
|
let clean = text.replace(/\x1b\[[0-9;]*m/g, "").replace(/```[\s\S]*?```/g, "").replace(/`[^`]+`/g, "");
|
|
@@ -683,7 +684,11 @@ export async function setupVoice(onStatus) {
|
|
|
683
684
|
}),
|
|
684
685
|
});
|
|
685
686
|
|
|
686
|
-
if (!response.ok)
|
|
687
|
+
if (!response.ok) {
|
|
688
|
+
const body = await response.text().catch(() => "");
|
|
689
|
+
process.stderr.write(`[speak] xAI TTS error: HTTP ${response.status} ${body.slice(0, 100)}\n`);
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
687
692
|
if (_ttsCancelled) return;
|
|
688
693
|
|
|
689
694
|
const audioBuffer = Buffer.from(await response.arrayBuffer());
|
|
@@ -726,15 +731,19 @@ export async function setupVoice(onStatus) {
|
|
|
726
731
|
await new Promise((resolve) => {
|
|
727
732
|
const child = spawn(playCmd, playArgs, { stdio: "ignore" });
|
|
728
733
|
_ttsPlayback = child;
|
|
729
|
-
child.on("exit", () => {
|
|
734
|
+
child.on("exit", (code) => {
|
|
730
735
|
if (_ttsPlayback === child) _ttsPlayback = null;
|
|
736
|
+
if (code !== 0) process.stderr.write(`[speak] playback exited with code ${code}\n`);
|
|
731
737
|
for (const f of cleanupFiles) fs.unlink(f).catch(() => {});
|
|
732
738
|
resolve();
|
|
733
739
|
});
|
|
734
|
-
child.on("error", () => {
|
|
740
|
+
child.on("error", (err) => {
|
|
741
|
+
process.stderr.write(`[speak] playback error: ${err.message}\n`);
|
|
742
|
+
resolve();
|
|
743
|
+
});
|
|
735
744
|
});
|
|
736
|
-
} catch {
|
|
737
|
-
|
|
745
|
+
} catch (err) {
|
|
746
|
+
process.stderr.write(`[speak] TTS failed: ${err.message}\n`);
|
|
738
747
|
}
|
|
739
748
|
_ttsCancelled = false;
|
|
740
749
|
},
|