french was never going to work, and a test said it would

Probing all nine of Kokoro's languages through the running endpoint, one request
each: eight returned audio and `fr` returned a 500 — "espeak-ng has no such
language". French is regioned in espeak exactly like English (fr-fr, fr-be,
fr-ch), so the bare code every OpenAI-compatible client sends was refused. The
French voice had never worked.

The regionless map's own comment asserted the opposite: that "it", "fr" and "de"
are all accepted bare. Two of those are true. A test asserted the same thing for
all three, so the belief was pinned in place without ever being measured —
exactly the failure the Kokoro-English fix was about, one language further along.
"fr" now maps to "fr-fr"; the comment says not to add a code on the strength of
the pattern, because the pattern is what got this wrong.

Measured bare-OK while I was there, so the next person has data instead of a
guess: de, it, nl, pl, tr, ru, ko, ar, cs, hu, sv. The corrected test asserts
those, and a new one checks the invariant that broke here — every language the
listing advertises for Kokoro must resolve to something espeak was measured to
accept.
Co-Authored-By: 's avatarClaude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T3rZozi1Ehk96NG1WesgC
parent 40aa3eb0
......@@ -16,7 +16,7 @@
# Canonical product version for CoderAI — single source of truth. Both the API
# metadata and the admin web UI read from here.
__version__ = "0.5.39"
__version__ = "0.5.40"
__tagline__ = "Complete orchestration, distribution and escalation of remotizable advanced inference."
# Configure the CUDA caching allocator BEFORE torch is imported anywhere.
......
......@@ -237,10 +237,17 @@ def _kokoro_static_voices(config: Optional[dict] = None) -> list:
#: Every OpenAI-compatible client in existence sends "en", so Kokoro's English
#: voices were unreachable while its Italian ones worked, which reads as the
#: model being broken rather than as a two-letter code needing a region.
#: Only codes espeak actually refuses belong here: "it", "fr" and "de" are
#: accepted bare and must pass through untouched.
#: Only codes espeak actually refuses belong here. Measured against the running
#: engine 2026-10-30, one language per request: "de", "it", "nl", "pl", "tr",
#: "ru", "ko", "ar", "cs", "hu" and "sv" are all accepted bare and must pass
#: through untouched -- but "fr" is NOT, which this comment previously asserted
#: it was. French is regioned in espeak exactly like English (fr-fr, fr-be,
#: fr-ch), so Kokoro's French voice answered every request with a 500 while its
#: Italian one worked. Do not add a code here on the strength of the pattern:
#: probe it, because the pattern is what got "fr" wrong.
_ESPEAK_REGIONLESS = {
"en": "en-us",
"fr": "fr-fr",
"pt": "pt-br",
"zh": "cmn",
}
......
......@@ -128,12 +128,26 @@ def test_a_bare_en_becomes_an_espeak_language():
def test_languages_espeak_accepts_bare_are_untouched():
"""Rewriting 'it' would break the voices that were working."""
"""Rewriting 'it' would break the voices that were working.
'fr' USED to be in this list, on the strength of the pattern rather than a
measurement, and it was wrong: probing the running engine on 2026-10-30
showed French is regioned in espeak exactly like English, so a bare 'fr'
answered every request with a 500 while 'it' worked. It now maps to 'fr-fr'
and lives in the mapped set below. The rest of these were measured bare.
"""
from codai.api.tts_backends import espeak_language
for code in ("it", "fr", "de", "es", "en-gb", "en-us"):
for code in ("it", "de", "es", "nl", "pl", "tr", "ru", "ko", "ar",
"cs", "hu", "sv", "en-gb", "en-us"):
assert espeak_language(code) == code
def test_french_is_regioned_like_english():
from codai.api.tts_backends import espeak_language
assert espeak_language("fr") == "fr-fr"
assert espeak_language("fr-be") == "fr-be"
def test_an_empty_language_still_has_a_default():
from codai.api.tts_backends import espeak_language
assert espeak_language("") == "en-us"
......
......@@ -305,3 +305,64 @@ def test_xtts_set_matches_the_checkpoints_own_config():
if not declared:
pytest.skip('this XTTS config declares no languages')
assert sorted(T._FAMILY_LANGUAGES['coqui']) == sorted(declared)
# ── a language we advertise has to actually come out ─────────────────────────
#
# Advertising is only half the job. Probing all nine of Kokoro's languages
# through the real endpoint on 2026-10-30 found eight working and ONE failing:
# `fr` returned `espeak-ng has no such language`, because French is regioned in
# espeak (fr-fr, fr-be, fr-ch) exactly as English is. The map's own comment
# asserted the opposite -- that "it", "fr" and "de" all pass bare -- so the
# claim had never been tested. de/it/nl/pl/tr/ru/ko/ar/cs/hu/sv do pass bare;
# fr does not.
def test_french_is_regioned_like_english():
"""The regression: a bare 'fr' is what every OpenAI-compatible client
sends, and it 500ed."""
assert T.espeak_language("fr") == "fr-fr"
@pytest.mark.parametrize("code", ["en", "fr", "pt", "zh"])
def test_every_regioned_language_is_mapped(code):
"""These four are the ones espeak refuses bare."""
assert T.espeak_language(code) != code
@pytest.mark.parametrize("code", ["de", "it", "nl", "pl", "tr", "ru",
"ko", "ar", "cs", "hu", "sv"])
def test_a_bare_code_espeak_accepts_is_left_alone(code):
"""Measured: each of these works bare. Rewriting one would send espeak a
region it may not have."""
assert T.espeak_language(code) == code
@pytest.mark.parametrize("code", ["fr-fr", "fr-be", "en-gb", "pt-br"])
def test_an_explicit_region_passes_through(code):
assert T.espeak_language(code) == code
def test_a_blank_language_defaults_to_english():
assert T.espeak_language("") == "en-us"
assert T.espeak_language(None) == "en-us"
def test_case_and_underscores_are_normalised():
"""Clients send en_US and EN-GB; both name a real espeak voice."""
assert T.espeak_language("FR") == "fr-fr"
assert T.espeak_language("en_GB") == "en-gb"
def test_every_language_kokoro_advertises_resolves_to_something_espeak_takes():
"""The listing and the synthesis path must agree. Each advertised code is
either accepted bare (measured) or mapped to a region that is.
This is the invariant that was broken: `fr` was advertised through the voice
ids and rejected at synthesis.
"""
measured_bare_ok = {"es", "hi", "it", "ja", "en-gb", "en-us", "pt-br"}
for code in T.family_languages("hexgrad/Kokoro-82M"):
resolved = T.espeak_language(code)
assert resolved in measured_bare_ok or code in T._ESPEAK_REGIONLESS, (
f"Kokoro advertises {code!r} but it resolves to {resolved!r}, "
f"which was never measured against espeak")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment