From 8823cc0bf043b3d90619a38102c17ef18052208f Mon Sep 17 00:00:00 2001 From: Till JS Date: Fri, 17 Apr 2026 15:22:52 +0200 Subject: [PATCH] feat(profile): voice interview with pre-rendered TTS audio + Orpheus/Zonos backends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Voice-based interview for the profile module — users choose between text, voice (question read aloud + mic for answer), or conversation mode (fully automatic flow with auto-save). Interview audio: - 92 pre-rendered MP3 files (23 questions × 4 voices) via Edge TTS - Voices: Seraphina (DE-f), Florian (DE-m), Leni (CH-f), Jan (CH-m) - User picks voice via dropdown, persisted in localStorage - Web Speech API fallback for missing audio files Profile UI: - Interview hero block on overview with 3 start modes (text/voice/conversation) - Voice/conversation toggle + voice picker in interview view - Mic button on text/textarea/tags inputs for per-question voice input - Conversation mode: auto-save + auto-advance after STT transcription - Recording/transcribing/speaking state indicators mana-tts service: - New Orpheus TTS backend (German finetune, SNAC codec) - New Zonos TTS backend (Zyphra, 200k hours, emotion control) - Endpoints: POST /synthesize/orpheus, POST /synthesize/zonos - espeak-ng installed on GPU server for Zonos phonemizer - Compare script for side-by-side voice quality testing Co-Authored-By: Claude Opus 4.6 (1M context) --- .../modules/profile/ContextInterview.svelte | 569 +++++++++++++++++- .../src/lib/modules/profile/ListView.svelte | 203 ++++++- .../profile/use-interview-tts.svelte.ts | 159 +++++ .../static/audio/interview/ch-f/about.bio.mp3 | Bin 0 -> 15120 bytes .../audio/interview/ch-f/about.birthday.mp3 | Bin 0 -> 15264 bytes .../audio/interview/ch-f/about.languages.mp3 | Bin 0 -> 14832 bytes .../audio/interview/ch-f/about.location.mp3 | Bin 0 -> 11088 bytes .../audio/interview/ch-f/about.occupation.mp3 | Bin 0 -> 15408 bytes .../audio/interview/ch-f/goals.current.mp3 | Bin 0 -> 16992 bytes .../audio/interview/ch-f/goals.focus.mp3 | Bin 0 -> 21600 bytes .../audio/interview/ch-f/goals.learn.mp3 | Bin 0 -> 25200 bytes .../static/audio/interview/ch-f/interests.mp3 | Bin 0 -> 20016 bytes .../interview/ch-f/leisure.favoriteMedia.mp3 | Bin 0 -> 18288 bytes .../audio/interview/ch-f/leisure.sports.mp3 | Bin 0 -> 23904 bytes .../interview/ch-f/nutrition.allergies.mp3 | Bin 0 -> 22464 bytes .../audio/interview/ch-f/nutrition.diet.mp3 | Bin 0 -> 13680 bytes .../interview/ch-f/nutrition.preferences.mp3 | Bin 0 -> 20160 bytes .../audio/interview/ch-f/routine.bedtime.mp3 | Bin 0 -> 19872 bytes .../audio/interview/ch-f/routine.wakeUp.mp3 | Bin 0 -> 19008 bytes .../audio/interview/ch-f/routine.workDays.mp3 | Bin 0 -> 15552 bytes .../audio/interview/ch-f/routine.workEnd.mp3 | Bin 0 -> 13824 bytes .../interview/ch-f/routine.workStart.mp3 | Bin 0 -> 17280 bytes .../interview/ch-f/social.communication.mp3 | Bin 0 -> 25200 bytes .../audio/interview/ch-f/social.living.mp3 | Bin 0 -> 11088 bytes .../audio/interview/ch-f/social.pets.mp3 | Bin 0 -> 12240 bytes .../audio/interview/ch-f/social.workStyle.mp3 | Bin 0 -> 16560 bytes .../static/audio/interview/ch-m/about.bio.mp3 | Bin 0 -> 13104 bytes .../audio/interview/ch-m/about.birthday.mp3 | Bin 0 -> 13536 bytes .../audio/interview/ch-m/about.languages.mp3 | Bin 0 -> 14544 bytes .../audio/interview/ch-m/about.location.mp3 | Bin 0 -> 10512 bytes .../audio/interview/ch-m/about.occupation.mp3 | Bin 0 -> 13248 bytes .../audio/interview/ch-m/goals.current.mp3 | Bin 0 -> 14976 bytes .../audio/interview/ch-m/goals.focus.mp3 | Bin 0 -> 19152 bytes .../audio/interview/ch-m/goals.learn.mp3 | Bin 0 -> 22464 bytes .../static/audio/interview/ch-m/interests.mp3 | Bin 0 -> 17136 bytes .../interview/ch-m/leisure.favoriteMedia.mp3 | Bin 0 -> 17136 bytes .../audio/interview/ch-m/leisure.sports.mp3 | Bin 0 -> 23472 bytes .../interview/ch-m/nutrition.allergies.mp3 | Bin 0 -> 19296 bytes .../audio/interview/ch-m/nutrition.diet.mp3 | Bin 0 -> 12816 bytes .../interview/ch-m/nutrition.preferences.mp3 | Bin 0 -> 17856 bytes .../audio/interview/ch-m/routine.bedtime.mp3 | Bin 0 -> 17424 bytes .../audio/interview/ch-m/routine.wakeUp.mp3 | Bin 0 -> 16992 bytes .../audio/interview/ch-m/routine.workDays.mp3 | Bin 0 -> 15552 bytes .../audio/interview/ch-m/routine.workEnd.mp3 | Bin 0 -> 12528 bytes .../interview/ch-m/routine.workStart.mp3 | Bin 0 -> 15696 bytes .../interview/ch-m/social.communication.mp3 | Bin 0 -> 22176 bytes .../audio/interview/ch-m/social.living.mp3 | Bin 0 -> 10656 bytes .../audio/interview/ch-m/social.pets.mp3 | Bin 0 -> 11376 bytes .../audio/interview/ch-m/social.workStyle.mp3 | Bin 0 -> 14544 bytes .../static/audio/interview/de-f/about.bio.mp3 | Bin 0 -> 11520 bytes .../audio/interview/de-f/about.birthday.mp3 | Bin 0 -> 12240 bytes .../audio/interview/de-f/about.languages.mp3 | Bin 0 -> 13104 bytes .../audio/interview/de-f/about.location.mp3 | Bin 0 -> 8352 bytes .../audio/interview/de-f/about.occupation.mp3 | Bin 0 -> 11376 bytes .../audio/interview/de-f/goals.current.mp3 | Bin 0 -> 14400 bytes .../audio/interview/de-f/goals.focus.mp3 | Bin 0 -> 18864 bytes .../audio/interview/de-f/goals.learn.mp3 | Bin 0 -> 22896 bytes .../static/audio/interview/de-f/interests.mp3 | Bin 0 -> 16272 bytes .../interview/de-f/leisure.favoriteMedia.mp3 | Bin 0 -> 15696 bytes .../audio/interview/de-f/leisure.sports.mp3 | Bin 0 -> 19728 bytes .../interview/de-f/nutrition.allergies.mp3 | Bin 0 -> 19584 bytes .../audio/interview/de-f/nutrition.diet.mp3 | Bin 0 -> 10656 bytes .../interview/de-f/nutrition.preferences.mp3 | Bin 0 -> 19440 bytes .../audio/interview/de-f/routine.bedtime.mp3 | Bin 0 -> 15264 bytes .../audio/interview/de-f/routine.wakeUp.mp3 | Bin 0 -> 14400 bytes .../audio/interview/de-f/routine.workDays.mp3 | Bin 0 -> 14112 bytes .../audio/interview/de-f/routine.workEnd.mp3 | Bin 0 -> 11664 bytes .../interview/de-f/routine.workStart.mp3 | Bin 0 -> 14400 bytes .../interview/de-f/social.communication.mp3 | Bin 0 -> 21600 bytes .../audio/interview/de-f/social.living.mp3 | Bin 0 -> 8352 bytes .../audio/interview/de-f/social.pets.mp3 | Bin 0 -> 10656 bytes .../audio/interview/de-f/social.workStyle.mp3 | Bin 0 -> 13680 bytes .../static/audio/interview/de-m/about.bio.mp3 | Bin 0 -> 10656 bytes .../audio/interview/de-m/about.birthday.mp3 | Bin 0 -> 11088 bytes .../audio/interview/de-m/about.languages.mp3 | Bin 0 -> 12240 bytes .../audio/interview/de-m/about.location.mp3 | Bin 0 -> 7776 bytes .../audio/interview/de-m/about.occupation.mp3 | Bin 0 -> 10800 bytes .../audio/interview/de-m/goals.current.mp3 | Bin 0 -> 13104 bytes .../audio/interview/de-m/goals.focus.mp3 | Bin 0 -> 17280 bytes .../audio/interview/de-m/goals.learn.mp3 | Bin 0 -> 21456 bytes .../static/audio/interview/de-m/interests.mp3 | Bin 0 -> 15120 bytes .../interview/de-m/leisure.favoriteMedia.mp3 | Bin 0 -> 14832 bytes .../audio/interview/de-m/leisure.sports.mp3 | Bin 0 -> 19872 bytes .../interview/de-m/nutrition.allergies.mp3 | Bin 0 -> 18000 bytes .../audio/interview/de-m/nutrition.diet.mp3 | Bin 0 -> 9936 bytes .../interview/de-m/nutrition.preferences.mp3 | Bin 0 -> 17712 bytes .../audio/interview/de-m/routine.bedtime.mp3 | Bin 0 -> 14256 bytes .../audio/interview/de-m/routine.wakeUp.mp3 | Bin 0 -> 13824 bytes .../audio/interview/de-m/routine.workDays.mp3 | Bin 0 -> 12960 bytes .../audio/interview/de-m/routine.workEnd.mp3 | Bin 0 -> 10800 bytes .../interview/de-m/routine.workStart.mp3 | Bin 0 -> 13392 bytes .../interview/de-m/social.communication.mp3 | Bin 0 -> 19296 bytes .../audio/interview/de-m/social.living.mp3 | Bin 0 -> 7920 bytes .../audio/interview/de-m/social.pets.mp3 | Bin 0 -> 9936 bytes .../audio/interview/de-m/social.workStyle.mp3 | Bin 0 -> 12528 bytes services/mana-tts/CLAUDE.md | 12 + services/mana-tts/app/main.py | 167 +++++ services/mana-tts/app/orpheus_service.py | 229 +++++++ services/mana-tts/app/zonos_service.py | 205 +++++++ services/mana-tts/requirements.txt | 10 + .../mana-tts/scripts/compare-german-tts.sh | 74 +++ 101 files changed, 1597 insertions(+), 31 deletions(-) create mode 100644 apps/mana/apps/web/src/lib/modules/profile/use-interview-tts.svelte.ts create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/about.bio.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/about.birthday.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/about.languages.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/about.location.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/about.occupation.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/goals.current.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/goals.focus.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/goals.learn.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/interests.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/leisure.favoriteMedia.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/leisure.sports.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/nutrition.allergies.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/nutrition.diet.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/nutrition.preferences.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/routine.bedtime.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/routine.wakeUp.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/routine.workDays.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/routine.workEnd.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/routine.workStart.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/social.communication.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/social.living.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/social.pets.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-f/social.workStyle.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/about.bio.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/about.birthday.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/about.languages.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/about.location.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/about.occupation.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/goals.current.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/goals.focus.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/goals.learn.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/interests.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/leisure.favoriteMedia.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/leisure.sports.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/nutrition.allergies.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/nutrition.diet.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/nutrition.preferences.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/routine.bedtime.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/routine.wakeUp.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/routine.workDays.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/routine.workEnd.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/routine.workStart.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/social.communication.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/social.living.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/social.pets.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/ch-m/social.workStyle.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/about.bio.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/about.birthday.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/about.languages.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/about.location.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/about.occupation.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/goals.current.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/goals.focus.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/goals.learn.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/interests.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/leisure.favoriteMedia.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/leisure.sports.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/nutrition.allergies.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/nutrition.diet.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/nutrition.preferences.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/routine.bedtime.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/routine.wakeUp.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/routine.workDays.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/routine.workEnd.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/routine.workStart.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/social.communication.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/social.living.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/social.pets.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-f/social.workStyle.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/about.bio.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/about.birthday.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/about.languages.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/about.location.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/about.occupation.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/goals.current.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/goals.focus.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/goals.learn.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/interests.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/leisure.favoriteMedia.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/leisure.sports.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/nutrition.allergies.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/nutrition.diet.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/nutrition.preferences.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/routine.bedtime.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/routine.wakeUp.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/routine.workDays.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/routine.workEnd.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/routine.workStart.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/social.communication.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/social.living.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/social.pets.mp3 create mode 100644 apps/mana/apps/web/static/audio/interview/de-m/social.workStyle.mp3 create mode 100644 services/mana-tts/app/orpheus_service.py create mode 100644 services/mana-tts/app/zonos_service.py create mode 100755 services/mana-tts/scripts/compare-german-tts.sh diff --git a/apps/mana/apps/web/src/lib/modules/profile/ContextInterview.svelte b/apps/mana/apps/web/src/lib/modules/profile/ContextInterview.svelte index 0694c2b64..e08bb8459 100644 --- a/apps/mana/apps/web/src/lib/modules/profile/ContextInterview.svelte +++ b/apps/mana/apps/web/src/lib/modules/profile/ContextInterview.svelte @@ -2,7 +2,7 @@ Context Interview — Guided question flow that populates userContext. -->