Raises docstring coverage on the changed files past the threshold the PR
check enforces; the reasoning each test carried in a leading comment now
lives where the checker and a reader both find it.
resolve_kokoro_lang_code validates against mlx-audio's own LANG_CODES —
its docstring is explicit that the vendored table is the only source of
truth — but built the "Kokoro supports: …" list in the rejection message
from the hardcoded _KOKORO_ISO_BY_FULL_NAME instead.
That map exists to translate full names into Kokoro's codes, and it has
no entry that produces "b". British English is reachable as en-gb, and
the existing test asserts resolve("en-gb") == "b", yet the message never
mentioned it: the installed table lists nine languages and the message
named eight. Any language a later mlx-audio adds would be dropped the
same way, telling a user to switch engines when they need not.
Derives the labels from ALIASES and LANG_CODES instead, preferring the
full name a caller can actually pass and falling back to the table's own
description for codes no full name reaches.
The derivation takes the tables as arguments, so its tests run on every
platform. The resolution tests around it need the Apple-Silicon-only
package and skip on every CI runner, which is why a message drifting
from the table it documents went unnoticed.
Fixes#2156
Installing a gated model failed the fast download path with "401
Unauthorized" even with a valid token and the licence accepted, then fell
back to snapshot_download and logged a 401 that reads like the token or
the licence grant is at fault when it is neither (#2163).
`token_resolver.resolve()` returns a ResolvedToken record, not the bearer
string. Two call sites handed that record straight to consumers typed
`token: str | None`, and both fail silently rather than loudly:
- `_segmented_snapshot` passes it to HfApi, get_hf_file_metadata and our
own segmented_download. huggingface_hub's build_hf_headers ignores a
non-str token and falls back to its own ambient discovery, so a token
held only in VoiceStudio's Settings produces NO Authorization header
and every gated file 401s. segmented_download instead interpolates it
into `f"Bearer {token}"`, sending a malformed header that also inlines
the raw secret into the request.
- `_step_fetch_weights` passes it to snapshot_download, so gated engine
weights 401 the same way.
Every other resolve() caller already unwraps `.token`; these two were the
outliers. Both now unwrap once, at the seam.
The existing weights tests all stubbed resolve() to return None, so no
test ever exercised a resolved token — which is why this went unnoticed.
The new tests drive a real ResolvedToken through both seams and assert a
`str` reaches every consumer, plus an integration test that installs the
pyannote diarisation pipeline end to end: a weightless config_only repo
validates, both dependency repos are fetched, and every call carries the
bearer string.
Two catalogue invariants keep the rest of #2163 from returning by edit:
dependency repos must be revision-pinned (revision_for raises otherwise,
so an unpinned one ships an always-failing install), and a config_only
entry must declare config_required_files (without them the completeness
check can never pass and the error lists no files at all — the shape the
report hit on 0.5.2).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>