Repository navigation
v1.2.0 — OpenAI-compat polish sweep (8 fixes, 1 CRITICAL)
cloning, upgrade. v1.1.0 silently ignored uploaded custom_voice_file
/ speaker_wav bodies and returned default-voice audio. v1.2.0 is
the first release where adhoc cloning actually works end-to-end.
Fixed
- [CRITICAL] Adhoc voice cloning was silently disabled. The
isinstance(spec, UploadFile)check used
fastapi.datastructures.UploadFile, but Starlette's form parser
returnsstarlette.datastructures.UploadFile— distinct classes
in FastAPI 0.136+ / Starlette 1.0+. The check always returned
False,speaker_wavnever latched, the handler silently fell
through to the default voice, and the response was cached as a
regular request (X-Route: HOT,X-Cache: MISS | HITinstead of
the documentedADHOC/ADHOC). Fixed by matching either class
plus a duck-type fallback. - Bogus
custom_voice_filebodies (non-audio, empty) were
silently accepted — same root cause. Now rejected with HTTP 400
and a trimmed decode error. - JSON body without
inputraisedpydantic.ValidationError
that escaped as HTTP 500 with no body. Now caught → HTTP 422. speedrange validation. Values outside[0.25, 4.0]
(OpenAI spec) were silently accepted. Now HTTP 422.speedis now actually applied. The VoxCPM2 engine doesn't
support variable-rate synthesis natively;speed != 1.0was
silently ignored._encode_audio()now routes every output
format through an ffmpegatempofilter chain (chained for
values < 0.5 or > 2.0).cfg_valuerange validation in[0.5, 5.0](VoxCPM2 safe
range). Previously any float was accepted, allowing NaN / garbage
output from the diffusion solver. Now HTTP 422 outside the range.- HEAD /health now accepted (
@app.api_route(methods=["GET", "HEAD"])).
Load-balancer uptime probes no longer get 405s. - Opt-in
CORSMiddlewaregated onCORS_ALLOW_ORIGINSenv var
(comma-separated list or"*"). Disabled by default — API-first
deployments don't need it.
Verified
- 128-concurrent regression burst: 128/128 OK, ~12 rps.
- Adhoc voice cloning via both
custom_voice_fileandspeaker_wav
alias emitX-Route: ADHOCand generate audio in the cloned voice. speed=2.0→ ~half-duration audio;speed=0.5→ ~double-duration
(verified withffprobe).- CORS preflight + actual POST emit the expected headers when
CORS_ALLOW_ORIGINSis set. - Zero HTTP 500s in the sweep log.
Full diff
See CHANGELOG.md.