@tritard/waterbrother 0.14.17 → 0.14.19
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 +2 -0
- package/src/voice.js +6 -2
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
|
|
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, "");
|
|
@@ -670,6 +671,7 @@ export async function setupVoice(onStatus) {
|
|
|
670
671
|
if (!fullText.trim()) return;
|
|
671
672
|
|
|
672
673
|
try {
|
|
674
|
+
process.stderr.write(`[speak] fetching ${XAI_TTS_URL} (${fullText.length} chars)\n`);
|
|
673
675
|
const response = await fetch(XAI_TTS_URL, {
|
|
674
676
|
method: "POST",
|
|
675
677
|
headers: {
|
|
@@ -682,15 +684,17 @@ export async function setupVoice(onStatus) {
|
|
|
682
684
|
language: "en",
|
|
683
685
|
}),
|
|
684
686
|
});
|
|
687
|
+
process.stderr.write(`[speak] response: ${response.status} ${response.statusText}\n`);
|
|
685
688
|
|
|
686
689
|
if (!response.ok) {
|
|
687
690
|
const body = await response.text().catch(() => "");
|
|
688
|
-
process.stderr.write(`[speak] xAI TTS error: HTTP ${response.status} ${body.slice(0,
|
|
691
|
+
process.stderr.write(`[speak] xAI TTS error: HTTP ${response.status} ${body.slice(0, 200)}\n`);
|
|
689
692
|
return;
|
|
690
693
|
}
|
|
691
694
|
if (_ttsCancelled) return;
|
|
692
695
|
|
|
693
696
|
const audioBuffer = Buffer.from(await response.arrayBuffer());
|
|
697
|
+
process.stderr.write(`[speak] audio: ${audioBuffer.length} bytes\n`);
|
|
694
698
|
if (_ttsCancelled || !audioBuffer.length) return;
|
|
695
699
|
|
|
696
700
|
const tmpDir = path.join(getWaterbrotherHome(), "tmp");
|