新增 External v1 去背景生成链路
Project CI / Repository checks (pull_request) Failing after 12s
Project CI / Backend tests (pull_request) Failing after 11s
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled

新增外部去背景 API、MCP 工具与异步队列契约

补齐来源归属、媒体类型、幂等重放和画布原子持久化校验

修复 provenance 重建、assetKindOverride 门禁与 revision retry 竞态

同步 Python helper、Skill、OpenAPI 及项目文档
This commit is contained in:
2026-08-24 12:25:17 +08:00
parent 44ee28c43f
commit 3c8ece15f8
15 changed files with 1953 additions and 150 deletions
@@ -1145,6 +1145,60 @@
}
}
},
"/api/external/v1/editor/images/background-removals": {
"post": {
"tags": [
"Editor Images"
],
"operationId": "removeExternalEditorImageBackground",
"summary": "去除编辑器图片背景",
"description": "提交已有静态图片素材的异步去背景任务。sourceImageSrc 只接受当前账号拥有的稳定 objectKey、项目资源 ID 或素材 ID;禁止 Data URL、Blob URL 和临时 signed URL。assetKind 只能表达静态图片,并且存在权威来源记录时必须与其类型一致;视频、音频、动画和图片序列在入队前返回 400。服务端固定使用 complex 去背景模式,不会在失败时切换到其它 provider。需要写入画布时提供 projectId 与 canvasCompletion;仅需原位替换既有图层时提供 projectId 与 targetLayerId,且来源与目标必须指向同一权威对象。",
"security": [
{
"ExternalApiKey": []
}
],
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EditorBackgroundRemovalRequest"
}
}
}
},
"responses": {
"202": {
"description": "去背景任务已持久化入队",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ExternalEditorGenerationSubmissionResponse"
}
}
}
},
"400": {
"$ref": "#/components/responses/BadRequest"
},
"401": {
"$ref": "#/components/responses/Unauthorized"
},
"403": {
"$ref": "#/components/responses/Forbidden"
},
"502": {
"$ref": "#/components/responses/UpstreamError"
}
}
}
},
"/api/external/v1/editor/icon-spritesheets/generations": {
"post": {
"tags": [
@@ -2339,7 +2393,8 @@
"type": [
"string",
"null"
]
],
"description": "可选的来源项目资源 ID,用于在同一 objectKey 被多个资源以不同权威元数据登记时消歧。sourceImageSrc 已是项目资源 ID 或素材 ID 时按该显式 ID 定点解析;纯 objectKey 无法唯一确定权威来源时必须提供本字段,否则返回 400。原位替换使用纯 objectKey 且省略本字段时,服务端自动绑定 targetLayerId 对应的当前项目资源,并把该绑定写入队列供 Worker 复验。"
},
"assetKind": {
"type": [
@@ -3550,6 +3605,75 @@
},
"additionalProperties": false
},
"EditorBackgroundRemovalRequest": {
"type": "object",
"required": [
"sourceImageSrc"
],
"properties": {
"sourceImageSrc": {
"type": "string",
"minLength": 1,
"description": "当前账号拥有的稳定 objectKey、项目资源 ID 或素材 ID。禁止 Data URL、Blob URL 和临时 signed URL。"
},
"projectId": {
"type": [
"string",
"null"
],
"description": "可选项目上下文。提供 targetLayerId 时必须同时提供非空 projectId,否则在入队前返回 400。"
},
"targetLayerId": {
"type": [
"string",
"null"
],
"description": "提供时必须同时提供 projectId。仅在未提供 canvasCompletion 时用于原位替换既有画布图层,此时目标图层必须存在、关联当前项目静态图片资源;若图层提供 assetKindOverride,则以覆盖后的有效类型参与静态媒体门禁和来源类型比较。来源与目标必须指向同一权威对象:双方都有 assetObjectId 时按 ID 比较,任一缺失时回退 canonical bucket/objectKey;违反任一条件均在入队前返回 400。存在 canvasCompletion 时不参与原位替换。省略 targetLayerId 与 canvasCompletion 时只持久化请求指定的项目资源或素材库记录,不自动写入画布。"
},
"sourceResourceId": {
"type": [
"string",
"null"
],
"description": "可选的来源项目资源 ID,用于在同一 objectKey 被多个资源以不同权威元数据登记时消歧。sourceImageSrc 已是项目资源 ID 或素材 ID 时按该显式 ID 定点解析;纯 objectKey 无法唯一确定权威来源时必须提供本字段,否则返回 400。原位替换使用纯 objectKey 且省略本字段时,服务端自动绑定 targetLayerId 对应的当前项目资源,并把该绑定写入队列供 Worker 复验。"
},
"assetKind": {
"type": [
"string",
"null"
],
"description": "可选静态图片语义类型。服务端优先采用来源项目资源或素材库记录的权威语义类型;资产对象存储类型只参与非静态媒体门禁,不覆盖语义类型。请求值与权威来源类型不一致,或任一记录表示 video、audio、animation、image-sequence、sound-effect、background-music 等非静态媒体时,在入队前返回 400。",
"x-genarrative-media-family": "static-image"
},
"generationInputs": {
"$ref": "#/components/schemas/JsonValue"
},
"assetFolderId": {
"type": [
"string",
"null"
]
},
"assetLabel": {
"type": [
"string",
"null"
]
},
"canvasCompletion": {
"anyOf": [
{
"$ref": "#/components/schemas/EditorCanvasGenerationCompletion"
},
{
"type": "null"
}
],
"description": "画布生成占位完成指令。提供时优先按生成完成链路写入结果,targetLayerId 不参与原位替换。"
}
},
"additionalProperties": false
},
"EditorImageGenerationResponse": {
"type": "object",
"required": [