fix(voice): 思考看门狗覆盖 PTT 模式(别永远卡在"思考中")

此前 armThinkTimer 只在连续对话模式挂,PTT 下后端不回(dispatcher 未就绪/
模型没配/任务失败)就永远卡在"思考中",用户干等且毫无线索。

改:任何模式收到 final 转写都挂看门狗;超时后连续对话回聆听、PTT 回待命,
并明确提示可能原因 + 引导去运行页看任务状态。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-07-25 14:57:18 +08:00
parent e60679ed7b
commit c66d178efe
+7 -2
View File
@@ -147,7 +147,7 @@ export class VoiceClient {
if (m.final) { if (m.final) {
this.clearIdleTimer(); this.clearIdleTimer();
this.setState("thinking"); this.setState("thinking");
if (this.conversation) this.armThinkTimer(); // 看门狗任务失败/无 TTS 也能回到聆听 this.armThinkTimer(); // 看门狗:后端不回/任务失败/无 TTS 时别永远卡在"思考中"
} else if (this.conversation && this.state === "listening") { } else if (this.conversation && this.state === "listening") {
this.armIdleTimer(); // 有声音活动 → 空转计时重来 this.armIdleTimer(); // 有声音活动 → 空转计时重来
} }
@@ -341,12 +341,17 @@ export class VoiceClient {
this.clearThinkTimer(); this.clearThinkTimer();
this.thinkTimer = window.setTimeout(() => { this.thinkTimer = window.setTimeout(() => {
this.thinkTimer = null; this.thinkTimer = null;
if (this.conversation && this.state === "thinking") { if (this.state !== "thinking") return;
if (this.conversation) {
this.cb.onError?.("等回答超时,继续聆听"); this.cb.onError?.("等回答超时,继续聆听");
this.send({ type: "start" }); this.send({ type: "start" });
this.cb.onTurnStart?.(); this.cb.onTurnStart?.();
this.setState("listening"); this.setState("listening");
this.armIdleTimer(); this.armIdleTimer();
} else {
// PTT:回待命并说清可能原因,别让用户对着"思考中"干等。
this.cb.onError?.("等了很久没有回答——可能后端任务没跑起来(dispatcher/模型未就绪)。去运行页看看这条任务的状态。");
this.setState("ready");
} }
}, THINK_WATCHDOG_MS); }, THINK_WATCHDOG_MS);
} }