Files
cmshoppe/docs/tasks/T-679a.md
T

83 lines
4.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-679a
title: 商品套图自定义网关多来源任务状态机
phase: 7
deps: [T-678]
status: TODO
created: 2026-07-20
---
# T-679a 商品套图自定义网关多来源任务状态机
## 问题 / 背景
`app/image_studio_generation.py` 当前把运行时、提交、轮询和 job 来源硬编码为 cmhub。自定义网关是无 task ID 的同步图片编辑请求,不能复用 cmhub 的异步恢复模型;若只在现有分支上打补丁,停止、超时或程序中断时会出现已扣费图片丢失、误轮询或重复生成。
## 方案
### 1. 来源与运行快照
- 按 worker 启动时冻结的配置解析来源,不能读取运行中被⑤保存的新配置。
- 固定持久化语义:默认网关为 `generation_source="cmhub"`、`provider="cmhub"`;自定义网关为 `generation_source="direct"`、`provider="openai_images_edits"`。不得把用户填写的 URL、模型名或密钥写入来源字段、SQLite、日志或 UI。
- 自定义网关 job 的 `task_id` 必须为空;默认网关 job 的 task ID 只能由 cmhub 提交返回后写入。
### 2. 同步直连执行
- 复用 T-678 的有序多图图片编辑请求;每个 job 固定 `n=1`,直接取得图片字节后保存资产,不调用 `_poll_job()`。
- 默认网关路径的提交、轮询、下载和幂等键保持不变。分派必须按 job 的持久化来源而非当前设置判断,避免混合项目误走错误通道。
- 直连结果资产可不填 `remote_url`;不得为了填该字段额外拼接、记录或暴露上游地址。
- 将 `MAX_CMHUB_IMAGE_STUDIO_WORKERS` 改名为来源中立的并发常量,数值仍为 5;默认和直连共用全局上限,防止一次生成压垮本机或上游。
### 3. 停止、失败与不确定计费
- 停止只取消尚未发起的 job。已发出的同步请求不可强杀;如果已收到图片字节,必须先保存资产并标成功,停止只阻止后续 job。
- 直连请求提交后发生读超时、连接中断或进程退出时,客户端无法确认服务商是否已受理或计费:不自动重试,不自动恢复,不把该 job 放入“继续查询”。标失败并提供后续手动“重新生成”入口。
- 程序启动或进入项目时,遗留 `running` 的 direct job 统一标为失败,中文原因说明“程序中断,无法确认生成结果,请手动重新生成”;不得自动补发。
- 直连超时取冻结模型的 `connect_timeout_seconds` 和 `timeout_seconds`;若后者未设置,使用项目已有的受限默认值。不得使用 cmhub submit/poll/read timeout 常量。
### 4. 比例与参考图
- 套图比例固定映射:`1:1 -> 1024x1024`;`3:4`、`9:16 -> 1024x1536`;`4:3`、`16:9 -> 1536x1024`。后四种为近似映射,返回资产仍保存用户选择的原始比例。
- 任务层向调用方返回“是否近似比例”的结构化结果,T-679b 负责在确认框中告知用户;不得静默伪造精确比例。
- 首图主体与其余参考图的规则必须使用已冻结、已持久化的 job prompt;不能在 HTTP 调用层临时拼接,避免确认预览、历史 prompt 与实际请求不一致。
## 验收要点
- [ ] 可创建并执行 direct job,字段值精确为 `direct` / `openai_images_edits` / 空 `task_id`。
- [ ] direct 请求不调用 cmhub 提交、轮询、余额、价格或下载路径;cmhub job 行为不变。
- [ ] 已返回字节的 direct job 即使用户点击停止也会保存成功;未开始 job 才会取消。
- [ ] direct 不发生自动重试;遗留 `running` direct job 不会自动重发或进入继续查询。
- [ ] 比例映射、近似标记、`n=1`、多图顺序和 prompt 一致性有纯逻辑测试。
- [ ] 直连模型 URL、密钥与原始响应不进入 SQLite、事件日志或异常面向用户的文案。
## 测试与文档
- `tests/test_image_studio_generation.py`:来源分派、状态转移、停止边界、超时、遗留运行任务、比例映射、混合 job 防串路与无自动重试。
- `tests/test_image_studio.py`:来源字段和中断恢复的数据访问。
- 更新 `docs/04-architecture.md`、`docs/api.md`:记录两种来源 job 生命周期。
## 验证
```bash
py -3.10 -m unittest tests.test_image_studio_generation tests.test_image_studio tests.test_ai
py -3.10 -m ruff check app tests main.py
py -3.10 -m compileall app main.py
git diff --check
```
## 边界(不改什么)
- 不修改⑥按钮可用性、确认框、价格展示、历史 UI;见 T-679b/T-679c。
- 不改 cmhub 协议、幂等键和点数账本;不新增自动重试、provider 私有适配或接口探测。
- 不改图片理解、Chrome/CDP、Excel 或蝦皮更新流程。
## 关联
- T-678:直连图片编辑请求和多图契约。
- T-679b:消费本任务返回的来源、比例与停止语义。
- T-679c:消费本任务的中断状态与重试语义。
## 执行记录
(做完在这里写:变更文件、状态机决策、验证命令及结果。)