修复 External 去背景重放与画布竞态
Project CI / Repository checks (pull_request) Successful in 3m36s
Project CI / Frontend tests (pull_request) Successful in 3m59s
Project CI / Backend tests (pull_request) Successful in 5m27s
Project CI / Native shell tests (pull_request) Successful in 14m56s

按原始请求指纹在可变预检前返回幂等任务
修正来源身份优先级与跨项目歧义校验
冻结并复验原位替换目标的完整媒体语义
修复 Python helper 原位替换请求并补正向路由测试
This commit is contained in:
2026-08-24 14:11:34 +08:00
parent 015591594e
commit d39a211154
7 changed files with 921 additions and 159 deletions
@@ -582,11 +582,16 @@ class GenarrativeExternalClient:
session = fields.get("canvasSession")
if session is None:
session = fields.get("canvas_session")
target_layer_id = normalize_optional_text(fields.get("targetLayerId"))
if target_layer_id and fields.get("canvasCompletion") is not None:
raise GenarrativeApiError(
"targetLayerId and canvasCompletion are mutually exclusive for background removal"
)
canvas_width = fields.get("canvasWidth")
canvas_height = fields.get("canvasHeight")
if (canvas_width is None) != (canvas_height is None):
raise GenarrativeApiError("canvasWidth and canvasHeight must be provided together")
if session is not None and canvas_width is None:
if session is not None and canvas_width is None and not target_layer_id:
if source_width is None or source_height is None:
raise GenarrativeApiError(
"remove_background requires source_width and source_height when canvasSession is used without canvasWidth/canvasHeight"
@@ -599,6 +604,8 @@ class GenarrativeExternalClient:
source_width or 1,
source_height or 1,
)
if target_layer_id:
fields.pop("canvasCompletion", None)
idempotency_key = fields.pop("idempotencyKey", None)
return self.submit_and_wait_generation(
"/api/external/v1/editor/images/background-removals",
@@ -838,6 +845,30 @@ def _self_test() -> None:
assert calls[0]["body"]["canvasCompletion"]["placeholder"]["width"] == 720
assert calls[0]["body"]["canvasCompletion"]["placeholder"]["height"] == 1280
calls.clear()
client.remove_background(
"uploads/source.png",
canvasSession=session,
targetLayerId="layer-1",
assetLabel="原位去背景结果",
)
assert calls[0]["body"]["projectId"] == "proj-demo"
assert calls[0]["body"]["assetFolderId"] == "editor-asset-folder-demo"
assert calls[0]["body"]["assetLabel"] == "原位去背景结果"
assert calls[0]["body"]["targetLayerId"] == "layer-1"
assert "canvasCompletion" not in calls[0]["body"]
calls.clear()
try:
client.remove_background(
"uploads/source.png",
canvasSession=session,
targetLayerId="layer-1",
canvasCompletion={"title": "冲突完成指令"},
)
except GenarrativeApiError as error:
assert "targetLayerId and canvasCompletion are mutually exclusive" in str(error)
else:
raise AssertionError("background removal must reject conflicting canvas placement modes")
assert calls == []
try:
client.remove_background("uploads/source.png", canvasSession=session)
except GenarrativeApiError as error: