"use client"; /** * useStreamingVoice — KI-168 (2026-05-15). * * Replaces the custom AudioWorklet + VAD + WAV-encode + /api/transcribe path * (useLiveConversation) with the browser's native Web Speech API. The user * sees their words land in the chat input area in real time as they speak, * just like ChatGPT / Claude voice mode — and when the browser detects * end-of-utterance silence, the final transcript is auto-submitted through * the existing send() path. * * Why this exists * ------------------------------------------------------------------------- * The previous live-mode stack accumulated 12+ KIs of failure modes * (KI-044/057/060/064/113/114/115/131/134/139/141/159/165) trying to bolt * a reliable VAD onto raw mic PCM. Every fix surfaced a new failure on a * different mic / room / browser combo. The native SpeechRecognition API * gives us: * - browser-grade end-of-speech detection (no rmsThreshold tuning) * - streaming interim transcripts (no "where did my words go?" gap) * - in-browser STT (no /api/transcribe round-trip latency) * * Behaviour * ------------------------------------------------------------------------- * - `enabled = true` → recognition.start() runs, mic icon stays live, * interim transcript streams into the chat input via onInterimTranscript. * - Browser detects ~1.5s silence → onend fires → we hand the final * transcript to onFinalTranscript (caller calls send()). * - After onend, if `enabled` is still true and no text request is in * flight, we restart recognition so the mic stays live (continuous-mode * emulation; native `continuous=true` doesn't fire silence-end on most * browsers, so we use continuous=false + auto-restart instead). * - `enabled = false` → recognition.abort() runs, no callbacks fire. * * Bot TTS playback is untouched — the page.tsx-owned