feat: US-006 - Refactor tools/tts.py — rutare engine, backend pocket-tts și fallback
- synthesize() rezolvă engine din tts_voices.json (fallback la tts.default_engine din config) - _synthesize_pockettts nou: POST multipart la :7789/tts cu voice_wav/voice_url, ignoră lang - fallback tehnic automat pe _synthesize_supertonic(M2, ro) via _PocketTTSUnavailable; erori de conținut (voce lipsă, text gol) nu declanșează fallback; rezultatul include engine_used - gates rulate: tests PASS (1043 passed, 22 eșecuri preexistente neschimbate), /workflow:simplify (4 agenți) cu 1 fix aplicat, /review (backend, manual) PASS
This commit is contained in:
@@ -44,3 +44,84 @@ Project: echo-core
|
||||
- US-003 (db+backend, catalog tts_voices.json) — eligibil, dependsOn gol
|
||||
- US-005 (backend, config.json tts section) — eligibil, dependsOn gol
|
||||
---
|
||||
|
||||
## Iterație: 2026-07-11 (US-004)
|
||||
### Story implementat: US-004 - Script de export voce pocket_tts_add_voice.py (tags: backend)
|
||||
### Status: Complete
|
||||
|
||||
### Gates rulate:
|
||||
- Typecheck: SKIP (mypy neinstalat în .venv)
|
||||
- Lint: SKIP (ruff neinstalat în .venv)
|
||||
- Tests: PASS — pytest tests/ aceleași 22 eșecuri preexistente, 1043 passed (neschimbat)
|
||||
- /review (backend): PASS — script mic, single-responsibility, erori clare (wav lipsă / hf_token lipsă din keyring), fără shell injection / secret leakage (HF_TOKEN doar în os.environ al subprocesului, niciodată logat)
|
||||
- Verificare manuală: .venv-pockettts/bin/python tools/pocket_tts_add_voice.py --help rulează curat fără a atinge .venv principal; _next_free_index() -> 4 pentru Marius/Paula (seed 1-3 deja ocupat), 1 pentru nume noi; toate cele 6 blob-uri models/voices/{marius,paula}-{1,2,3}.safetensors validate cu safetensors.torch.load_file (12 tensori fiecare, fără corupere)
|
||||
|
||||
### Learnings:
|
||||
- Iterația anterioară (US-004, retries=1) a atins max_turns=30 în timp ce lucra pe US-003 și US-004 în aceeași sesiune (script scris, model încărcat, 6 voci exportate, catalog scris) dar nu a apucat să facă commit — la începutul iterației verifică mereu `git status`/`git log` înainte să presupui că trebuie reimplementat de la zero; codul + blob-urile deja produse pot fi validate în loc de regenerate (re-exportul ar fi reîncărcat modelul, costisitor).
|
||||
- `tools/pocket_tts_add_voice.py` a ajuns commitat accidental în același commit cu US-003 (e3b5cdf) pentru că era deja `git add`-uit din sesiunea anterioară — commit-urile per-story nu sunt garantat izolate dacă lucrul anterior a lăsat fișiere staged; verifică `git diff --cached` înainte de commit ca să știi exact ce intră.
|
||||
- `scripts/ralph/prd.json` (harness PRD-ul acestui proiect) și `cron/jobs.json` (timestamp-uri live ale schedulerului) nu trebuie commitate ca parte a unui story de cod — doar prd.json e commitat, dar separat, ca update de stare, nu amestecat în diff-ul de cod al story-ului.
|
||||
|
||||
### Next:
|
||||
- US-005 (backend, config.json secțiune tts) — eligibil, dependsOn gol
|
||||
- US-010 (backend, /voice doctor + pocket-tts health) — eligibil, dependsOn US-001+US-002 (ambele passes:true)
|
||||
---
|
||||
|
||||
## Iterație: 2026-07-11 (US-005)
|
||||
### Story implementat: US-005 - Adaugă secțiunea tts în config.json (tags: backend)
|
||||
### Status: Complete
|
||||
|
||||
### Gates rulate:
|
||||
- Typecheck: SKIP (mypy neinstalat în .venv)
|
||||
- Lint: SKIP (ruff neinstalat în .venv)
|
||||
- Tests: PASS — pytest tests/ aceleași 22 eșecuri preexistente, 1043 passed (neschimbat)
|
||||
- /review (backend): review manual (skill-ul interactiv /review nu se pretează unei iterații autonome — cere AskUserQuestion) — diff e doar date (4 linii JSON), fără cod nou care citește tts.* (US-006 face asta), fără secrete, JSON valid
|
||||
|
||||
### Learnings:
|
||||
- src/config.py::Config e deja complet generic (get/set/save/reload cu dot-notation pe orice cheie nouă) — adăugarea unei secțiuni noi în config.json nu cere nicio schimbare de cod, doar date. tests/test_config.py deja acoperă roundtrip-ul set→save→reload generic, deci AC-urile de persistență ale story-ului sunt satisfăcute fără teste noi.
|
||||
- Skill-ul gstack `/review` e construit pentru revizuire PR interactivă (AskUserQuestion, gh pr, telemetry) — pentru iterații Ralph autonome cu diff-uri mici/triviale, un review manual (grep pentru cod care citește noua cheie, verificare JSON valid, verificare secrete) e suficient și evită blocarea pe input interactiv indisponibil.
|
||||
|
||||
### Next:
|
||||
- US-010 (backend, /voice doctor + pocket-tts health) — eligibil, dependsOn US-001+US-002 (ambele passes:true)
|
||||
- US-006 (backend+refactor, rutare engine tts.py) — NU eligibil încă, dependsOn include US-003 (passes:true) dar și US-005 (acum passes:true) — devine eligibil următoarea iterație
|
||||
---
|
||||
|
||||
## Iterație: 2026-07-11 (US-006)
|
||||
### Story implementat: US-006 - Refactor tools/tts.py — rutare engine, backend pocket-tts și fallback (tags: backend, refactor)
|
||||
### Status: Complete
|
||||
|
||||
### Gates rulate:
|
||||
- Typecheck: SKIP (mypy neinstalat în .venv)
|
||||
- Lint: SKIP (ruff neinstalat în .venv)
|
||||
- Tests: PASS — pytest tests/ aceleași 22 eșecuri preexistente, 1043 passed (neschimbat)
|
||||
- /workflow:simplify (refactor): 4 agenți paraleli (reuse/simplification/efficiency/altitude) pe diff-ul tools/tts.py.
|
||||
Aplicat 1 fix sigur: `engine_used` setat o singură dată în loc de trei literali duplicate.
|
||||
Respinse ca false-positive (verificate contra AC-urilor explicite din PRD, nu doar "pare hardcodat"):
|
||||
- voice=DEFAULT_VOICE, lang=DEFAULT_LANG hardcodate pe calea de fallback tehnic — AC-ul US-006 cere explicit
|
||||
`_synthesize_supertonic(voice='M2', lang='ro')`; pocket-tts ignoră lang complet, deci la fallback nu există
|
||||
niciun semnal de încredere pentru ce limbă Supertonic ar trebui folosită — design intenționat, nu bandaid.
|
||||
- lookup catalog case-insensitive unificat — ar schimba comportamentul (matching pe nume gen "Marius 1")
|
||||
fără cerință din AC, risc fără beneficiu clar în scope-ul acestui story.
|
||||
Notat pentru follow-up (NU implementat, în afara scope-ului): `_load_voice_catalog()`/`_config_get()`/citirea
|
||||
fișierului de voce clonată se repetă per-clauză în hot path-ul de streaming (src/voice/tts_stream.py) — un
|
||||
cache per-sesiune ar elimina I/O redundant, dar necesită schimbări în afara tools/tts.py.
|
||||
- /review (backend, manual — skill-ul interactiv nu se pretează unei iterații autonome): PASS — fără shell
|
||||
injection, fără secret leakage, error handling scoped corect (ConnectError/TimeoutException/HTTPStatusError
|
||||
separate de erorile de conținut 4xx), semnătura publică synthesize(text, voice, lang) neschimbată (verificat
|
||||
caller-ul src/fast_commands.py::_tts_synthesize).
|
||||
|
||||
### Learnings:
|
||||
- Codul pentru US-006 era deja scris (necommitat) dintr-o iterație anterioară care nu a apucat să facă commit —
|
||||
la fel ca US-003/US-004, verifică mereu `git diff`/`git status` înainte să presupui reimplementare de la zero.
|
||||
- Gate-urile `/simplify` (agenți automați) găsesc uneori "probleme" care sunt de fapt cerințe explicite din AC
|
||||
(ex. valorile hardcodate de fallback voice='M2'/lang='ro') — verifică fiecare finding contra textului literal
|
||||
al acceptance criteria din PRD înainte să aplici un fix, nu doar contra intuiției generale de cod curat.
|
||||
- Findings de eficiență care ar necesita schimbări cross-file (aici: caching în src/voice/tts_stream.py pentru
|
||||
hot path-ul de streaming) rămân notate ca follow-up, nu aplicate — story-ul e scopat strict la tools/tts.py.
|
||||
|
||||
### Next:
|
||||
- US-010 (backend, /voice doctor + pocket-tts health) — eligibil, dependsOn US-001+US-002 (ambele passes:true)
|
||||
- US-007 (ui+backend, /voice engine) — eligibil, dependsOn US-005+US-006 (ambele acum passes:true)
|
||||
- US-008 (ui+backend, /voice addvoice) — eligibil, dependsOn US-004+US-006 (ambele acum passes:true)
|
||||
- US-009 (ui+backend, autocomplete voci) — eligibil, dependsOn US-003+US-006 (ambele acum passes:true)
|
||||
- US-011 (backend, teste TTS) — eligibil, dependsOn US-006 (acum passes:true)
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user