Skip to content

ADR-225: TTS sample generation stage#228

Merged
jodavis merged 7 commits into
feature/ADR-191-oop-ml-pipelinefrom
dev/claude/ADR-225
Jun 17, 2026
Merged

ADR-225: TTS sample generation stage#228
jodavis merged 7 commits into
feature/ADR-191-oop-ml-pipelinefrom
dev/claude/ADR-225

Conversation

@jodavis-claude

Copy link
Copy Markdown
Collaborator

Work item

ADR-225 — Implement the TTS sample generation stage (TtsSampleGenerator) and its DVC entry-point, converting Manifest[TextSample] into Manifest[AudioSample] by synthesizing speech via edge_tts with per-sample voice and speech-rate variation.

Changes

  • New ml/pipeline/speech/__init__.py — package marker for the new speech subpackage
  • New ml/pipeline/speech/tts_stage.pyTtsProvider protocol; TtsSampleGenerator(ModifierStage[TextSample, AudioSample]) with _get_applied_values, _derive_id, and _generate_output; EdgeTtsProvider concrete implementation that streams MP3 from edge_tts, converts to WAV via soundfile, and retries up to 3 times with exponential back-off
  • New ml/pipeline/stages/speech_03_generate_samples.py — DVC entry-point: fetches and filters the en-US female voice list, loads params, constructs the stage, and drives asyncio.run(stage.transform(...))
  • Modified ml/pipeline/stages/params.py — added GenerateSamplesParams dataclass (speech_rate_min, speech_rate_max) and wired it into PipelineParams.load() from stages.generate_speech_samples
  • Modified ml/params.yaml — added stages.generate_speech_samples section with default speech_rate_min: -10 / speech_rate_max: 20
  • Modified ml/dvc.yaml — added speech_03_generate_samples stage with persist: true on the output directory (required by ModifierStage seed-storage contract)
  • New ml/test/pipeline/speech/__init__.py — test package marker
  • New ml/test/pipeline/speech/test_tts_stage.py — 25 unit tests covering applied-values keys/types, _derive_id format, TTS provider call arguments, AudioSample.transcript correctness, rate-string formatting, and skip-path behaviour
  • Modified ml/test/pipeline/stages/test_params.py — updated _VALID_DATA fixture and added 3 tests for GenerateSamplesParams loading

Design decisions

MP3 → WAV conversion via soundfile. edge_tts streams raw MP3 bytes; soundfile 0.13.1 (already installed) reads MP3 natively from a BytesIO buffer. EdgeTtsProvider decodes to a numpy array and re-encodes as PCM_16 WAV — no additional runtime dependency required.

speech_rate stored as raw int, rate string assembled at synthesis time. Keeping +5% out of applied_values means the content hash is stable even if the formatting convention changes; only the semantic value matters for skip-unchanged detection.

Voice list filtered in the entry-point, not in the stage. TtsSampleGenerator accepts a plain list[str], making it trivially testable with a two-element stub list without any network calls.

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

Test Results

401 tests  ±0   401 ✅ ±0   2m 20s ⏱️ +2s
  5 suites ±0     0 💤 ±0 
  5 files   ±0     0 ❌ ±0 

Results for commit 2a33c51. ± Comparison against base commit 3008969.

♻️ This comment has been updated with latest results.

@jodavis-claude jodavis-claude left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

ADR-225 TTS Stage — First-pass review

All exit criteria are met: TtsProvider protocol, TtsSampleGenerator with correct _derive_id/_get_applied_values/_generate_output, EdgeTtsProvider with exponential back-off retry, entry-point voice filtering, 25 unit tests covering applied-value types, rate string formatting, skip path, and transcript/label invariants. Build and tests pass. No correctness, security, or performance issues found.

Issues

Priority 4

  • .claude/settings.json (line 7): Unrelated change (clearing extraKnownMarketplaces) bundled into this PR. Should be separated.
  • Missing ml/pipeline/speech/_doc_speech.md: ml/pipeline/speech/ is a new package. CONTRIBUTING.md: "When new subsystems are added, they should include a documentation file." The spec (_spec_OopPipeline.md) is pre-implementation and cannot serve this role. A _doc_*.md covering the speech subsystem's design intent (TtsProvider abstraction, EdgeTtsProvider retry contract, relationship to ModifierStage) should be added before this merges.

Priority 5 (style, non-blocking)

  • tts_stage.py line 91: Multi-line docstring on EdgeTtsProvider. CLAUDE.md: one short line max; remove or collapse.
  • speech_03_generate_samples.py line 1: 10-line module docstring with usage block. Same policy; remove or collapse to one line.

Comment thread .claude/settings.json
Comment thread ml/pipeline/speech/tts_stage.py Outdated
Comment thread ml/pipeline/stages/speech_03_generate_samples.py Outdated

@jodavis-claude jodavis-claude left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Sign-off review — all prior issues resolved, no new issues found.

Prior threads (all resolved):

  • [P4] .claude/settings.json: extraKnownMarketplaces cleared accidentally — reverted in 05abd7b, marketplace entry restored. ✓ Resolved.
  • [P5] tts_stage.py EdgeTtsProvider multi-line docstring — removed in 5608fbd. ✓ Resolved.
  • [P5] speech_03_generate_samples.py 10-line module docstring — removed in 07d468e. ✓ Resolved.

New file scan (4 modified files: .claude/settings.json, tts_stage.py, speech_03_generate_samples.py, _doc_speech.md):

  • No new Priority 1–4 issues found. The _doc_speech.md addition (commit 2c156c3) covers the required design decisions per CONTRIBUTING.md.

Outcome: approved — ready for human review.

@jodavis-claude
jodavis-claude marked this pull request as ready for review June 16, 2026 23:18
@jodavis-claude
jodavis-claude requested a review from jodavis June 16, 2026 23:19
@jodavis

jodavis commented Jun 16, 2026

Copy link
Copy Markdown
Owner

@copilot fix the test failure in this branch. It's probably a missing dependency in requirements.txt. Verify that the build passes with no warnings or errors and that all tests pass when you are done.

Copilot AI commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

@copilot fix the test failure in this branch. It's probably a missing dependency in requirements.txt. Verify that the build passes with no warnings or errors and that all tests pass when you are done.

Fixed in the latest commit. soundfile and edge-tts were missing from ml/requirements.txt — added soundfile>=0.13.1 and edge-tts>=6.1.9. All 177 Python tests pass locally.

Comment thread .claude/settings.json
Comment thread ml/pipeline/speech/tts_stage.py
Comment thread ml/dvc.yaml Outdated
ElwoodMoves and others added 5 commits June 16, 2026 18:13
The ADR-225 implementation commit accidentally cleared
extraKnownMarketplaces; restore the jodavis-agent-plugins marketplace
entry that was present before.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CONTRIBUTING.md requires a documentation file for new subsystems.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CLAUDE.md: never write multi-paragraph docstrings. The retry strategy is
self-evident from the constants and loop structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…les.py

CLAUDE.md: never write multi-paragraph docstrings. The usage block
duplicates what argparse --help already surfaces.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Speech and intent pipelines have separate number spaces. The speech
pipeline starts at 01, so this stage is speech_01, not speech_03.
@jodavis
jodavis enabled auto-merge (squash) June 17, 2026 01:24
@jodavis
jodavis merged commit c0d9a81 into feature/ADR-191-oop-ml-pipeline Jun 17, 2026
3 checks passed
@jodavis
jodavis deleted the dev/claude/ADR-225 branch June 17, 2026 01:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants