From 5caeb65a08a836defba9573368637e1a19af55ee Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Mon, 25 May 2026 13:33:45 -0700 Subject: [PATCH] test(tts): regression coverage for #29417 double-[pause] fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three new tests in tests/tools/test_tts_xai_speech_tags.py: - multi_paragraph_emits_single_pause — the headline #29417 case. Requires a first sentence of 12+ chars to hit the _XAI_FIRST_SENTENCE_RE length floor; the trivial 'Hello.\\n\\nWorld.' case dodged the bug by accident, which is why the PR's quoted repro didn't reproduce. Uses the longer 'Welcome to the demo of our new product line.\\n\\nIt has many features.' shape that actually trips the bug. - single_paragraph_still_gets_first_sentence_pause — sanity guard that the fix only suppresses the first-sentence pass when a paragraph pass injected [pause], so plain single-paragraph input still gets its leading pause. - single_newline_still_gets_first_sentence_pause — single newline isn't a paragraph break, no [pause] from the paragraph pass, so the first-sentence pause MUST still fire. Catches over-broad fixes. --- tests/tools/test_tts_xai_speech_tags.py | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/tools/test_tts_xai_speech_tags.py b/tests/tools/test_tts_xai_speech_tags.py index 6ab72452ac7..37bde1c710a 100644 --- a/tests/tools/test_tts_xai_speech_tags.py +++ b/tests/tools/test_tts_xai_speech_tags.py @@ -25,6 +25,53 @@ def test_apply_xai_auto_speech_tags_preserves_all_documented_xai_tags(): assert _apply_xai_auto_speech_tags(text) == text +def test_apply_xai_auto_speech_tags_multi_paragraph_emits_single_pause(): + """Regression for #29417 — multi-paragraph input doubled the pause. + + Pre-fix the paragraph substitution injected ``[pause]`` between + paragraphs, then the unconditional first-sentence substitution + added another one right after, producing ``[pause] [pause]`` in + the audio. The fix re-checks the tag-detection guard after the + paragraph pass. + + Requires a first sentence of 12+ chars to hit the + ``_XAI_FIRST_SENTENCE_RE`` length floor — the trivial + ``"Hello.\\n\\nWorld."`` case dodged the bug by accident. + """ + text = "Welcome to the demo of our new product line.\n\nIt has many features." + result = _apply_xai_auto_speech_tags(text) + + # Exactly one [pause] between the paragraphs, not two. + assert result.count("[pause]") == 1, ( + f"expected single [pause], got {result.count('[pause]')} in {result!r}" + ) + assert result == ( + "Welcome to the demo of our new product line. [pause] It has many features." + ) + + +def test_apply_xai_auto_speech_tags_single_paragraph_still_gets_first_sentence_pause(): + """Sanity guard — the fix only suppresses the first-sentence pass when + a paragraph pass already injected ``[pause]``. Single-paragraph input + must still get its first-sentence pause. + """ + text = "Welcome to the demo of our new product line. It has many features." + assert _apply_xai_auto_speech_tags(text) == ( + "Welcome to the demo of our new product line. [pause] It has many features." + ) + + +def test_apply_xai_auto_speech_tags_single_newline_still_gets_first_sentence_pause(): + """A single newline isn't a paragraph break — no ``[pause]`` injected by + the paragraph pass, so the first-sentence pause MUST still fire. + Guards against the fix being too greedy. + """ + text = "Welcome to the demo of our new product line.\nIt has many features." + assert _apply_xai_auto_speech_tags(text) == ( + "Welcome to the demo of our new product line. [pause] It has many features." + ) + + def test_generate_xai_tts_sends_auto_speech_tags_when_enabled(tmp_path, monkeypatch): captured = {}