From 4c17379ad45a7dca6bc8cfc9e2d04097f910e251 Mon Sep 17 00:00:00 2001 From: Dorian Date: Mon, 9 Mar 2026 10:18:03 +0000 Subject: [PATCH] fix: harden TTS with 2s await timeout and 4s worker timeout for reliable fallback Reduces worker generation timeout from 10s to 4s and adds 2s race on awaitReady so slow Kokoro generation falls back to Web Speech API quickly instead of stalling the fight. Co-Authored-By: Claude Opus 4.6 --- frontend/src/game/tts.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/frontend/src/game/tts.ts b/frontend/src/game/tts.ts index 4e9f18b..1c8670a 100644 --- a/frontend/src/game/tts.ts +++ b/frontend/src/game/tts.ts @@ -252,7 +252,7 @@ function _workerGenerate(text: string, voice: string, speed: number): Promise<{ const timeout = setTimeout(() => { _pending.delete(id) reject(new Error('TTS generation timed out')) - }, 10_000) + }, 4_000) _pending.set(id, { resolve: (v) => { clearTimeout(timeout); resolve(v) }, reject: (e) => { clearTimeout(timeout); reject(e) }, @@ -376,12 +376,15 @@ export function kokoroPrefetch(text: string, profileName: string): void { _generateAndCache(text, profileName).catch(() => {}) } -/** Await until prefetched audio is cached and ready. Returns true if cached, false on failure. */ +/** Await until prefetched audio is cached and ready (max 2s). Returns true if cached, false on timeout/failure. */ export async function kokoroAwaitReady(text: string, profileName: string): Promise { if (!_workerReady) return false try { - const buf = await _generateAndCache(text, profileName) - return !!buf + const result = await Promise.race([ + _generateAndCache(text, profileName), + new Promise(r => setTimeout(() => r(null), 2000)), + ]) + return !!result } catch { return false } }