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:
parent
a62dd0bac1
commit
ac115b25b9
@ -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
|
## [1.18.10] — 2026-07-29
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@ -382,7 +382,7 @@ async def update_voice_meta(request: Request):
|
|||||||
meta["enabled"] = enabled
|
meta["enabled"] = enabled
|
||||||
|
|
||||||
for field in ("note", "rating", "flag", "gender", "loudness", "persona", "origin", "group",
|
for field in ("note", "rating", "flag", "gender", "loudness", "persona", "origin", "group",
|
||||||
"name", "tag", "avatar"):
|
"name", "tag", "avatar", "voice_design_prompt"):
|
||||||
if field in data:
|
if field in data:
|
||||||
meta[field] = data[field]
|
meta[field] = data[field]
|
||||||
if "transcript" in data:
|
if "transcript" in data:
|
||||||
|
|||||||
4
static/dist/main.min.js
vendored
4
static/dist/main.min.js
vendored
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@
|
|||||||
<meta name="format-detection" content="telephone=no">
|
<meta name="format-detection" content="telephone=no">
|
||||||
<meta name="color-scheme" content="light dark">
|
<meta name="color-scheme" content="light dark">
|
||||||
<meta name="theme-color" content="#2563EB">
|
<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="manifest" href="/manifest.webmanifest">
|
||||||
<link rel="icon" href="/static/icon.svg" type="image/svg+xml">
|
<link rel="icon" href="/static/icon.svg" type="image/svg+xml">
|
||||||
<link rel="apple-touch-icon" href="/static/icon.svg">
|
<link rel="apple-touch-icon" href="/static/icon.svg">
|
||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
<!-- ── Core styles (local — no CDN dependency for first paint) ────────── -->
|
<!-- ── Core styles (local — no CDN dependency for first paint) ────────── -->
|
||||||
<link rel="stylesheet" href="/static/vendor/mdi/materialdesignicons.min.css">
|
<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) ── -->
|
<!-- ── Flag icons — non-blocking (loaded async, icons appear after JS) ── -->
|
||||||
@ -378,7 +378,7 @@ window.toggleNavTree = function(treeId, chevronId) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- loader.js: fetches sections → loads JS modules → removes skeleton -->
|
<!-- 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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -2714,6 +2714,11 @@ async function _charAutoDesignVoice(rec, force, instructOverride) {
|
|||||||
tag: rec.book || undefined,
|
tag: rec.book || undefined,
|
||||||
transcript: sampleText,
|
transcript: sampleText,
|
||||||
note: 'Voice Design: ' + instruct.slice(0, 240),
|
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 () {});
|
}).catch(function () {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -898,6 +898,10 @@ $('design-save-btn').addEventListener('click', async () => {
|
|||||||
flag: LANG_FLAG_DEFAULT[$('d-lang').value] || undefined,
|
flag: LANG_FLAG_DEFAULT[$('d-lang').value] || undefined,
|
||||||
transcript: $('d-transcript').value,
|
transcript: $('d-transcript').value,
|
||||||
note: 'Voice Design: ' + $('design-instruct').value.slice(0, 240),
|
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(()=>{});
|
}).catch(()=>{});
|
||||||
await loadVoiceLibrary().catch(()=>{});
|
await loadVoiceLibrary().catch(()=>{});
|
||||||
$('design-save-result').style.display='flex';
|
$('design-save-result').style.display='flex';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user