Files
cmshoppe/docs/tasks/T-590.md
T

48 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-590
title: AI工场托管模式多图异步生成编排与重启续查
phase: 7
deps: [T-586, T-564]
status: DONE
created: 2026-07-11
---
## 问题 / 背景
AI工场一次可生成 N 张,且每张都要独立计费、失败、重试、停止和续查。T-564 只为普通 tasks 表的一张封面保存一组 task_id/key,不能承载同商品多轮、多源图、多候选任务,需要把 cmhub submit/poll/download 能力复用到 image_studio_jobs。
## 方案
- 抽取可复用的 cmhub 异步生图客户端/服务,以持久化回调或 job repository 注入 task key/id;既有②路径行为保持兼容。
- 对同一源 asset 和同一完整提示词创建 N 条 job:一次调用一张,不按行拆词、不自动补动作、不保证去重。
- 每条 job 在 submit 前落稳定 key,202 后立即落 task_id;poll 成功下载校验后创建 generated asset,记录 main/detail、比例、父 asset、提示词和计费元数据。
- 并发沿用当前最大 5 的 submit+poll/下载双池保护;逐条事件回调供 GUI 显示。
- 停止不删除已提交任务:未开始 job 取消,已提交 job 停止等待并保留 task_id,下次继续查询。
- 本任务只实现 cmhub 托管来源;`generation_source/provider` 固定写入 `cmhub`,只作为状态自描述和后续兼容字段。本轮不展示或实现来源切换,自定义模型后置到 T-596。
## 验收要点
- N=3 产生 3 个不同 job/key/task,使用完全相同 prompt/source;每个成功独立进池。
- submit 响应后、poll 前 task_id 已落库;重启续查不再次 POST、不重复扣点。
- 单张失败不回滚成功图;下载失败不重新提交生成。
- 停止、总预算超时、服务端 failed/expired、幂等冲突和点数不足生命周期正确。
- 计费事件按 job 记录;全程不阻塞 GUI 主线程。
- 既有② AI生成 T-564 路径全量测试不回归。
## 边界(不改什么)
- 不做 BYOK、自定义 Provider、API Key、来源切换、自动去重或自动重生成。
- 不做 GUI、终选、导出、CDP 或蝦皮写操作。
- 不改变 cmhub 单次调用一张、预扣/失败退点契约。
## 执行记录
- 2026-07-11:完成 AI工场 cmhub 托管多图异步生成 service。
- 新增 `app/image_studio_generation.py`,不改现有② AI生成路径;AI工场单独使用 `image_studio_jobs/assets` 持久化 job/key/task_id/计费/状态和输出 asset。
- `generate_image_jobs()` 对同一源 asset + 完整提示词创建 N 条独立 job;每条 job 单独提交 `/api/v1/generate/image/tasks`,使用自身 `task_key` 作为 `Idempotency-Key`,submit 成功后立即写 `task_id/call_id/points_cost/points_balance`。
- `resume_image_jobs()` 对已有 `task_id` 的 `submitted/running` job 只 GET poll,不再 POST,避免重启续查重复扣点;poll 成功后下载保存 JPEG 到项目 `generated/` 并创建 `generated_main/generated_detail` asset,关联父源图、比例、提示词和远程 `image_url`。
- 单张失败只更新该 job 为 `failed`,不回滚其他成功图;下载失败发生在 poll 成功之后,不重新 submit、不创建输出 asset;停止语义保留已提交 job 的 task_id,未开始/可取消 job 标记 `cancelled`。
- 新增 `tests/test_image_studio_generation.py` 覆盖 N=3 独立 job/key/task、submit 后 poll 前已落库、续查不 POST、下载失败不重提交/不创建 asset、服务端单张 failed 不影响其他成功。
- 验证:在只套用 T-590 diff 的 clean worktree 中运行 `py -3.10 -m unittest tests.test_image_studio_generation tests.test_ai tests.test_db`(66 tests)、`python -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`py -3.10 -m unittest discover -s tests`(360 tests)和 `git diff --check`,全部通过。
- 本任务未接 GUI,也未打真实 cmhub 收费接口;T-591 接 UI 时应在 worker/QThread 中调用该 service,避免阻塞主线程。