diff --git a/backend/internal/protocol/lxmone_video_test.go b/backend/internal/protocol/lxmone_video_test.go new file mode 100644 index 000000000..2cd4ef818 --- /dev/null +++ b/backend/internal/protocol/lxmone_video_test.go @@ -0,0 +1,51 @@ +package protocol + +import ( + "context" + "encoding/json" + "testing" +) + +func TestOfficialLxmoneVideoResultURLs(t *testing.T) { + providers := []string{ + "lxmone-wan-videos", "lxmone-wan-channel-s", "lxmone-seedance-videos", "lxmone-h3-max-videos", + "lxmone-sd-videos", "lxmone-sd-mini-videos", "lxmone-grok-videos", "lxmone-h3-workflow", + } + const directURL = "https://cdn.example.com/generated.mp4?signature=test" + for _, provider := range providers { + t.Run(provider, func(t *testing.T) { + adapter := officialPackageAdapter(t, "lxmone-video-suite.yingce-plugin", provider) + for _, tc := range []struct { + name string + payload map[string]any + }{ + {"direct_over_relative", map[string]any{"id": "video-test", "status": "completed", "metadata": map[string]any{"url": "/v1/videos/video-test/content", "direct_url": directURL}}}, + {"nested_direct_over_relative", map[string]any{"metadata": map[string]any{"url": "/v1/videos/video-test/content"}, "data": map[string]any{"id": "video-test", "status": "completed", "metadata": map[string]any{"url": "/v1/videos/video-test/content", "direct_url": directURL}}}}, + {"absolute_url_without_direct", map[string]any{"id": "video-test", "status": "completed", "metadata": map[string]any{"url": directURL}}}, + } { + t.Run(tc.name, func(t *testing.T) { + body, err := json.Marshal(tc.payload) + if err != nil { + t.Fatal(err) + } + created, err := adapter.ParseCreate(context.Background(), body) + if err != nil { + t.Fatal(err) + } + polled, err := adapter.ParsePoll(context.Background(), PollContext{TaskID: "video-test"}, body) + if err != nil { + t.Fatal(err) + } + if created.Status != StatusSucceeded || polled.Status != StatusSucceeded || created.TaskID != "video-test" || polled.TaskID != "video-test" { + t.Fatalf("unexpected completion: create=%#v poll=%#v", created, polled) + } + for _, result := range []*Result{created.Result, polled.Result} { + if result == nil || len(result.Videos) != 1 || result.Videos[0].URL != directURL { + t.Fatalf("expected direct download URL, got %#v", result) + } + } + }) + } + }) + } +} diff --git a/docs/content/docs/progress/pending-test.mdx b/docs/content/docs/progress/pending-test.mdx index 96b428b40..e311933da 100644 --- a/docs/content/docs/progress/pending-test.mdx +++ b/docs/content/docs/progress/pending-test.mdx @@ -17,6 +17,20 @@ description: 当前项目已实现功能的手工验证清单与未确认边界 - [x] 修复已在部署预览版验证:从设置页返回画布列表后,菜单背景和圆角保持正常;深浅主题的卡片操作菜单及浅色排序菜单验证通过。 - [ ] 上游集成后复核设置页与其他工作台页面之间的导航。 +## 万有引力视频结果地址 + +- 已修复:万有引力视频套件更新为 `1.0.1`,8 个协议优先读取 `metadata.direct_url` / `data.metadata.direct_url`,避免完成响应中的相对 `metadata.url` 遮蔽完整视频地址。保留已有完整 URL 回退,宿主下载与 SSRF 校验不变;源码、内嵌接口文档和插件归档同步更新。 +- [x] 真实插件归档的 24 组响应回归通过,覆盖创建 / 轮询完成、顶层 / data 内直链优先以及完整 URL 回退;官方插件归档完整性检查通过。 +- [x] 修复插件已部署并验证运行时注册版本与归档一致,后端就绪及 API 代理检查通过。从失败任务已记录的完整地址取回 MP4,未发起新的上游生成,也未修改原失败任务与账务状态。 +- [ ] 真实创作台新视频任务验证下载、资源转存与结果展示。原失败任务取回的视频保存在受限本地缓存,未自动回填到会话。 + +## 创作台视频同步音频参数 + +- 已修复:创作台视频报价、提交和重试共用按所选模型能力整理的配置。不支持同步音频或水印时使用 `false`,支持时遵循模型默认值,不再把全局 `videoGenerateAudio=true` 当成用户请求;模型筛选只使用创作台实际可选的参数。 +- [x] 创作台请求配置、模型能力与报价相关的 32 项专项测试通过,前端类型检查通过;覆盖无声视频的报价 / 任务参数、重试元数据以及支持音频时的模型默认值。 +- [x] 前端生产构建通过,修复镜像已部署;首页、创作台路由、入口资源和创作台脚本与本次构建逐字节一致,容器健康与 API 就绪检查通过。构建仍提示部分 chunk 超过 500 kB。 +- [ ] 在真实创作台使用万有引力渠道的 `minimax-h3-a`,输入“小猫在流泪”,选择 `16:9`、`480P`,检查报价、首次生成和失败后重试;同时确认支持同步音频的模型遵循各自默认值。本次不调用真实上游,生成结果仍待验收。 + ## 多模态列表与分镜表合并回归 - [x] 合入 PR #549 的图片 / 视频列表分析、动态表格、视频脚本转换和批量生成设置;参考图上限前后端统一为 10。保留本地主分支表格布局、参考图提及、删除列、结果定位、手工行增量同步及单行重新生成。 diff --git a/plugin-packages/lxmone-video-suite.yingce-plugin b/plugin-packages/lxmone-video-suite.yingce-plugin index 3bcb96aab..fcaf82570 100644 Binary files a/plugin-packages/lxmone-video-suite.yingce-plugin and b/plugin-packages/lxmone-video-suite.yingce-plugin differ diff --git a/plugin-packages/lxmone-video-suite/docs/interface.md b/plugin-packages/lxmone-video-suite/docs/interface.md index 840b17305..ae646309b 100644 --- a/plugin-packages/lxmone-video-suite/docs/interface.md +++ b/plugin-packages/lxmone-video-suite/docs/interface.md @@ -85,10 +85,15 @@ 轮询时按 `status`、`state`、`data.status` 取状态,`completed`/`succeeded` 归一为 `succeeded`, `failed`/`expired`/`error` 归一为 `failed`,其余按进行中处理。 -视频地址按 `metadata.url`、`metadata.video_url`、`video_url`、`videoUrl`、`result_url`、`url`、 +视频地址优先取 `metadata.direct_url`、`data.metadata.direct_url`,再按 +`metadata.url`、`metadata.video_url`、`video_url`、`videoUrl`、`result_url`、`url`、 `data.metadata.url`、`data.video_url`、`output.url` 依次取值;上游返回的是临时地址 (`resultEphemeral`),由宿主立即下载并转存为项目资源。 +H3 工作流完成响应可能同时包含相对路径 `metadata.url` 和完整 HTTPS 地址 +`metadata.direct_url`,必须优先选择后者,避免把缺少主机的路径交给外部资源下载器。 +下载仍执行宿主的地址与 SSRF 校验。 + 错误信息取 `error.message`、`message`、`fail_reason`,错误码路径为 `error.message` 与 `error.code`。 HTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结束并把上游原文回传给用户。 @@ -102,7 +107,7 @@ HTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结 "apiVersion": "yingce.plugin/v2", "id": "lxmone-video-suite", "name": "万有引力视频套件", - "version": "1.0.0", + "version": "1.0.1", "author": "Yingce / 万有引力", "description": "万有引力(lxmone.xyz)视频协议套件:Wan 3.0(现有渠道与 S 渠道)、Seedance 2 / 2.5、SD 2.0 / 2.5 / Mini、Grok Imagine、MiniMax H3(Max 与 A-E 独立工作流)。", "permissions": [ @@ -360,6 +365,12 @@ HTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结 }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -648,6 +659,12 @@ HTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结 }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -912,6 +929,12 @@ HTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结 }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -1176,6 +1199,12 @@ HTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结 }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -1440,6 +1469,12 @@ HTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结 }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -1721,6 +1756,12 @@ HTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结 }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -2013,6 +2054,12 @@ HTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结 }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -2347,6 +2394,12 @@ HTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结 }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, diff --git a/plugin-packages/lxmone-video-suite/manifest.json b/plugin-packages/lxmone-video-suite/manifest.json index 595bf4887..7f275ac7a 100644 --- a/plugin-packages/lxmone-video-suite/manifest.json +++ b/plugin-packages/lxmone-video-suite/manifest.json @@ -2,7 +2,7 @@ "apiVersion": "yingce.plugin/v2", "id": "lxmone-video-suite", "name": "万有引力视频套件", - "version": "1.0.0", + "version": "1.0.1", "author": "Yingce / 万有引力", "description": "万有引力(lxmone.xyz)视频协议套件:Wan 3.0(现有渠道与 S 渠道)、Seedance 2 / 2.5、SD 2.0 / 2.5 / Mini、Grok Imagine、MiniMax H3(Max 与 A-E 独立工作流)。", "permissions": [ @@ -260,6 +260,12 @@ }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -548,6 +554,12 @@ }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -812,6 +824,12 @@ }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -1076,6 +1094,12 @@ }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -1340,6 +1364,12 @@ }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -1621,6 +1651,12 @@ }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -1913,6 +1949,12 @@ }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -2247,6 +2289,12 @@ }, "videos": { "$coalesce": [ + { + "$ref": "response.metadata.direct_url" + }, + { + "$ref": "response.data.metadata.direct_url" + }, { "$ref": "response.metadata.url" }, @@ -2285,5 +2333,5 @@ } ] }, - "documentation": "# 万有引力视频套件(lxmone.xyz)\n\n该目录是万有引力中转站(`https://lxmone.xyz/v1`)视频协议的官方声明式插件源码。\n后端从生成的 `lxmone-video-suite.yingce-plugin` 包加载,不依赖系统内置 `host:` 适配器。\n\n协议按中转站公开接口文档 `https://lxmone.xyz/docs/` 的 `/v1/videos` 与 `/v1/videos/generations`\n两套请求体形状编写,拆成 8 个 provider,覆盖该站点当前开放的全部视频模型:\n\n| Provider ID | 覆盖模型 | 创建接口 |\n| --- | --- | --- |\n| `lxmone-wan-videos` | `wan3.0-video`、`wan3.0-video-prime` | `POST /v1/videos` |\n| `lxmone-wan-channel-s` | `wan3.0-video-s`、`wan3.0-video-prime-s` | `POST /v1/videos` |\n| `lxmone-seedance-videos` | `seedance-2-pro/fast/mini`、`seedance-2.5-pro`、`seedance2.0-a`~`seedance2.0-f`、`seedance2.5-a` | `POST /v1/videos` |\n| `lxmone-h3-max-videos` | `minimax-h3-max` | `POST /v1/videos` |\n| `lxmone-sd-videos` | `sd-2.0-a`、`sd-2.0-b`、`sd-2.0-c`、`sd-2.5-a`、`sd-2.5` | `POST /v1/videos` |\n| `lxmone-sd-mini-videos` | `sd-mini` | `POST /v1/videos` |\n| `lxmone-grok-videos` | `grok-imagine-video`、`grok-imagine-video-1.5`、`grok-imagine-video-1.5S` | `POST /v1/videos/generations` |\n| `lxmone-h3-workflow` | `minimax-h3-a`~`minimax-h3-e` | `POST /v1/videos/generations` |\n\n完整字段、请求模板与响应映射见 [docs/interface.md](docs/interface.md)。\n\n## 构建\n\n```sh\nnode plugin-packages/embed-documentation.mjs lxmone-video-suite\nsh plugin-packages/build-packages.sh\n```\n\n---\n\n# 万有引力视频套件接口字段\n\n## 协议身份\n\n- 插件 ID:`lxmone-video-suite`。\n- 能力:`video`。\n- 默认 Base URL:`https://lxmone.xyz/v1`。\n- 鉴权驱动:`bearer`。\n- 创建接口:`POST /v1/videos` 或 `POST /v1/videos/generations`(按模型所属 provider 决定)。\n- 查询接口:`GET /v1/videos/{{taskId}}` 或 `GET /v1/videos/generations/{{taskId}}`。\n- 参考媒体要求公开可访问的 HTTPS URL(`requiresPublicMediaUrls`)。\n\n以上形状来自中转站公开文档 `https://lxmone.xyz/docs/`:同一批模型的 `model`、`prompt`、时长、\n分辨率与画幅字段名在不同渠道并不一致,因此按上游请求体拆成 8 个 provider,而不是一个通用协议。\n\n## 配置字段\n\n| 字段 | 类型 | 必填 | 含义 |\n| --- | --- | --- | --- |\n| `apiKey` | secret | 是 | 万有引力中转站的 API Key,随请求发送 `Authorization: Bearer `。 |\n\n## 统一字段映射\n\n宿主向插件提交统一的视频生成请求,插件按 provider 映射到上游字段:\n\n| 统一字段 | 类型 | 必填 | 上游映射 | 说明 |\n| --- | --- | --- | --- | --- |\n| `model` | string | 是 | `model` | 上游模型 ID,透传,不做改名或别名。 |\n| `prompt` | string | 是 | `prompt` / `input.prompt` | 视频提示词。 |\n| `images` | media[] | 否 | `reference_images` / `images` / `image_url` / `input.media[]` / `input_reference` | 参考图;带 role 的 `first_frame`、`last_frame` 会落到支持首尾帧的 provider 专属字段。 |\n| `videos` | media[] | 否 | `reference_videos` / `videos` / `input.media[]` | 参考视频。 |\n| `audios` | media[] | 否 | `reference_audios` / `audio` / `audio_urls` / `input.media[]` | 参考音频。 |\n| `duration` | integer | 否 | `seconds` / `duration` / `duration_seconds` | 时长秒数;缺省由各 provider 填默认值。 |\n| `aspectRatio` | string | 否 | `aspect_ratio` / `parameters.ratio` | 画幅比例,默认 `16:9`。 |\n| `resolution` | string | 否 | `resolution` / `size` / `parameters.resolution` | 分辨率档位;上游要求大写 `720P` 形式的 provider 会自动转换。 |\n| `generateAudio` | boolean | 否 | `audio` / `generate_audio` | 是否生成或保留音频。 |\n\n## 各 provider 的创建体\n\n### `lxmone-wan-videos`(`wan3.0-video`、`wan3.0-video-prime`)\n\n`POST /v1/videos`,顶层字段:`model`、`prompt`、`seconds`、`size`、`aspect_ratio`、\n`reference_images[{url, role}]`、`reference_videos[]`、`reference_audios[]`、`prompt_extend`。\n\n### `lxmone-wan-channel-s`(`wan3.0-video-s`、`wan3.0-video-prime-s`)\n\n`POST /v1/videos`,`input.media[{type, url}]` 与 `input.prompt`,参数放在\n`parameters{resolution, ratio, duration, audio, prompt_extend}`。\n\n### `lxmone-seedance-videos`(`seedance-2-pro/fast/mini`、`seedance-2.5-pro`、`seedance2.0-a`~`f`、`seedance2.5-a`)\n\n`POST /v1/videos`,字段:`model`、`prompt`、`duration_seconds`、`resolution`、`aspect_ratio`、\n`reference_images[]`、`reference_videos[]`、`reference_audios[]`。\n\n### `lxmone-h3-max-videos`(`minimax-h3-max`)\n\n官方文档要求 H3 Max 走 `POST /v1/videos`(不要提交到 `/v1/videos/generations`,也要避开\n`input_reference` 与 `audio` 这组独立工作流字段),字段为:`model`、`prompt`、`seconds`、\n`resolution`、`aspect_ratio`、`reference_images[]`、`reference_videos[]`、`reference_audios[]`。\n上游把客户端传入的 720p 映射为 768p,参考素材上限为图 / 视频 / 音频各 12 段。\n\n### `lxmone-sd-videos`(`sd-2.0-a`、`sd-2.0-b`、`sd-2.0-c`、`sd-2.5-a`、`sd-2.5`)\n\n`POST /v1/videos`,字段:`model`、`prompt`、`duration`、`resolution`、`aspect_ratio`、\n`images[]`、`videos[]`、`audio[]`。\n\n### `lxmone-sd-mini-videos`(`sd-mini`)\n\n`POST /v1/videos`,字段:`model`、`prompt`、`seconds`、`resolution`、`aspect_ratio`、\n`image_url`、`reference_image_urls[]`、`audio_urls[]`。\n\n### `lxmone-grok-videos`(`grok-imagine-video`、`grok-imagine-video-1.5`、`grok-imagine-video-1.5S`)\n\n`POST /v1/videos/generations`,字段:`model`、`prompt`、`duration`、`aspect_ratio`、`resolution`、\n`generate_audio`,以及互斥的 `image{url}`(首帧)或 `reference_images[{url}]`(参考图)。\n\n### `lxmone-h3-workflow`(`minimax-h3-a`~`minimax-h3-e`)\n\n`POST /v1/videos/generations`,字段:`model`、`prompt`、`seconds`、`resolution`、`aspect_ratio`、\n`input_reference[]`、`first_frame`、`last_frame`、`audio`。\n\n## 响应与错误\n\n创建成功后,插件从上游响应里按顺序取 `id`、`task_id`、`taskId`、`data.id` 得到统一 `taskId`,\n轮询时按 `status`、`state`、`data.status` 取状态,`completed`/`succeeded` 归一为 `succeeded`,\n`failed`/`expired`/`error` 归一为 `failed`,其余按进行中处理。\n\n视频地址按 `metadata.url`、`metadata.video_url`、`video_url`、`videoUrl`、`result_url`、`url`、\n`data.metadata.url`、`data.video_url`、`output.url` 依次取值;上游返回的是临时地址\n(`resultEphemeral`),由宿主立即下载并转存为项目资源。\n\n错误信息取 `error.message`、`message`、`fail_reason`,错误码路径为 `error.message` 与 `error.code`。\nHTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结束并把上游原文回传给用户。\n\n\n## Manifest 完整接口定义\n\n以下 JSON 与插件包内实际 `manifest.json` 逐字段一致,覆盖插件身份、权限、配置、鉴权、参数、校验、创建、Agent、查询、取消、结果下载、响应和 Agent 响应映射。`documentation` 字段的值就是当前完整文档;为避免文档在自身内部无限递归,JSON 中仅用等义占位文本表示正文。\n\n```json\n{\n \"apiVersion\": \"yingce.plugin/v2\",\n \"id\": \"lxmone-video-suite\",\n \"name\": \"万有引力视频套件\",\n \"version\": \"1.0.0\",\n \"author\": \"Yingce / 万有引力\",\n \"description\": \"万有引力(lxmone.xyz)视频协议套件:Wan 3.0(现有渠道与 S 渠道)、Seedance 2 / 2.5、SD 2.0 / 2.5 / Mini、Grok Imagine、MiniMax H3(Max 与 A-E 独立工作流)。\",\n \"permissions\": [\n \"generation.run\",\n \"media.read\"\n ],\n \"configuration\": {\n \"fields\": [\n {\n \"name\": \"apiKey\",\n \"type\": \"secret\",\n \"label\": \"API Key\",\n \"required\": true\n }\n ]\n },\n \"contributes\": {\n \"providers\": [\n {\n \"id\": \"lxmone-wan-videos\",\n \"label\": \"万有引力 Wan 3.0 视频(现有渠道)\",\n \"description\": \"wan3.0-video / wan3.0-video-prime:POST /v1/videos,顶层 reference_images、reference_videos、reference_audios。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"seconds\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 10\n }\n },\n \"size\": {\n \"$coalesce\": [\n {\n \"$upper\": {\n \"$ref\": \"request.resolution\"\n }\n },\n \"720P\"\n ]\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"reference_images\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"url\": {\n \"$ref\": \"media.value\"\n },\n \"role\": {\n \"$coalesce\": [\n {\n \"$ref\": \"media.role\"\n },\n \"reference_image\"\n ]\n }\n }\n }\n }\n },\n \"reference_videos\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.videos\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"reference_audios\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"prompt_extend\": false\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-wan-channel-s\",\n \"label\": \"万有引力 Wan 3.0 视频(S 渠道)\",\n \"description\": \"wan3.0-video-s / wan3.0-video-prime-s:POST /v1/videos,原生 input.media 与 parameters。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"input\": {\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"media\": {\n \"$omitEmpty\": {\n \"$concatArrays\": [\n {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"type\": {\n \"$coalesce\": [\n {\n \"$ref\": \"media.role\"\n },\n \"reference_image\"\n ]\n },\n \"url\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.videos\"\n },\n \"as\": \"media\",\n \"in\": {\n \"type\": \"reference_video\",\n \"url\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"type\": \"reference_audio\",\n \"url\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n ]\n }\n }\n },\n \"parameters\": {\n \"resolution\": {\n \"$coalesce\": [\n {\n \"$upper\": {\n \"$ref\": \"request.resolution\"\n }\n },\n \"720P\"\n ]\n },\n \"ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"duration\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"audio\": {\n \"$ref\": \"request.generateAudio\"\n },\n \"prompt_extend\": false\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-seedance-videos\",\n \"label\": \"万有引力 Seedance 视频\",\n \"description\": \"seedance-2-pro/fast/mini、seedance-2.5-pro、seedance2.0-a~f、seedance2.5-a。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"duration_seconds\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"720p\"\n ]\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"reference_images\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"reference_videos\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.videos\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"reference_audios\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-h3-max-videos\",\n \"label\": \"万有引力 MiniMax H3 Max 视频\",\n \"description\": \"minimax-h3-max:POST /v1/videos,seconds、resolution 与 reference_images、reference_videos、reference_audios 扁平 URL 数组。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"seconds\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"768p\"\n ]\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"reference_images\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"reference_videos\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.videos\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"reference_audios\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-sd-videos\",\n \"label\": \"万有引力 SD 视频\",\n \"description\": \"sd-2.0-a/b/c、sd-2.5-a、sd-2.5:POST /v1/videos,duration 与 images、videos、audio 数组。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"duration\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"720p\"\n ]\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"images\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"videos\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.videos\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"audio\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-sd-mini-videos\",\n \"label\": \"万有引力 SD Mini 视频\",\n \"description\": \"sd-mini:POST /v1/videos,主图 image_url、额外参考图 reference_image_urls、音频 audio_urls。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"seconds\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"720p\"\n ]\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"image_url\": {\n \"$omitEmpty\": {\n \"$first\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n },\n \"reference_image_urls\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$filter\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"where\": {\n \"$gt\": [\n {\n \"$ref\": \"media.order\"\n },\n 0\n ]\n }\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"audio_urls\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-grok-videos\",\n \"label\": \"万有引力 Grok Imagine 视频\",\n \"description\": \"grok-imagine-video / 1.5 / 1.5S:POST /v1/videos/generations,duration、image、reference_images。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos/generations\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"duration\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 6\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"720p\"\n ]\n }\n },\n \"image\": {\n \"$omitEmpty\": {\n \"$if\": {\n \"condition\": {\n \"$eq\": [\n {\n \"$len\": {\n \"$ref\": \"request.images\"\n }\n },\n 1\n ]\n },\n \"then\": {\n \"url\": {\n \"$first\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n },\n \"else\": null\n }\n }\n },\n \"reference_images\": {\n \"$omitEmpty\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$len\": {\n \"$ref\": \"request.images\"\n }\n },\n 1\n ]\n },\n \"then\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"url\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"else\": null\n }\n }\n },\n \"generate_audio\": {\n \"$ref\": \"request.generateAudio\"\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/generations/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-h3-workflow\",\n \"label\": \"万有引力 MiniMax H3 工作流\",\n \"description\": \"minimax-h3-a~e:POST /v1/videos/generations,input_reference、first_frame、last_frame、audio。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos/generations\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"seconds\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"720p\"\n ]\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"input_reference\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$filter\": {\n \"from\": {\n \"$ref\": \"request.images\"\n },\n \"as\": \"media\",\n \"where\": {\n \"$and\": [\n {\n \"$ne\": [\n {\n \"$ref\": \"media.role\"\n },\n \"first_frame\"\n ]\n },\n {\n \"$ne\": [\n {\n \"$ref\": \"media.role\"\n },\n \"last_frame\"\n ]\n }\n ]\n }\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"first_frame\": {\n \"$omitEmpty\": {\n \"$first\": {\n \"$map\": {\n \"from\": {\n \"$filter\": {\n \"from\": {\n \"$ref\": \"request.images\"\n },\n \"as\": \"media\",\n \"where\": {\n \"$eq\": [\n {\n \"$ref\": \"media.role\"\n },\n \"first_frame\"\n ]\n }\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n },\n \"last_frame\": {\n \"$omitEmpty\": {\n \"$first\": {\n \"$map\": {\n \"from\": {\n \"$filter\": {\n \"from\": {\n \"$ref\": \"request.images\"\n },\n \"as\": \"media\",\n \"where\": {\n \"$eq\": [\n {\n \"$ref\": \"media.role\"\n },\n \"last_frame\"\n ]\n }\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n },\n \"audio\": {\n \"$omitEmpty\": {\n \"$first\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.audios\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/generations/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n }\n ]\n },\n \"documentation\": \"<当前插件的完整 documentation,由 README.md 与 docs/interface.md 拼接而成;为避免 JSON 递归,此处不重复展开正文。>\"\n}\n```\n\n" + "documentation": "# 万有引力视频套件(lxmone.xyz)\n\n该目录是万有引力中转站(`https://lxmone.xyz/v1`)视频协议的官方声明式插件源码。\n后端从生成的 `lxmone-video-suite.yingce-plugin` 包加载,不依赖系统内置 `host:` 适配器。\n\n协议按中转站公开接口文档 `https://lxmone.xyz/docs/` 的 `/v1/videos` 与 `/v1/videos/generations`\n两套请求体形状编写,拆成 8 个 provider,覆盖该站点当前开放的全部视频模型:\n\n| Provider ID | 覆盖模型 | 创建接口 |\n| --- | --- | --- |\n| `lxmone-wan-videos` | `wan3.0-video`、`wan3.0-video-prime` | `POST /v1/videos` |\n| `lxmone-wan-channel-s` | `wan3.0-video-s`、`wan3.0-video-prime-s` | `POST /v1/videos` |\n| `lxmone-seedance-videos` | `seedance-2-pro/fast/mini`、`seedance-2.5-pro`、`seedance2.0-a`~`seedance2.0-f`、`seedance2.5-a` | `POST /v1/videos` |\n| `lxmone-h3-max-videos` | `minimax-h3-max` | `POST /v1/videos` |\n| `lxmone-sd-videos` | `sd-2.0-a`、`sd-2.0-b`、`sd-2.0-c`、`sd-2.5-a`、`sd-2.5` | `POST /v1/videos` |\n| `lxmone-sd-mini-videos` | `sd-mini` | `POST /v1/videos` |\n| `lxmone-grok-videos` | `grok-imagine-video`、`grok-imagine-video-1.5`、`grok-imagine-video-1.5S` | `POST /v1/videos/generations` |\n| `lxmone-h3-workflow` | `minimax-h3-a`~`minimax-h3-e` | `POST /v1/videos/generations` |\n\n完整字段、请求模板与响应映射见 [docs/interface.md](docs/interface.md)。\n\n## 构建\n\n```sh\nnode plugin-packages/embed-documentation.mjs lxmone-video-suite\nsh plugin-packages/build-packages.sh\n```\n\n---\n\n# 万有引力视频套件接口字段\n\n## 协议身份\n\n- 插件 ID:`lxmone-video-suite`。\n- 能力:`video`。\n- 默认 Base URL:`https://lxmone.xyz/v1`。\n- 鉴权驱动:`bearer`。\n- 创建接口:`POST /v1/videos` 或 `POST /v1/videos/generations`(按模型所属 provider 决定)。\n- 查询接口:`GET /v1/videos/{{taskId}}` 或 `GET /v1/videos/generations/{{taskId}}`。\n- 参考媒体要求公开可访问的 HTTPS URL(`requiresPublicMediaUrls`)。\n\n以上形状来自中转站公开文档 `https://lxmone.xyz/docs/`:同一批模型的 `model`、`prompt`、时长、\n分辨率与画幅字段名在不同渠道并不一致,因此按上游请求体拆成 8 个 provider,而不是一个通用协议。\n\n## 配置字段\n\n| 字段 | 类型 | 必填 | 含义 |\n| --- | --- | --- | --- |\n| `apiKey` | secret | 是 | 万有引力中转站的 API Key,随请求发送 `Authorization: Bearer `。 |\n\n## 统一字段映射\n\n宿主向插件提交统一的视频生成请求,插件按 provider 映射到上游字段:\n\n| 统一字段 | 类型 | 必填 | 上游映射 | 说明 |\n| --- | --- | --- | --- | --- |\n| `model` | string | 是 | `model` | 上游模型 ID,透传,不做改名或别名。 |\n| `prompt` | string | 是 | `prompt` / `input.prompt` | 视频提示词。 |\n| `images` | media[] | 否 | `reference_images` / `images` / `image_url` / `input.media[]` / `input_reference` | 参考图;带 role 的 `first_frame`、`last_frame` 会落到支持首尾帧的 provider 专属字段。 |\n| `videos` | media[] | 否 | `reference_videos` / `videos` / `input.media[]` | 参考视频。 |\n| `audios` | media[] | 否 | `reference_audios` / `audio` / `audio_urls` / `input.media[]` | 参考音频。 |\n| `duration` | integer | 否 | `seconds` / `duration` / `duration_seconds` | 时长秒数;缺省由各 provider 填默认值。 |\n| `aspectRatio` | string | 否 | `aspect_ratio` / `parameters.ratio` | 画幅比例,默认 `16:9`。 |\n| `resolution` | string | 否 | `resolution` / `size` / `parameters.resolution` | 分辨率档位;上游要求大写 `720P` 形式的 provider 会自动转换。 |\n| `generateAudio` | boolean | 否 | `audio` / `generate_audio` | 是否生成或保留音频。 |\n\n## 各 provider 的创建体\n\n### `lxmone-wan-videos`(`wan3.0-video`、`wan3.0-video-prime`)\n\n`POST /v1/videos`,顶层字段:`model`、`prompt`、`seconds`、`size`、`aspect_ratio`、\n`reference_images[{url, role}]`、`reference_videos[]`、`reference_audios[]`、`prompt_extend`。\n\n### `lxmone-wan-channel-s`(`wan3.0-video-s`、`wan3.0-video-prime-s`)\n\n`POST /v1/videos`,`input.media[{type, url}]` 与 `input.prompt`,参数放在\n`parameters{resolution, ratio, duration, audio, prompt_extend}`。\n\n### `lxmone-seedance-videos`(`seedance-2-pro/fast/mini`、`seedance-2.5-pro`、`seedance2.0-a`~`f`、`seedance2.5-a`)\n\n`POST /v1/videos`,字段:`model`、`prompt`、`duration_seconds`、`resolution`、`aspect_ratio`、\n`reference_images[]`、`reference_videos[]`、`reference_audios[]`。\n\n### `lxmone-h3-max-videos`(`minimax-h3-max`)\n\n官方文档要求 H3 Max 走 `POST /v1/videos`(不要提交到 `/v1/videos/generations`,也要避开\n`input_reference` 与 `audio` 这组独立工作流字段),字段为:`model`、`prompt`、`seconds`、\n`resolution`、`aspect_ratio`、`reference_images[]`、`reference_videos[]`、`reference_audios[]`。\n上游把客户端传入的 720p 映射为 768p,参考素材上限为图 / 视频 / 音频各 12 段。\n\n### `lxmone-sd-videos`(`sd-2.0-a`、`sd-2.0-b`、`sd-2.0-c`、`sd-2.5-a`、`sd-2.5`)\n\n`POST /v1/videos`,字段:`model`、`prompt`、`duration`、`resolution`、`aspect_ratio`、\n`images[]`、`videos[]`、`audio[]`。\n\n### `lxmone-sd-mini-videos`(`sd-mini`)\n\n`POST /v1/videos`,字段:`model`、`prompt`、`seconds`、`resolution`、`aspect_ratio`、\n`image_url`、`reference_image_urls[]`、`audio_urls[]`。\n\n### `lxmone-grok-videos`(`grok-imagine-video`、`grok-imagine-video-1.5`、`grok-imagine-video-1.5S`)\n\n`POST /v1/videos/generations`,字段:`model`、`prompt`、`duration`、`aspect_ratio`、`resolution`、\n`generate_audio`,以及互斥的 `image{url}`(首帧)或 `reference_images[{url}]`(参考图)。\n\n### `lxmone-h3-workflow`(`minimax-h3-a`~`minimax-h3-e`)\n\n`POST /v1/videos/generations`,字段:`model`、`prompt`、`seconds`、`resolution`、`aspect_ratio`、\n`input_reference[]`、`first_frame`、`last_frame`、`audio`。\n\n## 响应与错误\n\n创建成功后,插件从上游响应里按顺序取 `id`、`task_id`、`taskId`、`data.id` 得到统一 `taskId`,\n轮询时按 `status`、`state`、`data.status` 取状态,`completed`/`succeeded` 归一为 `succeeded`,\n`failed`/`expired`/`error` 归一为 `failed`,其余按进行中处理。\n\n视频地址优先取 `metadata.direct_url`、`data.metadata.direct_url`,再按\n`metadata.url`、`metadata.video_url`、`video_url`、`videoUrl`、`result_url`、`url`、\n`data.metadata.url`、`data.video_url`、`output.url` 依次取值;上游返回的是临时地址\n(`resultEphemeral`),由宿主立即下载并转存为项目资源。\n\nH3 工作流完成响应可能同时包含相对路径 `metadata.url` 和完整 HTTPS 地址\n`metadata.direct_url`,必须优先选择后者,避免把缺少主机的路径交给外部资源下载器。\n下载仍执行宿主的地址与 SSRF 校验。\n\n错误信息取 `error.message`、`message`、`fail_reason`,错误码路径为 `error.message` 与 `error.code`。\nHTTP 失败、业务错误码或状态进入 `failed` 时,任务以失败结束并把上游原文回传给用户。\n\n\n## Manifest 完整接口定义\n\n以下 JSON 与插件包内实际 `manifest.json` 逐字段一致,覆盖插件身份、权限、配置、鉴权、参数、校验、创建、Agent、查询、取消、结果下载、响应和 Agent 响应映射。`documentation` 字段的值就是当前完整文档;为避免文档在自身内部无限递归,JSON 中仅用等义占位文本表示正文。\n\n```json\n{\n \"apiVersion\": \"yingce.plugin/v2\",\n \"id\": \"lxmone-video-suite\",\n \"name\": \"万有引力视频套件\",\n \"version\": \"1.0.1\",\n \"author\": \"Yingce / 万有引力\",\n \"description\": \"万有引力(lxmone.xyz)视频协议套件:Wan 3.0(现有渠道与 S 渠道)、Seedance 2 / 2.5、SD 2.0 / 2.5 / Mini、Grok Imagine、MiniMax H3(Max 与 A-E 独立工作流)。\",\n \"permissions\": [\n \"generation.run\",\n \"media.read\"\n ],\n \"configuration\": {\n \"fields\": [\n {\n \"name\": \"apiKey\",\n \"type\": \"secret\",\n \"label\": \"API Key\",\n \"required\": true\n }\n ]\n },\n \"contributes\": {\n \"providers\": [\n {\n \"id\": \"lxmone-wan-videos\",\n \"label\": \"万有引力 Wan 3.0 视频(现有渠道)\",\n \"description\": \"wan3.0-video / wan3.0-video-prime:POST /v1/videos,顶层 reference_images、reference_videos、reference_audios。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"seconds\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 10\n }\n },\n \"size\": {\n \"$coalesce\": [\n {\n \"$upper\": {\n \"$ref\": \"request.resolution\"\n }\n },\n \"720P\"\n ]\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"reference_images\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"url\": {\n \"$ref\": \"media.value\"\n },\n \"role\": {\n \"$coalesce\": [\n {\n \"$ref\": \"media.role\"\n },\n \"reference_image\"\n ]\n }\n }\n }\n }\n },\n \"reference_videos\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.videos\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"reference_audios\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"prompt_extend\": false\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.data.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-wan-channel-s\",\n \"label\": \"万有引力 Wan 3.0 视频(S 渠道)\",\n \"description\": \"wan3.0-video-s / wan3.0-video-prime-s:POST /v1/videos,原生 input.media 与 parameters。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"input\": {\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"media\": {\n \"$omitEmpty\": {\n \"$concatArrays\": [\n {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"type\": {\n \"$coalesce\": [\n {\n \"$ref\": \"media.role\"\n },\n \"reference_image\"\n ]\n },\n \"url\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.videos\"\n },\n \"as\": \"media\",\n \"in\": {\n \"type\": \"reference_video\",\n \"url\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"type\": \"reference_audio\",\n \"url\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n ]\n }\n }\n },\n \"parameters\": {\n \"resolution\": {\n \"$coalesce\": [\n {\n \"$upper\": {\n \"$ref\": \"request.resolution\"\n }\n },\n \"720P\"\n ]\n },\n \"ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"duration\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"audio\": {\n \"$ref\": \"request.generateAudio\"\n },\n \"prompt_extend\": false\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.data.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-seedance-videos\",\n \"label\": \"万有引力 Seedance 视频\",\n \"description\": \"seedance-2-pro/fast/mini、seedance-2.5-pro、seedance2.0-a~f、seedance2.5-a。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"duration_seconds\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"720p\"\n ]\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"reference_images\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"reference_videos\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.videos\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"reference_audios\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.data.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-h3-max-videos\",\n \"label\": \"万有引力 MiniMax H3 Max 视频\",\n \"description\": \"minimax-h3-max:POST /v1/videos,seconds、resolution 与 reference_images、reference_videos、reference_audios 扁平 URL 数组。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"seconds\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"768p\"\n ]\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"reference_images\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"reference_videos\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.videos\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"reference_audios\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.data.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-sd-videos\",\n \"label\": \"万有引力 SD 视频\",\n \"description\": \"sd-2.0-a/b/c、sd-2.5-a、sd-2.5:POST /v1/videos,duration 与 images、videos、audio 数组。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"duration\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"720p\"\n ]\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"images\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"videos\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.videos\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"audio\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.data.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-sd-mini-videos\",\n \"label\": \"万有引力 SD Mini 视频\",\n \"description\": \"sd-mini:POST /v1/videos,主图 image_url、额外参考图 reference_image_urls、音频 audio_urls。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"seconds\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"720p\"\n ]\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"image_url\": {\n \"$omitEmpty\": {\n \"$first\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n },\n \"reference_image_urls\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$filter\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"where\": {\n \"$gt\": [\n {\n \"$ref\": \"media.order\"\n },\n 0\n ]\n }\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"audio_urls\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$ref\": \"request.audios\"\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.data.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-grok-videos\",\n \"label\": \"万有引力 Grok Imagine 视频\",\n \"description\": \"grok-imagine-video / 1.5 / 1.5S:POST /v1/videos/generations,duration、image、reference_images。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos/generations\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"duration\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 6\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"720p\"\n ]\n }\n },\n \"image\": {\n \"$omitEmpty\": {\n \"$if\": {\n \"condition\": {\n \"$eq\": [\n {\n \"$len\": {\n \"$ref\": \"request.images\"\n }\n },\n 1\n ]\n },\n \"then\": {\n \"url\": {\n \"$first\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n },\n \"else\": null\n }\n }\n },\n \"reference_images\": {\n \"$omitEmpty\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$len\": {\n \"$ref\": \"request.images\"\n }\n },\n 1\n ]\n },\n \"then\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.images\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"url\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"else\": null\n }\n }\n },\n \"generate_audio\": {\n \"$ref\": \"request.generateAudio\"\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/generations/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.data.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n },\n {\n \"id\": \"lxmone-h3-workflow\",\n \"label\": \"万有引力 MiniMax H3 工作流\",\n \"description\": \"minimax-h3-a~e:POST /v1/videos/generations,input_reference、first_frame、last_frame、audio。\",\n \"capabilities\": [\n \"video\"\n ],\n \"scopes\": [\n \"admin.system-channel\",\n \"user.custom-channel\",\n \"canvas\",\n \"creation\",\n \"agent\"\n ],\n \"baseUrl\": \"https://lxmone.xyz/v1\",\n \"requiresPublicMediaUrls\": true,\n \"auth\": {\n \"type\": \"bearer\",\n \"field\": \"apiKey\"\n },\n \"parameters\": [\n {\n \"name\": \"model\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"model\",\n \"description\": \"上游模型 ID。\"\n },\n {\n \"name\": \"prompt\",\n \"type\": \"string\",\n \"required\": true,\n \"mapping\": \"prompt\",\n \"description\": \"视频提示词。\"\n },\n {\n \"name\": \"images\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_images\",\n \"description\": \"参考图片,宿主发布为公开 URL 后提交。\"\n },\n {\n \"name\": \"videos\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_videos\",\n \"description\": \"参考视频。\"\n },\n {\n \"name\": \"audios\",\n \"type\": \"media[]\",\n \"required\": false,\n \"mapping\": \"reference_audios\",\n \"description\": \"参考音频。\"\n },\n {\n \"name\": \"duration\",\n \"type\": \"integer\",\n \"required\": false,\n \"mapping\": \"seconds/duration/duration_seconds\",\n \"description\": \"输出时长,单位秒。\"\n },\n {\n \"name\": \"aspectRatio\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"aspect_ratio\",\n \"description\": \"画幅比例。\"\n },\n {\n \"name\": \"resolution\",\n \"type\": \"string\",\n \"required\": false,\n \"mapping\": \"resolution/size\",\n \"description\": \"输出分辨率档位。\"\n },\n {\n \"name\": \"generateAudio\",\n \"type\": \"boolean\",\n \"required\": false,\n \"mapping\": \"audio/generate_audio\",\n \"description\": \"是否生成或保留音频。\"\n }\n ],\n \"create\": {\n \"method\": \"POST\",\n \"path\": \"/v1/videos/generations\",\n \"contentType\": \"application/json\",\n \"body\": {\n \"model\": {\n \"$ref\": \"request.model\"\n },\n \"prompt\": {\n \"$ref\": \"request.prompt\"\n },\n \"seconds\": {\n \"$if\": {\n \"condition\": {\n \"$gt\": [\n {\n \"$ref\": \"request.duration\"\n },\n 0\n ]\n },\n \"then\": {\n \"$ref\": \"request.duration\"\n },\n \"else\": 5\n }\n },\n \"resolution\": {\n \"$lower\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.resolution\"\n },\n \"720p\"\n ]\n }\n },\n \"aspect_ratio\": {\n \"$coalesce\": [\n {\n \"$ref\": \"request.aspectRatio\"\n },\n \"16:9\"\n ]\n },\n \"input_reference\": {\n \"$omitEmpty\": {\n \"$map\": {\n \"from\": {\n \"$filter\": {\n \"from\": {\n \"$ref\": \"request.images\"\n },\n \"as\": \"media\",\n \"where\": {\n \"$and\": [\n {\n \"$ne\": [\n {\n \"$ref\": \"media.role\"\n },\n \"first_frame\"\n ]\n },\n {\n \"$ne\": [\n {\n \"$ref\": \"media.role\"\n },\n \"last_frame\"\n ]\n }\n ]\n }\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n },\n \"first_frame\": {\n \"$omitEmpty\": {\n \"$first\": {\n \"$map\": {\n \"from\": {\n \"$filter\": {\n \"from\": {\n \"$ref\": \"request.images\"\n },\n \"as\": \"media\",\n \"where\": {\n \"$eq\": [\n {\n \"$ref\": \"media.role\"\n },\n \"first_frame\"\n ]\n }\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n },\n \"last_frame\": {\n \"$omitEmpty\": {\n \"$first\": {\n \"$map\": {\n \"from\": {\n \"$filter\": {\n \"from\": {\n \"$ref\": \"request.images\"\n },\n \"as\": \"media\",\n \"where\": {\n \"$eq\": [\n {\n \"$ref\": \"media.role\"\n },\n \"last_frame\"\n ]\n }\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n },\n \"audio\": {\n \"$omitEmpty\": {\n \"$first\": {\n \"$map\": {\n \"from\": {\n \"$sortByOrder\": {\n \"$ref\": \"request.audios\"\n }\n },\n \"as\": \"media\",\n \"in\": {\n \"$ref\": \"media.value\"\n }\n }\n }\n }\n }\n }\n },\n \"poll\": {\n \"method\": \"GET\",\n \"path\": \"/v1/videos/generations/{{taskId}}\",\n \"contentType\": \"application/json\"\n },\n \"response\": {\n \"taskId\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.id\"\n },\n {\n \"$ref\": \"response.task_id\"\n },\n {\n \"$ref\": \"response.taskId\"\n },\n {\n \"$ref\": \"response.request_id\"\n },\n {\n \"$ref\": \"response.data.id\"\n },\n \"taskId\"\n ]\n },\n \"status\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.status\"\n },\n {\n \"$ref\": \"response.state\"\n },\n {\n \"$ref\": \"response.data.status\"\n },\n \"pending\"\n ]\n },\n \"message\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.error.message\"\n },\n {\n \"$ref\": \"response.message\"\n },\n {\n \"$ref\": \"response.fail_reason\"\n }\n ]\n },\n \"videos\": {\n \"$coalesce\": [\n {\n \"$ref\": \"response.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.data.metadata.direct_url\"\n },\n {\n \"$ref\": \"response.metadata.url\"\n },\n {\n \"$ref\": \"response.metadata.video_url\"\n },\n {\n \"$ref\": \"response.video_url\"\n },\n {\n \"$ref\": \"response.videoUrl\"\n },\n {\n \"$ref\": \"response.result_url\"\n },\n {\n \"$ref\": \"response.url\"\n },\n {\n \"$ref\": \"response.data.metadata.url\"\n },\n {\n \"$ref\": \"response.data.video_url\"\n },\n {\n \"$ref\": \"response.output.url\"\n }\n ]\n },\n \"errorPaths\": [\n \"error.message\",\n \"error.code\"\n ],\n \"resultEphemeral\": true\n }\n }\n ]\n },\n \"documentation\": \"<当前插件的完整 documentation,由 README.md 与 docs/interface.md 拼接而成;为避免 JSON 递归,此处不重复展开正文。>\"\n}\n```\n\n" } diff --git a/web/src/pages/create/creation-generation-config.ts b/web/src/pages/create/creation-generation-config.ts new file mode 100644 index 000000000..5ec5839d3 --- /dev/null +++ b/web/src/pages/create/creation-generation-config.ts @@ -0,0 +1,26 @@ +import { modelCapabilityConfigFor, normalizeVideoValue } from "@/lib/model-capabilities"; +import { resolveModelVideoBooleanOptions } from "@/lib/model-selection"; +import type { AiConfig } from "@/stores/use-config-store"; +import type { CreationSettings } from "./creation-types"; + +// 创作台没有音频和水印开关;报价与提交共用所选模型的默认值和能力限制。 +export function creationVideoConfig(config: AiConfig, model: string, settings: Pick): AiConfig { + const profile = modelCapabilityConfigFor(config, model).video!; + const normalized = normalizeVideoValue(profile, { + ratio: settings.ratio, + seconds: settings.seconds, + resolution: settings.videoQuality, + }); + return { + ...config, + model, + videoModel: model, + size: normalized.ratio, + videoSeconds: normalized.seconds, + vquality: normalized.resolution.replace(/p$/i, ""), + ...resolveModelVideoBooleanOptions(config, model, {}, { + videoGenerateAudio: config.videoGenerateAudio, + videoWatermark: config.videoWatermark, + }), + }; +} diff --git a/web/src/pages/create/index.tsx b/web/src/pages/create/index.tsx index 3a8f4758e..c588b028d 100644 --- a/web/src/pages/create/index.tsx +++ b/web/src/pages/create/index.tsx @@ -34,6 +34,7 @@ import { attachCreationTaskContexts, completedCreationGenerationTask, conversati import { CreationComposer, CreationEmptySuggest, CreationFeaturedWorks, CreationHistoryDrawer, CreationMessageView, CreationModeTabs, CreationWorkspaceToolbar, creationAssetCategoryLabels } from "./creation-workspace"; import { CreationAgentEntry } from "./creation-agent-entry"; import { createCreationSubmitGate } from "./creation-submit-gate"; +import { creationVideoConfig } from "./creation-generation-config"; const AssetLibraryPickerModal = lazy(() => import("@/components/assets/asset-library-picker-modal").then((module) => ({ default: module.AssetLibraryPickerModal }))); const loadCreationRuntime = () => import("./creation-runtime"); @@ -142,10 +143,13 @@ export default function CreatePage() { options: mode === "image" ? { size: ratio, quality, count: Number(count), transparentBackground: config.transparentBackground === "true" } : mode === "video" - ? { size: ratio, videoSeconds: Number(seconds), vquality: videoQuality, videoGenerateAudio: config.videoGenerateAudio === "true", videoWatermark: config.videoWatermark === "true" } + ? { size: ratio, videoSeconds: Number(seconds), vquality: videoQuality } : {}, - }), [attachments, config.transparentBackground, config.videoGenerateAudio, config.videoWatermark, count, hasPrompt, mode, quality, ratio, seconds, videoQuality]); + }), [attachments, config.transparentBackground, count, hasPrompt, mode, quality, ratio, seconds, videoQuality]); const selectedModel = resolveCompatibleModel(config, preferredModel, modelRequirements) || preferredModel; + const generationConfig = useMemo(() => mode === "video" + ? creationVideoConfig(config, selectedModel, { ratio, seconds, videoQuality }) + : config, [config, mode, ratio, seconds, selectedModel, videoQuality]); const imageProfile = useMemo(() => modelCapabilityConfigFor(config, selectedModel).image!, [config, selectedModel]); const videoProfile = useMemo(() => modelCapabilityConfigFor(config, selectedModel).video!, [config, selectedModel]); const maxReferences = mode === "video" ? videoProfile.operations.includes("image_to_video") ? videoProfile.references.maxImages : 0 : mode === "image" ? imageProfile.references.maxImages : 6; @@ -628,18 +632,15 @@ export default function CreatePage() { const requestLifecycle = runtime.beginGenerationConsumer(controller.signal); abortRef.current = controller; const normalizedImage = mode === "image" ? normalizeImageValue(imageProfile, { size: ratio, quality, count }) : undefined; - const normalizedVideo = mode === "video" ? normalizeVideoValue(videoProfile, { seconds, ratio, resolution: videoQuality }) : undefined; const requestConfig = { - ...config, + ...generationConfig, model: selectedModel, imageModel: selectedModel, videoModel: selectedModel, textModel: selectedModel, ...(mode === "image" ? { size: normalizedImage?.size || ratio, quality: normalizedImage?.quality || quality, count: normalizedImage?.count || count, videoSeconds: config.videoSeconds } - : mode === "video" - ? { size: normalizedVideo?.ratio ?? ratio, videoSeconds: normalizedVideo?.seconds || seconds, vquality: (normalizedVideo?.resolution ?? videoQuality).replace(/p$/i, "") } - : {}), + : {}), }; try { if (mode === "text") { @@ -957,7 +958,7 @@ export default function CreatePage() { modelRequirements, imageProfile, videoProfile, - config, + config: generationConfig, onModelChange: (value: string) => updateConfig(mode === "text" ? "textModel" : mode === "image" ? "imageModel" : "videoModel", value), ratio, setRatio: setComposerRatio, diff --git a/web/test/creation-generation-config.test.ts b/web/test/creation-generation-config.test.ts new file mode 100644 index 000000000..b53386760 --- /dev/null +++ b/web/test/creation-generation-config.test.ts @@ -0,0 +1,50 @@ +import { expect, test } from "bun:test"; +import { defaultModelCapabilityConfig } from "../src/lib/model-capabilities"; +import { modelQuoteRequest } from "../src/lib/model-pricing"; +import { creationVideoConfig } from "../src/pages/create/creation-generation-config"; +import { prepareBackendGenerationTask } from "../src/services/api/generation-task"; +import { defaultConfig, type AiConfig } from "../src/stores/use-config-store"; + +function videoConfig(generateAudio: { supported: boolean; default: boolean }): AiConfig { + const capabilityConfig = defaultModelCapabilityConfig(); + capabilityConfig.video!.generateAudio = generateAudio; + capabilityConfig.video!.watermark = { supported: false, default: false }; + return { + ...defaultConfig, + model: "gravity::minimax-h3-a", + videoModel: "gravity::minimax-h3-a", + videoGenerateAudio: "true", + videoWatermark: "true", + channels: [{ + id: "gravity", name: "万有引力", baseUrl: "/api", apiKey: "", apiFormat: "openai", scope: "system", + models: ["minimax-h3-a"], + modelCosts: [{ model: "minimax-h3-a", capability: "video", billingMode: "per_second", unitPriceMicrocredits: 1, capabilityConfig }], + }], + }; +} + +test("创作台无声视频报价、提交与重试不携带全局音频和水印默认值", async () => { + const config = videoConfig({ supported: false, default: false }); + const requestConfig = creationVideoConfig(config, config.videoModel, { ratio: "16:9", seconds: "6", videoQuality: "480" }); + const quote = modelQuoteRequest(requestConfig, requestConfig.model, "video"); + expect(quote?.intent.options).toMatchObject({ size: "16:9", vquality: "480", videoSeconds: 6, videoGenerateAudio: false, videoWatermark: false }); + + for (const retryOf of [undefined, "failed-task"]) { + const task = await prepareBackendGenerationTask({ mode: "video", prompt: "小猫在流泪", config: requestConfig, retryOf }); + expect(task.input).toMatchObject({ + config: { size: "16:9", vquality: "480", videoSeconds: "6", videoGenerateAudio: "false", videoWatermark: "false" }, + ...(retryOf ? { metadata: { retryOf } } : {}), + }); + expect(task.operation).toBe("text_to_video"); + } + expect(config.videoGenerateAudio).toBe("true"); + expect(config.videoWatermark).toBe("true"); +}); + +test.each([false, true])("创作台支持同步音频时遵循模型默认值 %s", (audioDefault) => { + const config = videoConfig({ supported: true, default: audioDefault }); + config.videoGenerateAudio = String(!audioDefault); + const requestConfig = creationVideoConfig(config, config.videoModel, { ratio: "16:9", seconds: "6", videoQuality: "480" }); + expect(requestConfig.videoGenerateAudio).toBe(String(audioDefault)); + expect(modelQuoteRequest(requestConfig, requestConfig.model, "video")?.intent.options?.videoGenerateAudio).toBe(audioDefault); +});