External API既有问题:抠图幂等重放误报409、动画轮询结果与序列字段文档不一致 #495

Open
opened 2026-09-23 15:54:00 +08:00 by lhk229 · 0 comments
Member

概述

2026-09-23 本地 MCP 全工具实测发现两个后端既有问题:抠图同键重放错误返回 409;动画异步查询的精简结果与既有 Skill 文档承诺的嵌套序列字段不一致。

两处相关生产代码在本次 MCP 语义工具改造前已存在,改造未修改这些逻辑。本 issue 用于移交后续处理,本轮只测试、记录,未实施修复。

测试环境:本地 API server + SpacetimeDB 2.8.3 + BgFilter worker,隔离数据库、测试 API Key;本地测试版本 23b2a3325。真实调用 OSS 与生成 Provider:44 个工具主调用路径跑通,11 个生成任务 completed。以下两项严格合同检查未通过,不能据此声称整体验收全部通过;未验证线上部署状态。

问题一:抠图同一请求、同一幂等键重放错误返回 409

复现

  1. 上传并确认一张纯绿色背景的 512×512 图片,将其登记为当前用户的项目资源。
  2. 使用 modify_image 提交如下请求,保留幂等键及完整参数:
{
  "action": "remove_background",
  "idempotencyKey": "background-replay-example-001",
  "input": {
    "projectId": "<当前用户的项目ID>",
    "assetFolderId": "<当前用户的文件夹ID>",
    "assetLabel": "抠图重放测试",
    "sourceImageSrc": "<已登记的项目资源ID>",
    "backgroundMode": "flat",
    "screenColor": "#00FF00",
    "canvasCompletion": {
      "title": "抠图重放测试",
      "placeholder": {
        "x": 0, "y": 0, "width": 512, "height": 512,
        "originalWidth": 512, "originalHeight": 512
      }
    }
  }
}
  1. 首次受理返回 operationId,任务可正常 completed;真实产物可下载,透明背景和保留前景均通过像素检查。
  2. 原样通过新工具重放,或使用旧工具 remove_external_editor_image_background,将上述 input 原样放入 body,并使用相同 idempotencyKey。

实际: 新旧入口均返回 MCP isError=true,业务状态 409 / CONFLICT,提示“Idempotency-Key 已用于不同的生成请求,请复用原请求参数或更换幂等键。”没有改动请求参数。旧工具另用独立逻辑请求可以正常完成抠图。

预期: 相同请求、相同用户、相同幂等键应返回原 operationId;不新建任务、不重复扣费。只有相同键搭配不同请求时才应返回 409。

影响: 首次受理响应丢失时,客户端遵循文档同键重试也无法找回原任务。不是首次抠图能力失效。

代码原因

  • server-rs/crates/api-server/src/editor_project.rs:enqueue_editor_background_removal_for_owner 先计算原始请求身份,再调用专用的提前重放查询。
  • server-rs/crates/api-server/src/editor_generation_queue.rs:find_external_api_editor_generation_replay 调用 get_external_generation_job,随后 ensure_external_api_editor_generation_request_identity 核对 job_id、dedupe_key、owner、kind 和原始请求指纹。
  • server-rs/crates/spacetime-module/src/external_generation.rs:get_external_generation_job_tx 实际返回 summary 经 map_external_generation_job_summary_to_compat_snapshot 转换的兼容快照;该映射明确将 dedupe_key 置为空字符串,并把 request_payload_json 重建为仅含 prompt 或空对象,丢失原始请求指纹,导致身份比较失败。
  • 历史依据:摘要兼容映射来自 324f99efdf(2026-07-11),抠图提前重放查询来自 aa8e3507d1(2026-08-24),均早于本次 MCP 改造。其他实测生成入口的同键重放返回同一任务。

建议后续从后端重放查询的数据合同修复;不要在 MCP 层换键重试或关闭幂等校验。

问题二:动画轮询结果缺少文档承诺的嵌套正式序列字段

复现与结果

  1. 使用新工具 generate_character_animation,或对应旧工具,提交角色动画;本轮参数为真实 512×512 来源图,model=seedance2.0-fast、resolution=480p、ratio=1:1、frameCount=32、durationSeconds=4,带 projectId、assetFolderId、canvasCompletion。
  2. 使用 check_generation / get_external_editor_generation_job 查询至 completed。
  3. 检查 result.resource 和 result.asset,再通过完整项目和素材库读取接口核对正式记录。

实际读数:

位置 帧数/字段 时长
任务结果顶层 result.frames 32 帧 顶层 durationSeconds=4
任务结果内嵌 result.resource 缺少 imageSequenceFrames 缺少 imageSequenceDurationMs
任务结果内嵌 result.asset 缺少 imageSequenceFrames 缺少 imageSequenceDurationMs
完整项目的正式资源记录 imageSequenceFrames=32 帧 imageSequenceDurationMs=4000
完整素材库的正式素材记录 imageSequenceFrames=32 帧 imageSequenceDurationMs=4000

首末帧可下载并解码为 480×480 PNG,存在透明像素。没有 warning/sliceWarning,未发现持久化丢帧。问题是精简响应与说明不一致,不是动画生成或存储失败。

代码与文档

  • .codex/skills/genarrative-external-editor-api/references/requests-and-outputs.md 明确说明 completed compact result 的正式 resource/asset 包含 imageSequenceFrames 和 imageSequenceDurationMs,调用者可直接使用。
  • server-rs/crates/api-server/src/character_animation_assets.rs:候选资源/素材通过 compact_editor_generation_candidate_resource / compact_editor_generation_candidate_asset 构造异步结果时,白名单未包含这两个字段。
  • server-rs/crates/api-server/src/editor_project.rs:External compact 的 compact_external_generation_resource / compact_external_generation_asset 白名单也未保留这两个字段。
  • 相关候选结果裁剪逻辑来自 6c53eda71c(2026-08-07),不是本次 MCP 改造新增。
  • OpenAPI 的生成结果 resource/asset 描述引用正式记录,而通用轮询 compact schema 较宽,未通过字段约束捕获该不一致。

后续需要明确合同:补齐精简响应的正式序列字段,或调整 Skill/说明,明确通过顶层 frames 或再读完整项目/素材库取得数据。不要将该问题描述为“动画丢帧”。

后续验收建议

  • 抠图首次受理、运行中与完成后,同 body/key 经新旧入口重放均返回原任务;不重复生成/扣费。
  • 相同键、不同请求仍返回 409;跨用户访问边界保持有效。
  • 动画轮询结果与最终约定的 Skill/OpenAPI 说明一致。
  • 动画正式项目资源、素材记录保留完整帧序列和时长。

本地测试脚本与产物位于测试执行者工作区的 local-scripts/tests,该目录未提交,不作为其他开发者复现的前置依赖;本 issue 已内联必要复现条件与实测结果。未附带凭证、上传签名或私有媒体链接。

## 概述 2026-09-23 本地 MCP 全工具实测发现两个后端既有问题:抠图同键重放错误返回 409;动画异步查询的精简结果与既有 Skill 文档承诺的嵌套序列字段不一致。 两处相关生产代码在本次 MCP 语义工具改造前已存在,改造未修改这些逻辑。本 issue 用于移交后续处理,本轮只测试、记录,未实施修复。 测试环境:本地 API server + SpacetimeDB 2.8.3 + BgFilter worker,隔离数据库、测试 API Key;本地测试版本 `23b2a3325`。真实调用 OSS 与生成 Provider:44 个工具主调用路径跑通,11 个生成任务 completed。以下两项严格合同检查未通过,不能据此声称整体验收全部通过;未验证线上部署状态。 ## 问题一:抠图同一请求、同一幂等键重放错误返回 409 ### 复现 1. 上传并确认一张纯绿色背景的 512×512 图片,将其登记为当前用户的项目资源。 2. 使用 `modify_image` 提交如下请求,保留幂等键及完整参数: ```json { "action": "remove_background", "idempotencyKey": "background-replay-example-001", "input": { "projectId": "<当前用户的项目ID>", "assetFolderId": "<当前用户的文件夹ID>", "assetLabel": "抠图重放测试", "sourceImageSrc": "<已登记的项目资源ID>", "backgroundMode": "flat", "screenColor": "#00FF00", "canvasCompletion": { "title": "抠图重放测试", "placeholder": { "x": 0, "y": 0, "width": 512, "height": 512, "originalWidth": 512, "originalHeight": 512 } } } } ``` 3. 首次受理返回 operationId,任务可正常 completed;真实产物可下载,透明背景和保留前景均通过像素检查。 4. 原样通过新工具重放,或使用旧工具 `remove_external_editor_image_background`,将上述 input 原样放入 body,并使用相同 idempotencyKey。 **实际:** 新旧入口均返回 MCP `isError=true`,业务状态 409 / `CONFLICT`,提示“Idempotency-Key 已用于不同的生成请求,请复用原请求参数或更换幂等键。”没有改动请求参数。旧工具另用独立逻辑请求可以正常完成抠图。 **预期:** 相同请求、相同用户、相同幂等键应返回原 operationId;不新建任务、不重复扣费。只有相同键搭配不同请求时才应返回 409。 **影响:** 首次受理响应丢失时,客户端遵循文档同键重试也无法找回原任务。不是首次抠图能力失效。 ### 代码原因 - `server-rs/crates/api-server/src/editor_project.rs`:`enqueue_editor_background_removal_for_owner` 先计算原始请求身份,再调用专用的提前重放查询。 - `server-rs/crates/api-server/src/editor_generation_queue.rs`:`find_external_api_editor_generation_replay` 调用 `get_external_generation_job`,随后 `ensure_external_api_editor_generation_request_identity` 核对 job_id、dedupe_key、owner、kind 和原始请求指纹。 - `server-rs/crates/spacetime-module/src/external_generation.rs`:`get_external_generation_job_tx` 实际返回 summary 经 `map_external_generation_job_summary_to_compat_snapshot` 转换的兼容快照;该映射明确将 dedupe_key 置为空字符串,并把 request_payload_json 重建为仅含 prompt 或空对象,丢失原始请求指纹,导致身份比较失败。 - 历史依据:摘要兼容映射来自 `324f99efdf`(2026-07-11),抠图提前重放查询来自 `aa8e3507d1`(2026-08-24),均早于本次 MCP 改造。其他实测生成入口的同键重放返回同一任务。 建议后续从后端重放查询的数据合同修复;不要在 MCP 层换键重试或关闭幂等校验。 ## 问题二:动画轮询结果缺少文档承诺的嵌套正式序列字段 ### 复现与结果 1. 使用新工具 `generate_character_animation`,或对应旧工具,提交角色动画;本轮参数为真实 512×512 来源图,`model=seedance2.0-fast`、`resolution=480p`、`ratio=1:1`、`frameCount=32`、`durationSeconds=4`,带 projectId、assetFolderId、canvasCompletion。 2. 使用 `check_generation` / `get_external_editor_generation_job` 查询至 completed。 3. 检查 result.resource 和 result.asset,再通过完整项目和素材库读取接口核对正式记录。 实际读数: | 位置 | 帧数/字段 | 时长 | | --- | --- | --- | | 任务结果顶层 result.frames | 32 帧 | 顶层 durationSeconds=4 | | 任务结果内嵌 result.resource | 缺少 imageSequenceFrames | 缺少 imageSequenceDurationMs | | 任务结果内嵌 result.asset | 缺少 imageSequenceFrames | 缺少 imageSequenceDurationMs | | 完整项目的正式资源记录 | imageSequenceFrames=32 帧 | imageSequenceDurationMs=4000 | | 完整素材库的正式素材记录 | imageSequenceFrames=32 帧 | imageSequenceDurationMs=4000 | 首末帧可下载并解码为 480×480 PNG,存在透明像素。没有 warning/sliceWarning,未发现持久化丢帧。问题是精简响应与说明不一致,不是动画生成或存储失败。 ### 代码与文档 - `.codex/skills/genarrative-external-editor-api/references/requests-and-outputs.md` 明确说明 completed compact result 的正式 resource/asset 包含 imageSequenceFrames 和 imageSequenceDurationMs,调用者可直接使用。 - `server-rs/crates/api-server/src/character_animation_assets.rs`:候选资源/素材通过 `compact_editor_generation_candidate_resource` / `compact_editor_generation_candidate_asset` 构造异步结果时,白名单未包含这两个字段。 - `server-rs/crates/api-server/src/editor_project.rs`:External compact 的 `compact_external_generation_resource` / `compact_external_generation_asset` 白名单也未保留这两个字段。 - 相关候选结果裁剪逻辑来自 `6c53eda71c`(2026-08-07),不是本次 MCP 改造新增。 - OpenAPI 的生成结果 resource/asset 描述引用正式记录,而通用轮询 compact schema 较宽,未通过字段约束捕获该不一致。 后续需要明确合同:补齐精简响应的正式序列字段,或调整 Skill/说明,明确通过顶层 frames 或再读完整项目/素材库取得数据。不要将该问题描述为“动画丢帧”。 ## 后续验收建议 - [ ] 抠图首次受理、运行中与完成后,同 body/key 经新旧入口重放均返回原任务;不重复生成/扣费。 - [ ] 相同键、不同请求仍返回 409;跨用户访问边界保持有效。 - [ ] 动画轮询结果与最终约定的 Skill/OpenAPI 说明一致。 - [ ] 动画正式项目资源、素材记录保留完整帧序列和时长。 本地测试脚本与产物位于测试执行者工作区的 `local-scripts/tests`,该目录未提交,不作为其他开发者复现的前置依赖;本 issue 已内联必要复现条件与实测结果。未附带凭证、上传签名或私有媒体链接。
lhk229 added the Kind/DocumentationKind/Bug labels 2026-09-23 15:54:00 +08:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: GenarrativeAI/Genarrative#495