Store the full voice design prompt, not just the clipped summary

For a designed voice the instruct prompt is the voice's identity — the TTS
engine reproduces the voice from that text alone. The only copy saved was the
`note` display summary, clipped to 240 characters, which left 43 of 73 voices
cut off mid-sentence. Save the complete prompt in its own field so the engine
can register a voice from the whole description.

Existing voices keep working from the clipped copy (it still carries gender,
accent and timbre) and pick up the full text when next redesigned.

Pairs with the engine-side fix in tts-dgx-spark-faster-qwen3-tts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mARTin-B78 2026-07-29 15:57:51 +02:00
parent a62dd0bac1
commit ac115b25b9
7 changed files with 24 additions and 7 deletions

View File

@ -5,6 +5,14 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
---
## [1.18.11] — 2026-07-29
### Fixed
- **Designed voices now store their full design prompt.** For a designed voice the prompt IS the voice's identity — the engine reproduces it from that text alone — but the only copy saved was the `note` display summary, which is deliberately clipped to 240 characters (43 of 73 voices were cut off mid-sentence). The complete prompt is now saved in its own field, so the TTS engine can register the voice from the whole description rather than a truncated one. Existing voices keep working from the clipped copy — it still carries gender, accent and timbre — and pick up the full text the next time they are redesigned.
### Note
- This release pairs with an engine-side fix (in the `tts-dgx-spark-faster-qwen3-tts` repo) for two bugs that made custom voices unusable: stale speaker embeddings causing cloned voices to ignore the requested text entirely, and designed voices never being registered with the Voice Design engine, which silently substituted a bundled British preset. See that repo's history for details.
## [1.18.10] — 2026-07-29
### Fixed

View File

@ -1 +1 @@
1.18.10
1.18.11

View File

@ -382,7 +382,7 @@ async def update_voice_meta(request: Request):
meta["enabled"] = enabled
for field in ("note", "rating", "flag", "gender", "loudness", "persona", "origin", "group",
"name", "tag", "avatar"):
"name", "tag", "avatar", "voice_design_prompt"):
if field in data:
meta[field] = data[field]
if "transcript" in data:

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,7 @@
<meta name="format-detection" content="telephone=no">
<meta name="color-scheme" content="light dark">
<meta name="theme-color" content="#2563EB">
<meta name="app-version" content="1.18.10">
<meta name="app-version" content="1.18.11">
<link rel="manifest" href="/manifest.webmanifest">
<link rel="icon" href="/static/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/static/icon.svg">
@ -27,7 +27,7 @@
<!-- ── Core styles (local — no CDN dependency for first paint) ────────── -->
<link rel="stylesheet" href="/static/vendor/mdi/materialdesignicons.min.css">
<link rel="stylesheet" href="/static/style.css?v=1.18.10">
<link rel="stylesheet" href="/static/style.css?v=1.18.11">
<!-- ── Flag icons — non-blocking (loaded async, icons appear after JS) ── -->
@ -378,7 +378,7 @@ window.toggleNavTree = function(treeId, chevronId) {
</script>
<!-- loader.js: fetches sections → loads JS modules → removes skeleton -->
<script src="/static/loader.js?v=1.18.10"></script>
<script src="/static/loader.js?v=1.18.11"></script>
</body>
</html>

View File

@ -2714,6 +2714,11 @@ async function _charAutoDesignVoice(rec, force, instructOverride) {
tag: rec.book || undefined,
transcript: sampleText,
note: 'Voice Design: ' + instruct.slice(0, 240),
// For a designed voice the instruct IS the voice's identity — the TTS
// engine reproduces it from this text alone. `note` is a short display
// summary and is deliberately clipped, so it cannot be the source of
// truth; store the prompt in full here.
voice_design_prompt: instruct,
}).catch(function () {});
}

View File

@ -898,6 +898,10 @@ $('design-save-btn').addEventListener('click', async () => {
flag: LANG_FLAG_DEFAULT[$('d-lang').value] || undefined,
transcript: $('d-transcript').value,
note: 'Voice Design: ' + $('design-instruct').value.slice(0, 240),
origin: 'designed',
// `note` is a clipped display summary; the engine needs the whole
// prompt, since for a designed voice the instruct is the identity.
voice_design_prompt: $('design-instruct').value,
}).catch(()=>{});
await loadVoiceLibrary().catch(()=>{});
$('design-save-result').style.display='flex';