Fix/let bgm and sfx async #437

Merged
k88936 merged 9 commits from fix/let-bgm-and-sfx-async into master 2026-09-21 00:48:49 +08:00
Member

bgm sfx错误地走了同步生成的路径, 在这里改为任务列表轮询

bgm sfx错误地走了同步生成的路径, 在这里改为任务列表轮询
k88936 added 3 commits 2026-09-21 00:16:13 +08:00
- 原生:`start_local_project_asset_generation` 新增可选入参 `idempotencyKey`,并在音频 kind 上分叉;图片类载荷与分支逐字未改
- 原生:新增音频提交期收口 `prepare_local_project_audio_generation`(kind / 提示词上限 / 素材名 / operation 身份 / 幂等键)
- 原生:新增 `run_local_project_audio_generation_at`,在派发时刻读项目 revision 并复用既有音频无源生成实现,不复制生成逻辑
- 原生:新增 `begin_local_project_audio_generation_task` / `run_local_project_audio_generation_task`,音频任务落同一份项目内账本并写 running → completed / failed,跑完没登记素材按失败收口
- 原生:补两条用例——被拒绝的提交零写入账本、音频任务落在同一账本且 kind 正确
- 前端任务模型:新增音频任务与 `idempotencyKey` 字段,恢复出来的历史任务不带它也不承接重试,入口文案扩到音频栏目
- 前端队列:按 kind 分流派发载荷,音频只发任务身份(任务 id 即 operation id)与幂等键
- 前端面板:音频生成面板改为点「生成」同步提交并立即关闭,删除「生成中…」「后台运行并关闭」与输入锁定
- 前端宿主:音频提交改为同步入队并展开「生成任务」侧栏,只有「后端从未受理」才连原草稿与原请求身份重开面板
- 前端清理:删除随本次改动失效的 `resourceCanvasGenerationSourceId` 与宿主里不再使用的 import
- 测试:面板 / 队列 / 宿主生命周期 / 落点 / appSurface 改按后台账本口径断言,并补「未受理即时失败重开」用例(已用移除重开逻辑的变异验证其非空)
- 文档:PRD §3.10 / §7.9、AGC 底部工具栏入口矩阵、V3 端到端验收 S11a 同步为音频后台化口径
- 文档:新增里程碑与实施计划(含验收证据矩阵),并在 decision-log 记下「音频并入后台任务账本」这条长期约定
AGC 音频账本 kind 判定改成显式穷举,去掉静默兜底
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 19s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 19s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 20s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 20s
Project CI / Native shell tests (pull_request) Failing after 17s
Project CI / AI game creator shell Rust crates (pull_request) Failing after 19s
Project CI / AI game creator shell Rust smoke (pull_request) Failing after 19s
Project CI / Backend tests (pull_request) Failing after 18s
Project CI / Frontend tests (pull_request) Failing after 8s
Project CI / Repository checks (pull_request) Failing after 12s
Project CI / AI game creator shell web tests (pull_request) Failing after 12s
fca111239c
- `begin_local_project_audio_generation_task` 的 `edit_kind → 账本 kind` 映射显式列出
  `SoundEffect` 与 `BackgroundMusic` 两个成员,不再用 `_ =>` 兜底
- 其余 `LocalProjectResourceEditKind` 变体在此处直接返回错误,避免新增音频变体(或上游白名单被
  放宽)时被静默记成音效
Author
Member
  • 1 音频提交上下文是单槽,重叠提交会互相覆盖(commit f2a3ba7ac)

    • 位置:apps/ai-game-creator-shell/src/view/project-development/index.tsx
      (原文指 7863-7868;改后声明 2093、写入 7871、收口读取 7969、切项目清空 8261)
    • 原文结论:属实(bug · medium)。
    • 当前实现:提交 submitResourceCanvasGeneration 时,把「这次提交属于哪张占位」写进
      resourceGenerationAudioSubmissionRef——一个 useRef<{taskId, draftId, kind, dispatchedImmediately} | null> 单槽;收口 handleResourceAssetGenerationSettlement 只在
      audioSubmission?.taskId === settlement.taskId 时才走「后端从未受理 → 把面板连原草稿、
      原请求身份带回来」。
    • 问题:队列是串行派发(下一条必须等上一条终态),第二张占位可以在第一条还在途时提交并
      排在本地队列里;第二张提交会把单槽覆盖成它自己。第一条随后「后端从未受理」(record === null)收口时,槽里已经指向第二条 → 匹配不上 → 丢掉「自动重开面板连草稿」,只剩通用失败
      路径(占位标 failed + 提示条)。不会卡死,但这条恢复 UX 没了。
    • 已修:Map<string, {...}>(键 = taskId,值里不再重复存 taskId);写入 set(task.taskId, …)
      收口 get(settlement.taskId) + delete、切项目 clear()。同时给宿主测试加了
      holdFirstAssetGenerationStart 开关(把第一次派发挂在「受理」之前),新增用例
      「两条音频提交重叠:第一条未被受理时,它的面板仍会被带回来」;该用例在旧实现下确实失败
      (面板不回来),在新实现下通过。
  • 2 音频账本 kind 判定用 _ => 兜底,会把未知类型静默记成音效(commit fca111239)

    • 位置:apps/ai-game-creator-shell/src-tauri/src/asset_generation_tasks.rs
      begin_local_project_audio_generation_task(原文指 425-428)。
    • 原文结论:属实(maintainability · low)。
    • 当前实现:match request.edit_kind { BackgroundMusic => …, _ => SoundEffect }
    • 问题:当前确实不可达——上游 prepare_local_project_audio_generation 已经把 edit_kind
      白名单在 SoundEffect / BackgroundMusic 两个成员上,非音频 kind 在那里就被拒。但兜底臂
      留着的风险是真实的:枚举新增音频变体、或上游白名单被放宽时,新变体会被静默记成音效
      (账本 kind 是侧栏条目身份),没有任何信号。
    • 已修:显式列出两个成员,其余走 other => Err("音频生成不支持该素材类型:{other:?}")
      LocalProjectResourceEditKind 已 derive Debug,不需要新增 Display)。原文件的
      {other:?} 建议可直接采用;这条改动不影响任何可达路径的行为。
  • 3 面板 draftReleasedRef 先置位、onSubmit 无返回值,被同步拒绝时草稿会丢(留给你

    • 位置:apps/ai-game-creator-shell/src/features/resource-canvas/ResourceCanvasGenerationPanelView.tsx
      submit()(原文指 242-253)。
    • 原文结论:属实(bug · low),但可达性比原文暗示的窄,我另外补充了可达性判断。
    • 当前实现:面板 submit()draftReleasedRef.current = true(卸载时不再把草稿交回宿主),
      onSubmit({...})(宿主侧是 submitResourceCanvasGeneration,返回 void),最后无条件
      onClose()。宿主那三个「同步拒绝但不抛错」的分支(!queue || !draftId、占位已不在画布、
      占位已在跑且 operationId 不同)只 setResourceWorkbenchNoticereturn——注意草稿写进
      resourceGenerationDraftRef 的语句在这些 return 之后
    • 问题:这几条分支命中时,宿主既没落草稿、也没派发任务,但面板照样收起且草稿被标成「已交出」
      → 用户刚敲的提示词真的丢了(原文这句准确)。
    • 可达性补充(我逐条核过宿主那几个 early return,比原文暗示的窄很多):
      !queue 不会命中——队列实例在组件 render 体内创建(index.tsx 8113 起,
      if (resourceAssetGenerationQueueRef.current === null) {...}),用户能点的时候它一定不是
      null;② !draftId 不会命中——音频浮层每次都传 resourceGenerationDraft.draftId
      input.kind === 'video' 不会命中——音频入口的 kinds 只放行音效 / 背景音乐。
      真正还剩的是 ④「占位在浮层画出来到点击之间消失」与 ⑤「占位已被另一次 operation 提交」。
      所以今天它更像「防线写漏了一格」而不是会被普遍踩到的线上 bug;但只要前提被放宽(例如让浮层
      挂在已提交的占位上、或把队列改成懒创建),草稿就会静默丢。
    • 其他生成入口(图片类 ResourceCanvasAssetGenerationPanelView.tsx)是怎么做的:结构完全
      一样
      ——面板 submit()draftReleasedRef.current = trueonSubmit({...})(宿主
      submitResourceAssetGeneration 同样返回 void)→ 无条件 onClose();草稿也只在宿主受理
      路径里落 resourceAssetGenerationDraftRef。所以它有同一个洞,但暴露面更小:
      · 宿主侧只有 !queue 一条 early return(index.tsx 8166-8170),而这条如上所述不可达;
      · 它把「不能提交」的判据大多放在面板内部(空提示词 / 空素材名 / 参考失效 / 提示词超限 /
      改了原请求输入),这些分支在 draftReleasedRef.current = true 之前return,面板
      不关、草稿不丢;
      · 图片类的「未受理重开」用的是 resourceAssetGenerationPanelSubmissionRef 里冻结的整份
      草稿(含比例 / 尺寸 / 参考)重开,比音频「草稿槽 + 请求身份槽」两处拼装更自洽。
      另外图片类每次提交都新铸 taskIdcrypto.randomUUID()),没有音频这条「同占位必须复用
      operation id」的判据——所以音频多出来的 ⑤ 是这次音频后台化新加的防线,不是图片类漏抄。
      结论:真要修第 3 条,别只修音频面板——两个面板是同一份契约(都是 onSubmit: (input) => void
      • 提交即关),最好一次把「提交被同步拒绝时要不要关面板 / 要不要交回草稿」定成组件契约,两个
        面板 + 两个宿主调用点 + 各自的用例一起改。
    • 推荐修法(为什么留给你:这是改组件对外契约 + 改 UX 语义,不是我该单方面拍的):
      1. onSubmit 改成能回报受理结果:onSubmit: (input) => boolean | void
      2. 面板侧 const accepted = onSubmit({...}); if (accepted === false) { return; },只有受理
        成功才 draftReleasedRef.current = true + onClose()(保留 === false 而不是真值判断:
        现有用例里传的是 async () => undefined 这类返回 Promise 的桩,非 false 一律按受理算);
      3. 宿主侧 submitResourceCanvasGeneration 三个 early return 改成 return false、成功路径
        return true
        影响面:ResourceCanvasGenerationPanelView 的 props 契约 + 宿主调用点 + 现有
        「点提交即同步关闭」的用例断言(resourceCanvasGenerationEntry.test.tsx 等)。
        不做这层的替代方案(在宿主里「重开面板」)不稳定:submit()onClose() 跟在 onSubmit()
        之后,同一事件里的 setResourceGenerationDraft(...) 会被随后的关闭覆盖掉。
  • 4 音频分支先落账本、后登记 live,留下「排队但还不 live」的竞态窗口(commit 7b1bc1d3e)

    • 位置:apps/ai-game-creator-shell/src-tauri/src/asset_generation_tasks.rs
      start_local_project_asset_generation 音频分支(原文指 531-543),以及同一函数的图片类分支。
    • 原文结论:属实(bug · low),并且不止音频:图片类分支是同一种顺序,同样有这个窗口。
    • 当前实现:begin_local_project_*(写排队记录、释放账本锁)→ 再 live_task_ids().insert(task_id)
      → 再 spawn 后台任务。
    • 问题:list_local_project_asset_generations 的判据是「非终态 + 不在 live 集合 = 上次运行
      的残留」,会调用 repair_interrupted_tasks 把它收口成 failed 并写回账本。窗口期里并发
      的那次 list 就会命中。判准确的后果:派发后的任务虽然会把 status 改回 running,但那次
      收口留下的 finishedAtMillis / error 不会被清掉,而侧栏对 task.error无条件渲染
      → 会出现「一条正在跑的任务带着中断失败原因」的假象(任务真正结束时会清掉 error,所以不会
      永久错乱,但显示是错的)。
    • 已修:改成「先登记 live,再落账本」,落账失败时回滚。回滚判据用新函数
      register_live_task_id(task_id) -> bool:只有本轮真的插入了新 id 才有资格回滚——否则
      同 id 那个正在跑的任务的 live 登记会被误删,list 随后又把它谎报成上次运行的中断残留。
      音频与图片两条分支都改(同一条命令、同一条顺序约束),并新增用例
      a_failed_ledger_write_only_takes_back_the_live_registration_it_inserted 覆盖该回滚判据。
      补充:同一份文档注释本来就写着「本进程派发的任务在 start 里先登记 live 再落账本」,这次是
      把实现修成与注释一致。
  • 5 source_media_type: Some("audio/mpeg") 是死参数(commit ae0ab0ddf)

    • 位置:apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs
      run_local_project_audio_generation_at(原文指 5470-5473)。
    • 原文结论:属实(maintainability · low)。
    • 当前实现:该函数给 derive_local_project_resource_atgeneration_mode: Create +
      source_media_type: Some("audio/mpeg")
    • 问题:Create 模式在 resolve_resource_edit_source提前返回,源快照的 media_type
      infer_resource_edit_source_media_type(edit_kind, source_path) 推(音频恒为 audio/mpeg),
      从头到尾不读 input.source_media_type。所以这个值对生成、对账本记录(账本存的是快照的
      media_type)、对恢复通道(resume_* 从账本回填 + 兜底推断)都没有作用,纯误导。
    • 已修(commit ae0ab0ddf):改成 source_media_type: None,并在函数文档里写明「Create 模式
      不读 input.source_media_type」,避免下一个人又被它骗回去加一个值。
      验证:cargo test resource_edit -- --test-threads=1 60 项全过(含所有音频 / 派生用例)。
      文档同步(commit 98e42e6da):docs/technical/【AGC】栏目画布底部工具栏入口矩阵-2026-09-13.md
      docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md 第 7.9 节第 6 条原先都写着音频通道
      「传 sourceMediaType: 'audio/mpeg'」,改成「源快照媒体类型由 editKind 推为 audio/mpeg
      (Create 模式不读该入参)」,与代码一致。
- [x] 1 音频提交上下文是单槽,重叠提交会互相覆盖(commit f2a3ba7ac) - 位置:`apps/ai-game-creator-shell/src/view/project-development/index.tsx` (原文指 7863-7868;改后声明 2093、写入 7871、收口读取 7969、切项目清空 8261) - 原文结论:属实(bug · medium)。 - 当前实现:提交 `submitResourceCanvasGeneration` 时,把「这次提交属于哪张占位」写进 `resourceGenerationAudioSubmissionRef`——一个 `useRef<{taskId, draftId, kind, dispatchedImmediately} | null>` 单槽;收口 `handleResourceAssetGenerationSettlement` 只在 `audioSubmission?.taskId === settlement.taskId` 时才走「后端从未受理 → 把面板连原草稿、 原请求身份带回来」。 - 问题:队列是串行派发(下一条必须等上一条终态),第二张占位**可以**在第一条还在途时提交并 排在本地队列里;第二张提交会把单槽覆盖成它自己。第一条随后「后端从未受理」(`record === null`)收口时,槽里已经指向第二条 → 匹配不上 → 丢掉「自动重开面板连草稿」,只剩通用失败 路径(占位标 failed + 提示条)。不会卡死,但这条恢复 UX 没了。 - 已修:`Map<string, {...}>`(键 = taskId,值里不再重复存 taskId);写入 `set(task.taskId, …)`、 收口 `get(settlement.taskId)` + `delete`、切项目 `clear()`。同时给宿主测试加了 `holdFirstAssetGenerationStart` 开关(把第一次派发挂在「受理」之前),新增用例 「两条音频提交重叠:第一条未被受理时,它的面板仍会被带回来」;该用例在旧实现下确实失败 (面板不回来),在新实现下通过。 - [x] 2 音频账本 `kind` 判定用 `_ =>` 兜底,会把未知类型静默记成音效(commit fca111239) - 位置:`apps/ai-game-creator-shell/src-tauri/src/asset_generation_tasks.rs` `begin_local_project_audio_generation_task`(原文指 425-428)。 - 原文结论:属实(maintainability · low)。 - 当前实现:`match request.edit_kind { BackgroundMusic => …, _ => SoundEffect }`。 - 问题:当前确实**不可达**——上游 `prepare_local_project_audio_generation` 已经把 `edit_kind` 白名单在 `SoundEffect` / `BackgroundMusic` 两个成员上,非音频 kind 在那里就被拒。但兜底臂 留着的风险是真实的:枚举新增音频变体、或上游白名单被放宽时,新变体会被**静默记成音效** (账本 `kind` 是侧栏条目身份),没有任何信号。 - 已修:显式列出两个成员,其余走 `other => Err("音频生成不支持该素材类型:{other:?}")` (`LocalProjectResourceEditKind` 已 derive `Debug`,不需要新增 `Display`)。原文件的 `{other:?}` 建议可直接采用;这条改动不影响任何可达路径的行为。 - [ ] 3 面板 `draftReleasedRef` 先置位、`onSubmit` 无返回值,被同步拒绝时草稿会丢(**留给你**) - 位置:`apps/ai-game-creator-shell/src/features/resource-canvas/ResourceCanvasGenerationPanelView.tsx` `submit()`(原文指 242-253)。 - 原文结论:属实(bug · low),但可达性比原文暗示的窄,我另外补充了可达性判断。 - 当前实现:面板 `submit()` 先 `draftReleasedRef.current = true`(卸载时不再把草稿交回宿主), 再 `onSubmit({...})`(宿主侧是 `submitResourceCanvasGeneration`,返回 `void`),最后无条件 `onClose()`。宿主那三个「同步拒绝但不抛错」的分支(`!queue || !draftId`、占位已不在画布、 占位已在跑且 operationId 不同)只 `setResourceWorkbenchNotice` 后 `return`——注意草稿写进 `resourceGenerationDraftRef` 的语句在这些 `return` **之后**。 - 问题:这几条分支命中时,宿主既没落草稿、也没派发任务,但面板照样收起且草稿被标成「已交出」 → 用户刚敲的提示词**真的丢了**(原文这句准确)。 - 可达性补充(我逐条核过宿主那几个 early return,比原文暗示的窄很多): ① `!queue` **不会**命中——队列实例在组件 render 体内创建(`index.tsx` 8113 起, `if (resourceAssetGenerationQueueRef.current === null) {...}`),用户能点的时候它一定不是 `null`;② `!draftId` 不会命中——音频浮层每次都传 `resourceGenerationDraft.draftId`; ③ `input.kind === 'video'` 不会命中——音频入口的 `kinds` 只放行音效 / 背景音乐。 真正还剩的是 ④「占位在浮层画出来到点击之间消失」与 ⑤「占位已被另一次 operation 提交」。 所以今天它更像「防线写漏了一格」而不是会被普遍踩到的线上 bug;但只要前提被放宽(例如让浮层 挂在已提交的占位上、或把队列改成懒创建),草稿就会静默丢。 - 其他生成入口(图片类 `ResourceCanvasAssetGenerationPanelView.tsx`)是怎么做的:**结构完全 一样**——面板 `submit()` 里 `draftReleasedRef.current = true` → `onSubmit({...})`(宿主 `submitResourceAssetGeneration` 同样返回 `void`)→ 无条件 `onClose()`;草稿也只在宿主受理 路径里落 `resourceAssetGenerationDraftRef`。所以它有同一个洞,但暴露面更小: · 宿主侧**只有** `!queue` 一条 early return(`index.tsx` 8166-8170),而这条如上所述不可达; · 它把「不能提交」的判据大多放在**面板内部**(空提示词 / 空素材名 / 参考失效 / 提示词超限 / 改了原请求输入),这些分支在 `draftReleasedRef.current = true` **之前**就 `return`,面板 不关、草稿不丢; · 图片类的「未受理重开」用的是 `resourceAssetGenerationPanelSubmissionRef` 里冻结的**整份** 草稿(含比例 / 尺寸 / 参考)重开,比音频「草稿槽 + 请求身份槽」两处拼装更自洽。 另外图片类每次提交都新铸 `taskId`(`crypto.randomUUID()`),没有音频这条「同占位必须复用 operation id」的判据——所以音频多出来的 ⑤ 是这次音频后台化新加的防线,不是图片类漏抄。 结论:真要修第 3 条,别只修音频面板——两个面板是同一份契约(都是 `onSubmit: (input) => void` + 提交即关),最好一次把「提交被同步拒绝时要不要关面板 / 要不要交回草稿」定成组件契约,两个 面板 + 两个宿主调用点 + 各自的用例一起改。 - 推荐修法(**为什么留给你**:这是改组件对外契约 + 改 UX 语义,不是我该单方面拍的): 1. `onSubmit` 改成能回报受理结果:`onSubmit: (input) => boolean | void`; 2. 面板侧 `const accepted = onSubmit({...}); if (accepted === false) { return; }`,只有受理 成功才 `draftReleasedRef.current = true` + `onClose()`(保留 `=== false` 而不是真值判断: 现有用例里传的是 `async () => undefined` 这类返回 Promise 的桩,非 `false` 一律按受理算); 3. 宿主侧 `submitResourceCanvasGeneration` 三个 early return 改成 `return false`、成功路径 `return true`。 影响面:`ResourceCanvasGenerationPanelView` 的 props 契约 + 宿主调用点 + 现有 「点提交即同步关闭」的用例断言(`resourceCanvasGenerationEntry.test.tsx` 等)。 不做这层的替代方案(在宿主里「重开面板」)不稳定:`submit()` 里 `onClose()` 跟在 `onSubmit()` 之后,同一事件里的 `setResourceGenerationDraft(...)` 会被随后的关闭覆盖掉。 - [x] 4 音频分支先落账本、后登记 live,留下「排队但还不 live」的竞态窗口(commit 7b1bc1d3e) - 位置:`apps/ai-game-creator-shell/src-tauri/src/asset_generation_tasks.rs` `start_local_project_asset_generation` 音频分支(原文指 531-543),以及同一函数的图片类分支。 - 原文结论:属实(bug · low),并且**不止音频**:图片类分支是同一种顺序,同样有这个窗口。 - 当前实现:`begin_local_project_*`(写排队记录、释放账本锁)→ 再 `live_task_ids().insert(task_id)` → 再 `spawn` 后台任务。 - 问题:`list_local_project_asset_generations` 的判据是「非终态 + 不在 live 集合 = 上次运行 的残留」,会调用 `repair_interrupted_tasks` 把它收口成 `failed` **并写回账本**。窗口期里并发 的那次 `list` 就会命中。判准确的后果:派发后的任务虽然会把 `status` 改回 `running`,但那次 收口留下的 `finishedAtMillis` / `error` 不会被清掉,而侧栏对 `task.error` 是**无条件渲染**的 → 会出现「一条正在跑的任务带着中断失败原因」的假象(任务真正结束时会清掉 error,所以不会 永久错乱,但显示是错的)。 - 已修:改成「先登记 live,再落账本」,落账失败时回滚。回滚判据用新函数 `register_live_task_id(task_id) -> bool`:只有**本轮真的插入了新 id** 才有资格回滚——否则 同 id 那个正在跑的任务的 live 登记会被误删,`list` 随后又把它谎报成上次运行的中断残留。 音频与图片两条分支都改(同一条命令、同一条顺序约束),并新增用例 `a_failed_ledger_write_only_takes_back_the_live_registration_it_inserted` 覆盖该回滚判据。 补充:同一份文档注释本来就写着「本进程派发的任务在 `start` 里先登记 live 再落账本」,这次是 把实现修成与注释一致。 - [x] 5 `source_media_type: Some("audio/mpeg")` 是死参数(commit ae0ab0ddf) - 位置:`apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs` `run_local_project_audio_generation_at`(原文指 5470-5473)。 - 原文结论:属实(maintainability · low)。 - 当前实现:该函数给 `derive_local_project_resource_at` 传 `generation_mode: Create` + `source_media_type: Some("audio/mpeg")`。 - 问题:`Create` 模式在 `resolve_resource_edit_source` 里**提前返回**,源快照的 `media_type` 由 `infer_resource_edit_source_media_type(edit_kind, source_path)` 推(音频恒为 `audio/mpeg`), 从头到尾不读 `input.source_media_type`。所以这个值对生成、对账本记录(账本存的是快照的 `media_type`)、对恢复通道(`resume_*` 从账本回填 + 兜底推断)都没有作用,纯误导。 - 已修(commit ae0ab0ddf):改成 `source_media_type: None`,并在函数文档里写明「Create 模式 不读 `input.source_media_type`」,避免下一个人又被它骗回去加一个值。 验证:`cargo test resource_edit -- --test-threads=1` 60 项全过(含所有音频 / 派生用例)。 文档同步(commit 98e42e6da):`docs/technical/【AGC】栏目画布底部工具栏入口矩阵-2026-09-13.md` 与 `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md` 第 7.9 节第 6 条原先都写着音频通道 「传 `sourceMediaType: 'audio/mpeg'`」,改成「源快照媒体类型由 `editKind` 推为 `audio/mpeg` (Create 模式不读该入参)」,与代码一致。
Author
Member

// TODO「提交被同步拒绝时要不要关面板 / 要不要交回草稿」is a question

// TODO「提交被同步拒绝时要不要关面板 / 要不要交回草稿」is a question
k88936 added this to the 陶泥儿gameAgent project 2026-09-21 00:30:08 +08:00
k88936 self-assigned this 2026-09-21 00:30:12 +08:00
k88936 added 5 commits 2026-09-21 00:37:20 +08:00
- `run_local_project_audio_generation_at` 提交 `derive_local_project_resource_at` 时把
  `source_media_type` 从 `Some("audio/mpeg")` 改成 `None`(`generation_mode: Create` 下源快照的
  媒体类型由 `edit_kind` 推出,这条通道根本不读该入参,留着会让读者以为它有作用)
- 该函数文档补一句说明「Create 模式不读 `input.source_media_type`」,避免后续又被加回去
- `start_local_project_asset_generation` 的音频分支改为一律先登记 live、再写排队记录(原先顺序
  相反,中间窗口里并发 `list_local_project_asset_generations` 会把这条排队记录当成上次运行的
  残留收口成失败)
- 图片类分支同一处顺序问题一并改正:同一条命令的两条通道共用同一条顺序约束
- 新增 `register_live_task_id`:登记并返回「本轮是否真的插入了新 id」,落账失败时只回滚本轮插入
  的那条登记,避免删掉同 id 那个正在运行任务的 live 登记
- 新增用例 `a_failed_ledger_write_only_takes_back_the_live_registration_it_inserted` 覆盖该回滚判据
- `resourceGenerationAudioSubmissionRef` 从单槽改成按任务 id 索引的 Map(键是 task id,值里
  不再重复存 taskId)
- 提交写入改成 `set(task.taskId, …)`,收口读取改成 `get(settlement.taskId)` + `delete`,切项目
  改成 `clear()`
- 原先两条音频提交重叠时,后一次提交会覆盖前一条的提交上下文,前一条「后端从未受理」的即时
  失败因此找不到自己的恢复上下文,只走通用失败提示、丢掉「面板连原草稿带回来」
- 新增宿主用例「两条音频提交重叠:第一条未被受理时,它的面板仍会被带回来」:给测试宿主加
  `holdFirstAssetGenerationStart` 开关,把第一次派发挂在受理前,复现两条提交重叠
- `docs/technical/【AGC】栏目画布底部工具栏入口矩阵-2026-09-13.md`:音频入口复用无源生成链路的措辞
  从「传 `sourceMediaType: 'audio/mpeg'`」改成「源快照媒体类型由 `editKind` 推为 `audio/mpeg`
  (Create 模式不读该入参)」
- `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md` 第 7.9 节第 6 条同口径修正,避免文档继续
  描述一个代码已经不传、也不会被读的参数
给生成面板的「提交被拒 + 草稿归属」加 TODO(只留标记,不改行为)
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 17s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 17s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust crates (pull_request) Failing after 18s
Project CI / AI game creator shell Rust smoke (pull_request) Failing after 19s
Project CI / Backend tests (pull_request) Failing after 18s
Project CI / Native shell tests (pull_request) Failing after 18s
Project CI / Frontend tests (pull_request) Failing after 8s
Project CI / Repository checks (pull_request) Failing after 16s
Project CI / AI game creator shell web tests (pull_request) Failing after 16s
04db93faab
- `ResourceCanvasGenerationPanelView.submit()` 加 `TODO(resource-generation-panel-contract)`:说明
  `onSubmit` 只返回 `void` 导致宿主同步拒绝时草稿没人接走的缺口,以及「`onSubmit` 回报受理结果、
  只有受理成功才置位 `draftReleased` 并关闭」的修法
- `ResourceCanvasAssetGenerationPanelView.submit()` 加同名 TODO:图片类面板与音频面板是同一份
  契约,要改一起改
- `index.tsx` 的 `submitResourceCanvasGeneration` 同步拒绝分支加同名 TODO:指向面板侧修法与
  「这里改成 `return false`」的宿主侧动作
k88936 added 1 commit 2026-09-21 00:48:28 +08:00
Merge branch 'master' into fix/let-bgm-and-sfx-async
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 17s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust crates (pull_request) Failing after 17s
Project CI / AI game creator shell Rust smoke (pull_request) Failing after 18s
Project CI / Backend tests (pull_request) Failing after 17s
Project CI / Native shell tests (pull_request) Failing after 17s
Project CI / Frontend tests (pull_request) Failing after 8s
Project CI / AI game creator shell web tests (pull_request) Failing after 15s
Project CI / Repository checks (pull_request) Failing after 15s
f19a003dec
k88936 merged commit 4be95f50ae into master 2026-09-21 00:48:49 +08:00
k88936 deleted branch fix/let-bgm-and-sfx-async 2026-09-21 00:48:49 +08:00
Sign in to join this conversation.