From d9336e74533415b3e6ba15d907dafd24edabc032 Mon Sep 17 00:00:00 2001 From: Johann Date: Thu, 28 May 2026 23:25:45 -0400 Subject: [PATCH] fix(tts): strip reasoning blocks from TTS text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When /reasoning show is enabled, the model's blocks appear in the final assistant message. TTS reads these aloud, which is unwanted — users want to see reasoning but not hear it spoken. - Add _THINK_BLOCK regex to _strip_markdown_for_tts() (tools/tts_tool.py) — the general TTS text-preparation path used by all TTS providers - Add stripping to prepare_tts_text() (gateway/platforms/base.py) — the gateway auto-TTS path - Reuses the existing regex pattern from stream_tts_to_speaker() Closes #34213 --- gateway/platforms/base.py | 8 +++++--- tools/tts_tool.py | 7 ++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/gateway/platforms/base.py b/gateway/platforms/base.py index 60f3344c38c8..8e1b2c638483 100644 --- a/gateway/platforms/base.py +++ b/gateway/platforms/base.py @@ -3833,9 +3833,10 @@ class BasePlatformAdapter(ABC): def prepare_tts_text(self, text: str) -> str: """Prepare a spoken script for TTS. - Auto-TTS should not feed raw chat Markdown or compact symbols to the - speech provider. It should receive a transcript-like script: headings - and bullets flattened into sentence pauses, and units like ``°C`` + Auto-TTS should not feed raw chat Markdown, ```` reasoning + blocks, or compact symbols to the speech provider. It should receive + a transcript-like script: reasoning blocks removed, headings and + bullets flattened into sentence pauses, and units like ``°C`` expanded to words such as ``degrees Celsius``. """ try: @@ -3843,6 +3844,7 @@ class BasePlatformAdapter(ABC): return prepare_spoken_text(text, max_chars=4000) except Exception: # Keep auto-TTS best-effort if the normalizer ever fails. + text = re.sub(r'].*?', ' ', text, flags=re.DOTALL) return re.sub(r'[*_`#\[\]()]', '', text)[:4000].strip() async def play_tts( diff --git a/tools/tts_tool.py b/tools/tts_tool.py index ebf5241cfc5b..9a691607c5eb 100644 --- a/tools/tts_tool.py +++ b/tools/tts_tool.py @@ -3057,9 +3057,14 @@ _EMOJI = re.compile( '[\U0001F000-\U0001FAFF\u2600-\u27BF\uFE0F\u200D\U000E0020-\U000E007F]+' ) +# Strip ... reasoning blocks before TTS — models with +# /reasoning show enabled produce think blocks that shouldn't be spoken. +_THINK_BLOCK = re.compile(r'].*?', flags=re.DOTALL) + def _strip_markdown_for_tts(text: str) -> str: - """Remove markdown formatting (and emoji) that shouldn't be spoken aloud.""" + """Remove markdown, think blocks, and emoji that shouldn't be spoken.""" + text = _THINK_BLOCK.sub(' ', text) text = _MD_CODE_BLOCK.sub(' ', text) text = _MD_LINK.sub(r'\1', text) text = _MD_URL.sub('', text)