fix: gate video models by runtime availability

This commit is contained in:
2026-06-03 17:48:49 +08:00
parent d038f1b2f4
commit ff0bfaa8b2
8 changed files with 109 additions and 32 deletions

View File

@@ -1524,6 +1524,8 @@ def video_api_key(model: str | None = None) -> str:
if "xai" in VIDEO_API_BASE_URL.lower() and VIDEO_API_KEY:
return VIDEO_API_KEY
return ""
if VIDEO_API_BASE_URL:
return VIDEO_API_KEY
if VIDEO_API_KEY:
return VIDEO_API_KEY
if video_uses_poe():
@@ -5145,6 +5147,8 @@ def video_model_options() -> list[dict]:
if key not in VIDEO_MODEL_ALIASES:
continue
model = VIDEO_MODEL_ALIASES[key]
if not _video_alias_can_use_current_gateway(key, model):
continue
if model in seen_models:
continue
seen_models.add(model)
@@ -5162,7 +5166,10 @@ def video_model_options() -> list[dict]:
"available": bool(video_api_key(model)),
})
default_model = resolve_video_model(VIDEO_MODEL)
if not any(item["id"] == VIDEO_MODEL or item["model"] == default_model for item in options):
if (
_video_alias_can_use_current_gateway(VIDEO_MODEL, default_model)
and not any(item["id"] == VIDEO_MODEL or item["model"] == default_model for item in options)
):
options.insert(0, {
"id": VIDEO_MODEL,
"label": label_map.get(VIDEO_MODEL, VIDEO_MODEL),
@@ -5179,6 +5186,41 @@ def video_model_options() -> list[dict]:
return options
def _video_model_is_doubao_seedance(model: str | None) -> bool:
value = (model or "").strip().lower()
return value.startswith("doubao-seedance")
def _video_alias_can_use_current_gateway(alias: str | None, model: str | None) -> bool:
key = (alias or "").strip().lower()
concrete = (model or "").strip()
concrete_lower = concrete.lower()
if is_xai_video_model(concrete):
return key in {"xai", "grok_imagine_video", "grok-imagine-video"} or concrete_lower == (XAI_VIDEO_MODEL or "").lower()
if video_uses_poe():
return not concrete_lower.startswith("doubao-")
if video_uses_ark(concrete):
return _video_model_is_doubao_seedance(concrete)
default_model = resolve_video_model(VIDEO_MODEL)
return concrete == default_model or key == (VIDEO_MODEL or "").strip().lower()
def ensure_video_model_available(raw: str | None) -> str:
model = resolve_video_model(raw)
requested = (raw or VIDEO_MODEL or "").strip().lower()
matches = [
item for item in video_model_options()
if item.get("available") is not False
and (
str(item.get("id") or "").strip().lower() == requested
or str(item.get("model") or "").strip() == model
)
]
if not matches:
raise HTTPException(400, "当前视频模型未接入或未配置,请选择 Seedance 2.0 Fast 或 Grok Imagine Video")
return model
def _image_failure_can_fallback(status_code: int, body: str, last_err: str) -> bool:
if status_code in (400, 401, 403, 404):
return False
@@ -9428,7 +9470,7 @@ def _enqueue_storyboard_videos(job: Job, frame: KeyFrame, req: GenerateStoryboar
reference_ref_paths.append(p)
seen_ref_paths.add(key)
model = resolve_video_model(req.model)
model = ensure_video_model_available(req.model)
ensure_video_api_configured(model)
seconds = video_seconds(float(req.duration or 4), model)
video_size = _normalize_video_size(req.size, model)