Fix voice_clone/streaming backends and POST /v1/audio/voices (port from -1 repo)
- voice_clone and streaming now return active library voices instead of probing upstream /v1/models (which only exposed 8 model entries) - Accept POST on /v1/audio/voices for clients that probe with POST - Fall back to first active voice when voice field missing in /v1/audio/speech Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c3b1cab75b
commit
8ce84e5523
@ -254,7 +254,7 @@ def _active_library_voice_options(settings: dict) -> list[dict]:
|
|||||||
|
|
||||||
def _fetch_backend_voices(settings: dict, backend: str) -> list:
|
def _fetch_backend_voices(settings: dict, backend: str) -> list:
|
||||||
backend = _clean_preview_backend(backend)
|
backend = _clean_preview_backend(backend)
|
||||||
if backend in {"nvidia_zeroshot", "nvidia_flow"}:
|
if backend in {"voice_clone", "streaming", "nvidia_zeroshot", "nvidia_flow"}:
|
||||||
return _active_library_voice_options(settings)
|
return _active_library_voice_options(settings)
|
||||||
tts_url = _validate_http_url(_preview_backend_base_url(settings, backend), allow_private=True).rstrip("/")
|
tts_url = _validate_http_url(_preview_backend_base_url(settings, backend), allow_private=True).rstrip("/")
|
||||||
key = (settings.get("voice_design_api_key") if backend == "voice_design" else settings.get("tts_api_key")) or ""
|
key = (settings.get("voice_design_api_key") if backend == "voice_design" else settings.get("tts_api_key")) or ""
|
||||||
@ -683,7 +683,7 @@ async def openai_audio_models_proxy():
|
|||||||
return await openai_models_proxy()
|
return await openai_models_proxy()
|
||||||
|
|
||||||
|
|
||||||
@router.get("/v1/audio/voices")
|
@router.api_route("/v1/audio/voices", methods=["GET", "POST"])
|
||||||
async def openai_audio_voices_proxy():
|
async def openai_audio_voices_proxy():
|
||||||
models = await openai_models_proxy()
|
models = await openai_models_proxy()
|
||||||
return [m["id"] for m in models["data"]]
|
return [m["id"] for m in models["data"]]
|
||||||
@ -706,15 +706,17 @@ async def openai_speech_proxy(request: Request):
|
|||||||
text=text, error="input is required",
|
text=text, error="input is required",
|
||||||
)
|
)
|
||||||
raise HTTPException(400, "input is required")
|
raise HTTPException(400, "input is required")
|
||||||
if not voice:
|
|
||||||
_routing_log_request(
|
|
||||||
request, status="error", app=request_app, requested_voice=original_voice,
|
|
||||||
routed_voice=voice, backend="", route=None, response_format=response_format,
|
|
||||||
text=text, error="voice is required",
|
|
||||||
)
|
|
||||||
raise HTTPException(400, "voice is required")
|
|
||||||
|
|
||||||
settings = _load_settings()
|
settings = _load_settings()
|
||||||
|
if not voice:
|
||||||
|
fallback = next((v["id"] for v in _active_library_voice_options(settings)), "")
|
||||||
|
if not fallback:
|
||||||
|
_routing_log_request(
|
||||||
|
request, status="error", app=request_app, requested_voice=original_voice,
|
||||||
|
routed_voice=voice, backend="", route=None, response_format=response_format,
|
||||||
|
text=text, error="voice is required",
|
||||||
|
)
|
||||||
|
raise HTTPException(400, "voice is required")
|
||||||
|
voice = fallback
|
||||||
voice, route = _resolve_tts_route(request_app, voice, text)
|
voice, route = _resolve_tts_route(request_app, voice, text)
|
||||||
backend = _route_backend(route, voice)
|
backend = _route_backend(route, voice)
|
||||||
style_instruction = str(data.get("instruct") or data.get("style_instruction") or "")
|
style_instruction = str(data.get("instruct") or data.get("style_instruction") or "")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user