fix(frank-tts): answer a voice-less request with the declared default
The omp speech device forwards a voice only when the call passes voice_id - there is no setting that feeds one (speech.voice is the TUI speak-aloud Kokoro enum, tts.localVoice belongs to the local backend) - so every harness voiceover arrives with no voice key and the shim answered 400 "unknown voice None". Measured on the deployed endpoint 2026-10-18, from a restarted session with the speech role pointed here. DEFAULT_VOICE makes the absent case a spoken operator choice instead of a code surprise: the pack named there answers a voice-less request and the journal line is marked (default), so an unrequested voice never reads later like a requested one. An UNKNOWN name still 400s with the list that exists - the no-silent-fallback law that this endpoint was built on is untouched, and the strict shape stays the code default (empty DEFAULT_VOICE), which the second new seam test pins. Ships narrator1 in scripts/frank-tts.env.
This commit is contained in:
1 parent
d2ce6693da
commit
b91873578b
3 files changed
+58
-6
No files matched your search
@@ -183,6 +183,37 @@ assert 'voice_id' not in body, body
|
||||
PY
|
||||
}
|
||||
|
||||
@test "a voice-less request speaks the declared default and marks the log" {
|
||||
# The omp harness has no setting that feeds a voice to its speech device, so
|
||||
# a voice-less call is its NORMAL shape rather than a client bug. With the
|
||||
# operator's default armed the call must produce that pack's audio, and the
|
||||
# journal line must say (default) — otherwise an unrequested voice reads,
|
||||
# weeks later, exactly like one somebody asked for.
|
||||
arm_omni
|
||||
export DEFAULT_VOICE=narrator1
|
||||
start_app
|
||||
speech '{"model":"tts-1","input":"hello"}'
|
||||
[ "$output" = "200" ] || { cat "$TEST_TMP/app.log"; false; }
|
||||
cmp "$TEST_TMP/out.bin" "$TEST_TMP/upstream.wav"
|
||||
python3 - "$TEST_TMP/capture.json" <<'PY'
|
||||
import json, sys
|
||||
body = json.load(open(sys.argv[1]))
|
||||
assert body['voice'] == 'narrator1', 'the declared default never reached the engine'
|
||||
PY
|
||||
grep -q 'speech voice=narrator1 (default) format=wav' "$TEST_TMP/app.log" \
|
||||
|| { cat "$TEST_TMP/app.log"; false; }
|
||||
}
|
||||
|
||||
@test "with no default declared a voice-less request stays a 400" {
|
||||
# Strictness is still the code default: an endpoint that invents a voice
|
||||
# nobody configured is exactly how a wrong-voice deployment stays wrong.
|
||||
arm_omni
|
||||
start_app
|
||||
speech '{"model":"tts-1","input":"hello"}'
|
||||
[ "$output" = "400" ] || { cat "$TEST_TMP/app.log"; false; }
|
||||
grep -q 'narrator1' "$TEST_TMP/out.bin"
|
||||
}
|
||||
|
||||
@test "an unknown voice is a 400 naming the voices that exist" {
|
||||
arm_omni
|
||||
start_app
|
||||
|
||||
Reference in new issue
Block a user