feat(seedance): 两个已开通模型的限制表与提交前本地预校验(23 测试)

账号实际接入 doubao-seedance-2-5-260628 与 doubao-seedance-2-0-260128,两者限制
差异不小,且同一组参数在一个上合法、在另一个上不合法:

|            | 2.5              | 2.0                |
| 时长        | [4, 30]          | [4, 15]            |
| 分辨率      | 480p/720p/1080p  | 480p/720p/1080p/4k |
| 图生视频 ratio | **只能 adaptive** | 可指定             |
| output_format | mp4/mov        | 仅 mp4             |

超范围的请求会被厂商 400 拒绝——那要花一次往返、计入 RPM,并表现为一个失败的
任务。故在 capabilities.py 落一张限制表并在提交前本地预校验,错误信息直接指出
是哪个模型的哪条限制。

两处刻意的设计:
- **按模型族前缀匹配**而非完整 ID:尾部是日期版本(260628/260128),会随厂商
  小版本更新而变,按前缀匹配使一次升级不必改表。
- **未知模型一律放行**(只记日志):账号新开通一个模型时不该因为这张表没更新
  就用不了,否则「开通即可用」会退化成「开通还得改代码发版」。代价只是失去
  本地预校验,厂商仍会兜底。

测试 100 → 123:限制表 23 项逐条对应官方文档的一条限制,另在适配器层加 4 项
端到端断言(超范围请求的 handler 直接 assert 不该被调用,确认请求根本没发出)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-20 15:12:06 +08:00
parent db87d66403
commit 8f1d1bc5f3
4 changed files with 324 additions and 0 deletions
+12
View File
@@ -24,6 +24,7 @@ from app.domain.generation import (
)
from app.providers.base import GenerationProvider
from .capabilities import validate as validate_limits
from .client import ArkClient
from .models import (
ASSET_URL_TTL_SEC,
@@ -88,6 +89,17 @@ class SeedanceVideoProvider(GenerationProvider):
model = request.model or self._default_model
if not model:
raise ValueError("未指定模型:请求未携带 model 且 ARK_VIDEO_MODEL 未配置")
# 本地预校验:已接入的两个模型限制不同(2.5 时长到 30 秒但无 4k,2.0 有 4k
# 但时长上限 15 秒;2.5 图生视频时 ratio 锁 adaptive)。超范围的请求会被厂商
# 400 拒绝——那要花一次往返、计入 RPM,并表现为一个失败的任务。未知模型放行。
validate_limits(
model,
resolution=request.resolution,
duration_sec=request.duration_sec,
ratio=request.ratio,
has_first_frame=bool(request.input_url),
)
return SeedanceSubmission(
model=model,
prompt=request.prompt,