fix(platform): AutoDL 插件 - 修复视频分辨率后缀丢失并升级插件包

This commit is contained in:
ddCat
2026-08-28 14:13:03 +08:00
parent 19ebfbb3c1
commit 8f9f326229
7 changed files with 39 additions and 7 deletions

View File

@@ -25,7 +25,7 @@ func TestAutoDLPluginArtifact(t *testing.T) {
t.Fatalf("loaded adapters = %d", len(adapters)) t.Fatalf("loaded adapters = %d", len(adapters))
} }
adapter := adapters[0] adapter := adapters[0]
if adapter.Metadata().ID != "autodl-comfyui" || adapter.Metadata().Execution != "declarative" { if adapter.Metadata().ID != "autodl-comfyui" || adapter.Metadata().Version != "1.0.1" || adapter.Metadata().Execution != "declarative" {
t.Fatalf("metadata = %#v", adapter.Metadata()) t.Fatalf("metadata = %#v", adapter.Metadata())
} }
if !adapter.Metadata().RequiresPublicMediaURLs { if !adapter.Metadata().RequiresPublicMediaURLs {
@@ -33,7 +33,7 @@ func TestAutoDLPluginArtifact(t *testing.T) {
} }
create, err := adapter.BuildCreate(context.Background(), RequestContext{BaseURL: "https://autodl.art", Request: GenerationRequest{ create, err := adapter.BuildCreate(context.Background(), RequestContext{BaseURL: "https://autodl.art", Request: GenerationRequest{
Model: "minimax_h3_lightx2v_no_pic", Prompt: "a cinematic test", Duration: 3, Resolution: "768P", Images: []MediaReference{{URL: "https://cdn.example/reference.png"}}, Model: "minimax_h3_lightx2v_no_pic", Prompt: "a cinematic test", Duration: 3, Resolution: "768", Images: []MediaReference{{URL: "https://cdn.example/reference.png"}},
}}) }})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@@ -365,6 +365,23 @@ func TestDeclarativeManifestSupportsMediaPathsTransformsAndErrors(t *testing.T)
} }
} }
func TestDeclarativeManifestNormalizesVideoResolutionWithoutBreakingWorkflowValues(t *testing.T) {
tests := map[string]string{
"768": "768p",
"768p": "768p",
"768P": "768p",
" 768P ": "768p",
"768p竖": "768p竖",
"768P横": "768p横",
"2K": "2k",
}
for input, expected := range tests {
if actual := applyManifestTransform(input, "video-resolution"); actual != expected {
t.Errorf("video resolution transform %q = %#v, want %q", input, actual, expected)
}
}
}
func TestDeclarativeManifestRequiresDocumentation(t *testing.T) { func TestDeclarativeManifestRequiresDocumentation(t *testing.T) {
manifest := Manifest{ manifest := Manifest{
APIVersion: "v1", APIVersion: "v1",

View File

@@ -10,7 +10,7 @@ AutoDL 的模型选择对应 ComfyUI 工作流 ID。不同工作流可以声明
## 参数 ## 参数
请求体为 JSON。常用字段包括 `prompt`、`duration` 和 `resolution`;实际工作流可以扩展自己的参数 schema。状态返回值位于 `data.status`,任务 ID 位于 `data.task_id`,成功结果位于 `data.results`。结果数组中的地址是短期 URL,成功后必须立即由宿主下载到影策资源存储,不能把临时地址直接写入画布长期数据。 请求体为 JSON。常用字段包括 `prompt`、`duration` 和 `resolution`;实际工作流可以扩展自己的参数 schema。插件使用 `video-resolution` 字段变换:历史状态中的纯数字 `768` 会发送为 `768p`,已经带后缀的 `768p` 以及工作流值 `768p竖`、`768p横` 保持其语义。状态返回值位于 `data.status`,任务 ID 位于 `data.task_id`,成功结果位于 `data.results`。结果数组中的地址是短期 URL,成功后必须立即由宿主下载到影策资源存储,不能把临时地址直接写入画布长期数据。
## 鉴权 ## 鉴权

View File

@@ -554,11 +554,26 @@ func applyManifestTransform(value any, transform string) any {
return strings.ToLower(text) return strings.ToLower(text)
case "upper", "uppercase": case "upper", "uppercase":
return strings.ToUpper(text) return strings.ToUpper(text)
case "video-resolution", "video_resolution", "videoresolution":
return normalizeManifestVideoResolution(text)
default: default:
return value return value
} }
} }
func normalizeManifestVideoResolution(value string) string {
normalized := strings.ToLower(strings.TrimSpace(value))
if normalized == "" {
return ""
}
for _, char := range normalized {
if char < '0' || char > '9' {
return normalized
}
}
return normalized + "p"
}
func pathValue(payload map[string]any, path string) any { func pathValue(payload map[string]any, path string) any {
var value any = payload var value any = payload
for _, part := range strings.Split(strings.Trim(path, "."), ".") { for _, part := range strings.Split(strings.Trim(path, "."), ".") {

View File

@@ -2,10 +2,10 @@
"apiVersion": "yingce.plugin/v1", "apiVersion": "yingce.plugin/v1",
"id": "autodl-comfyui", "id": "autodl-comfyui",
"name": "AutoDL ComfyUI 视频", "name": "AutoDL ComfyUI 视频",
"version": "1.0.0", "version": "1.0.1",
"author": "影策社区", "author": "影策社区",
"description": "通过 AutoDL.Art ComfyUI 工作流 API 接入异步视频生成。", "description": "通过 AutoDL.Art ComfyUI 工作流 API 接入异步视频生成。",
"documentation": "# AutoDL ComfyUI 视频\n\n## 接口\n\n创建任务:`POST /api/v1/comfyui/comfyui_workflow/{workflow_id}`。清单把渠道中的模型字段作为 `workflow_id`,因此每个 ComfyUI 工作流都可以通过工作流贡献加入,不需要修改宿主代码。\n\n查询任务:`GET /api/v1/comfyui/comfyui_workflow/result/{task_id}`。\n\n## 工作流\n\n示例 `minimax_h3_lightx2v_no_pic` 作为 MiniMax H3 文生视频入口,默认时长为 5 秒、分辨率为 `768p竖`。支持 `480p竖`、`768p竖`、`480p横`、`768p横`。上传后可以在渠道中直接选择该工作流;新增工作流只需扩展本清单。\n\n## 请求与鉴权\n\n创建请求为 JSON,发送 `prompt`、`duration`、`resolution`,并按存在的参考图片发送 `ref_image_0` 至 `ref_image_8`。分辨率字段由插件在发送前统一转换为小写。参考图片由宿主转换为短期签名公网 URL。AutoDL Token 在渠道密钥字段中配置,宿主以后端出站请求发送 `Authorization: Bearer <token>`;清单不包含密钥。\n\n## 状态与结果\n\n`QUEUED` 和 `RUNNING` 映射为统一任务的排队与处理中,`SUCCESS` 和 `completed` 映射为成功,`FAILED` 映射为失败。错误响应的 `code` 和 `msg` 会保留为任务错误。成功结果从 `data.results[].url` 读取为视频地址。AutoDL 地址是短期地址,清单标记为临时结果,宿主会在完成时下载并保存到影策资源存储。\n\n官方文档:[AutoDL ComfyUI API](https://autodl.art/docs/comfyui_api/)。", "documentation": "# AutoDL ComfyUI 视频\n\n## 接口\n\n创建任务:`POST /api/v1/comfyui/comfyui_workflow/{workflow_id}`。清单把渠道中的模型字段作为 `workflow_id`,因此每个 ComfyUI 工作流都可以通过工作流贡献加入,不需要修改宿主代码。\n\n查询任务:`GET /api/v1/comfyui/comfyui_workflow/result/{task_id}`。\n\n## 工作流\n\n示例 `minimax_h3_lightx2v_no_pic` 作为 MiniMax H3 文生视频入口,默认时长为 5 秒、分辨率为 `768p竖`。支持 `480p竖`、`768p竖`、`480p横`、`768p横`。上传后可以在渠道中直接选择该工作流;新增工作流只需扩展本清单。\n\n## 请求与鉴权\n\n创建请求为 JSON,发送 `prompt`、`duration`、`resolution`,并按存在的参考图片发送 `ref_image_0` 至 `ref_image_8`。分辨率字段由插件在发送前统一 trim 并转换为小写;纯数字值会自动补上 `p`,因此 `768` 与 `768p` 都会发送为 `768p`,`768p竖`、`768p横` 等工作流值保持不变。参考图片由宿主转换为短期签名公网 URL。AutoDL Token 在渠道密钥字段中配置,宿主以后端出站请求发送 `Authorization: Bearer <token>`;清单不包含密钥。\n\n## 状态与结果\n\n`QUEUED` 和 `RUNNING` 映射为统一任务的排队与处理中,`SUCCESS` 和 `completed` 映射为成功,`FAILED` 映射为失败。错误响应的 `code` 和 `msg` 会保留为任务错误。成功结果从 `data.results[].url` 读取为视频地址。AutoDL 地址是短期地址,清单标记为临时结果,宿主会在完成时下载并保存到影策资源存储。\n\n官方文档:[AutoDL ComfyUI API](https://autodl.art/docs/comfyui_api/)。",
"permissions": [ "permissions": [
"generation.run", "generation.run",
"media.read" "media.read"
@@ -70,7 +70,7 @@
"fields": { "fields": {
"prompt": "request.prompt", "prompt": "request.prompt",
"duration": "request.duration", "duration": "request.duration",
"resolution": "request.resolution|lower", "resolution": "request.resolution|video-resolution",
"ref_image_0": "request.images.0.url", "ref_image_0": "request.images.0.url",
"ref_image_1": "request.images.1.url", "ref_image_1": "request.images.1.url",
"ref_image_2": "request.images.2.url", "ref_image_2": "request.images.2.url",

View File

@@ -65,7 +65,7 @@ my-plugin.yingce-plugin
## 4. Provider 与工作流 ## 4. Provider 与工作流
请求字段右侧只能引用影策统一请求,例如 `request.prompt`、`request.model`、`request.duration`、`request.extra`。声明式字段也支持安全的对象/数组路径(例如 `request.images.0.url`)和字符串变换(`|trim`、`|lower`、`|upper`),不执行插件代码。字段解析为空时会省略该字段,适合映射可选参考素材。Provider 如果把 `requiresPublicMediaUrls` 设为 `true`,宿主会在请求前把用户资源转换为短期签名公网 URL。响应映射支持对象路径和数组下标,并可用 `errorPaths` 声明上游错误码路径。同步 provider 只需要 `create` 和 `response`;异步 provider 再声明 `poll`。 请求字段右侧只能引用影策统一请求,例如 `request.prompt`、`request.model`、`request.duration`、`request.extra`。声明式字段也支持安全的对象/数组路径(例如 `request.images.0.url`)和字符串变换(`|trim`、`|lower`、`|upper`、`|video-resolution`),不执行插件代码。`video-resolution` 会 trim 并转为小写,仅在输入是纯数字时补上 `p`,因此同时兼容历史状态中的 `768`、标准值 `768p` 和工作流值 `768p竖`。字段解析为空时会省略该字段,适合映射可选参考素材。Provider 如果把 `requiresPublicMediaUrls` 设为 `true`,宿主会在请求前把用户资源转换为短期签名公网 URL。响应映射支持对象路径和数组下标,并可用 `errorPaths` 声明上游错误码路径。同步 provider 只需要 `create` 和 `response`;异步 provider 再声明 `poll`。
结果 URL 如果是短期地址,必须设置 `resultEphemeral: true`。宿主会在任务完成后立即下载并保存资源,画布和任务记录只保存影策资源引用。 结果 URL 如果是短期地址,必须设置 `resultEphemeral: true`。宿主会在任务完成后立即下载并保存资源,画布和任务记录只保存影策资源引用。