mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-09-06 22:49:29 +00:00
* 🔊 fix: Autoplay Latest Message for Browser TTS and short responses Automatic playback never reached the Web Speech API and dropped audio for short responses. Two independent defects: Autoplay ignored the selected TTS engine. `ChatForm` mounted `StreamAudio` whenever automatic playback was on, and that component always POSTs to `/api/files/speech/tts`, so the Browser engine silently fell through to the external endpoint and `speechSynthesis.speak()` was never called. The engine-aware `useTextToSpeech` hook had no consumers. Autoplay now selects its driver by engine the same way `MessageAudio` does, with the gate shared between both drivers so they trigger on identical terms. `MediaSourceAppender` stranded its queue. `tryAppendNextChunk` only ran from `addData` and `updateend`, while `sourceopen` — which fires only once a media element attaches the object URL — created the `SourceBuffer` without draining what had queued up behind it. A response read in full before that event left every chunk in the queue with no `updateend` to ever restart the drain, so the element sat at `readyState: 0` and never played. Short responses lost the race; longer ones streamed past `sourceopen` and worked. The handler now drains, and `close()` (previously never called) ends the stream once the queue empties. Also in the same path: the error branch had its timeout comparison inverted, so real failures were logged as timeouts and swallowed; and the non-MSE fallback that hands the element a finished blob lived inside the cache-only branch, leaving browsers without MSE support for `audio/mpeg` with no audio at all unless Cache TTS happened to be enabled. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0184N7d9kgpdqmbCb9ujMmNX * 🧹 style: Sort imports in autoplay files `npm run sort-imports:check` on the changed files. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0184N7d9kgpdqmbCb9ujMmNX * 🔇 fix: End the media source when no audio ever arrives Codex P2 on #15347. The `hasAppended` guard in `tryEndOfStream` was defensive against a throw that cannot happen: `endOfStream()` only raises `InvalidStateError` while the source is not open or a buffer is updating, both of which the remaining guards already cover. Nothing about an empty buffer throws. The guard's actual effect was to strand the two cases it was meant to protect. A TTS response that completes with zero bytes, or a read timeout that fires before the first byte, both reach `close()` with the MediaSource URL already attached to the element — and left it `open` forever, so the element waited on a source that could never receive data and kept its streaming resources |
||
|---|---|---|
| .. | ||
| public | ||
| scripts | ||
| src | ||
| sw | ||
| test | ||
| babel.config.cjs | ||
| check_updates.sh | ||
| index.html | ||
| jest.config.cjs | ||
| jest.resolver.cjs | ||
| nginx.conf | ||
| package.json | ||
| postcss.config.cjs | ||
| tailwind.config.cjs | ||
| tsconfig.json | ||
| vite.config.ts | ||