Skip to content

fix(tts): key the TTS audio cache by a hash of voice + text - #16881

Open
aniketkrs wants to merge 1 commit into
LibreChat-AI:devfrom
aniketkrs:fix/tts-cache-key
Open

aniketkrs wants to merge 1 commit into
LibreChat-AI:devfrom
aniketkrs:fix/tts-cache-key

Conversation

@aniketkrs

Copy link
Copy Markdown
Contributor

Impact

With "Cache TTS" enabled, clicking read-aloud on a message plays the audio of a different message whenever both messages start with a Markdown heading. Markdown answers with headings are the common case for an assistant, so this breaks the feature exactly where it matters most.

Cause

In client/src/hooks/Input/useTextToSpeechExternal.ts, audio is stored with cache.put(new Request(inputText), response) and looked up with caches.match(text) — the raw message text doubles as the cache key. The Cache API parses that string as a URL against the document base (<base href="/">) and ignores the fragment when matching. A message starting with # therefore keys to the site base URL whatever its content, and every such message shares one cache entry: the first audio stored is served for all of them. Text with # later (a heading after the first paragraph) collides with any other text sharing the same prefix up to that #; ? or : early in the text mis-parse as query or scheme.

Verified with a Node repro of the Cache API's key derivation (new URL(text, base) with fragment stripped): two distinct messages starting with ## R..ponse courte both key to https://chat.example/ — collision confirmed.

Fix

Key the cache by a hash of voice + text (getTTSCacheKey, FNV-1a) instead of the raw text, at both the cache.put and caches.match sites. The same repro shows the two messages now key to distinct entries (tts-audio-a8f33905 vs tts-audio-7601e7f4), the key is stable for the same text + voice, and it changes with the voice so switching voices does not serve stale audio. The key is a plain relative path, so it resolves cleanly as a Request URL.

Fixes #16879.

Copilot AI balanced review requested due to automatic review settings October 8, 2026 03:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@github-actions
github-actions Bot changed the base branch from main to dev October 8, 2026 03:56
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

👋 Thanks for the contribution! LibreChat merges all changes into dev first — main only moves at release time — so this pull request's base branch was switched from main to dev automatically.

Nothing is needed from you; your commits, reviews and discussion are unchanged. If the diff now shows files you did not touch, rebase onto dev:

git remote add upstream https://github.com/LibreChat-AI/LibreChat.git
git fetch upstream dev
git rebase upstream/dev
git push --force-with-lease

Maintainers: apply the target: main label and restore the base branch if this one genuinely belongs on main.

@codegraph-librechat codegraph-librechat Bot added 🗺️ Speech IO codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) 🗺️ Core Chat UX codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) 🗺️ I18n & Voice codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) labels Oct 9, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🗺️ Core Chat UX codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) 🗺️ I18n & Voice codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) 🗺️ Speech IO codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: TTS cache plays another message's audio when messages start with a Markdown heading (cache key is the text, parsed as a URL)

2 participants