文档:集成图生图客户端契约
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
| AI 编程模型代理错误 | OpenCode provider 请求 | Main Host AI proxy → Works 模型上游 | 配额耗尽保持独立终止态;只有明确的分组上游饱和才投影为 OpenCode 终止状态,通用限速仍保留 `429` |
|
||||
| 设计会话创建/切换 | AI 绘画页面或侧栏 | Renderer API → Main → Workspace Conversation API | 新会话属于现有 Workspace;读取独立消息、Brief、Quote 和 `turnRevision` |
|
||||
| 设计消息与确认 | 当前 Conversation | Main → 持久 Agent Gateway Session → Conversation 快照 | 请求和流式结果同时绑定 Workspace + Conversation |
|
||||
| 设计单图来源选择 | 当前 Workspace 已完成图片 / 本地图片 | 现有 Asset 上传或选择 → `attachmentAssetIds` → 当前 Conversation Turn | 图片 Brief 用作图生图参考图;视频 Brief 用作首帧;只提交一个真实 Workspace Asset ID |
|
||||
| 设计任务同步 | 任一 Conversation 的事件流 / REST | Renderer Workspace 任务列表 | Task 和 Asset 按 Workspace 归并,切换 Conversation 后仍可见 |
|
||||
|
||||
## State Ownership
|
||||
@@ -26,6 +27,7 @@
|
||||
- 本地构建临时目录、HTTP origin 和预检 WebContents/partition 只属于一次调用;预检读取与 `built_archive` 相同的内存字节,但结果不写为可信上传 receipt,也不覆盖生产 opaque-origin。
|
||||
- 旧 schema v1 `submitted` 记录迁移并保留;旧 `armed`、`waiting_for_package`、`waiting_for_login`、`uploading`、`failed` 归一为 `legacy_retired`,不再启动 watcher 或上传任务。
|
||||
- AI 绘画 Conversation 持有消息、Brief、Quote、`turnRevision` 和服务端 Session 绑定;Workspace 持有 Conversation 列表、生成任务和资产。
|
||||
- 图生图参考图与视频首帧都先归一为当前 Workspace 的 Asset;从作品选择时复用生成结果 Asset,本地选择时先走既有上传接口,再把唯一 Asset ID 随 Turn 提交。选择或上传成功后关闭选择器。
|
||||
- 本地开发适配器将旧单会话 schema v2 原子迁移为带默认 Conversation 的 schema v3;打包应用不使用该本地适配器作为云端失败回退。
|
||||
- 注销和退出会关闭本地事件流并清除本机 Conversation Session-id 缓存;服务端持久 Session 保留,下一次访问从 Conversation API 重新读取。
|
||||
- AI 编程 Store 的 `sessionMessagesBySessionId` own-key 是加载状态契约:键缺失表示历史未知,存在且值为 `[]` 表示已知为空。只有后者可使用不读取历史的快速选择;普通历史会话选择继续刷新消息。
|
||||
@@ -41,4 +43,4 @@
|
||||
|
||||
## Last Updated
|
||||
|
||||
2026-08-12
|
||||
2026-08-13
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
| `electron/image-workspace/works-square-workspace.ts` | Works Square 多 Conversation 云端适配器与 Gateway 事件映射 | 使用服务端持久 Session;本地清理不 DELETE 远端 Session |
|
||||
| `electron/image-workspace/local-workspace.ts` | 未打包开发模式的本地 Workspace 适配器和 v2→v3 迁移 | 仅开发使用,不得成为打包回退 |
|
||||
| `src/stores/image-workspace.ts` | 当前 Workspace/Conversation、项目任务及流式更新状态 | 异步结果按 Workspace + Conversation generation/revision 防护 |
|
||||
| `src/pages/ImageCanvas/index.tsx` | Conversation 对话、Quote 确认、统一任务列表与新会话入口 | Enter 发送、Shift+Enter 换行、IME 保护 |
|
||||
| `src/pages/ImageCanvas/index.tsx` | Conversation 对话、Quote 确认、统一任务列表、新会话入口与单图来源选择器 | 图片 Brief 选择/上传图生图参考图;视频 Brief 绑定首帧;均提交一个 Workspace Asset ID |
|
||||
| `src/components/layout/ImageWorkspaceSidebar.tsx` | Workspace 与近期 Conversation 切换/创建 | 切换会话不清空项目级任务 |
|
||||
|
||||
## Dependency Direction
|
||||
@@ -45,7 +45,8 @@
|
||||
- `ai-proxy.ts` 的上游饱和状态投影依赖当前固定 OpenCode 的重试语义和窄化错误文案;升级 runtime 或调整上游错误格式时必须复核,不能把所有 `429` 统一终止。
|
||||
- 多 Conversation 事件处理必须区分对话快照与 Workspace 任务更新;不得用任务时间戳推进 Conversation 流水位,也不得让旧会话的迟到流覆盖当前会话。
|
||||
- `closeEventSessions` 只负责本地流和缓存生命周期;远端 Conversation Session 是服务端持久资源。
|
||||
- 单图来源选择器当前仍由精确中文 quick reply 触发,并以 Brief medium 判断图生图或视频首帧用途;扩展更多输入用途前应先把消息协议升级为结构化 action/purpose,避免展示文案与行为继续耦合。
|
||||
|
||||
## Last Updated
|
||||
|
||||
2026-08-12
|
||||
2026-08-13
|
||||
|
||||
@@ -19,6 +19,7 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展
|
||||
| Built Artifact Preflight | 在上传前对最终 built snapshot 做桌面/移动 UX fail-fast | Main 使用临时 loopback origin 与 Electron WebContents/CDP;不使用 Playwright、不生成可信证明 |
|
||||
| AI Design Workspace | 保存项目身份、Conversation 列表、生成任务和资产 | 任务和资产在切换 Conversation 后继续可见 |
|
||||
| AI Design Conversation | 保存消息、Brief、Quote、`turnRevision` 与服务端 Agent Session 绑定 | 同一 Workspace 内互相隔离;Session 由服务端持久化 |
|
||||
| AI Design Image Source Picker | 当前 Workspace 已完成图片或本地上传 | 图片 Brief 绑定图生图参考图;视频 Brief 绑定首帧;提交一个真实 Asset ID |
|
||||
| AI Design Event Routing | Main 云端适配器 → Host API/SSE → Renderer store | Conversation 更新按 Workspace + Conversation 路由;任务更新按 Workspace 归并 |
|
||||
|
||||
## Important Boundaries
|
||||
@@ -37,11 +38,13 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展
|
||||
- AI 绘画中,一个 Workspace 可包含多条 Conversation;消息、Brief、Quote 和 `turnRevision` 属于 Conversation,生成任务和资产属于 Workspace。新建 Conversation 不得隐式创建新 Workspace。
|
||||
- 每条 Conversation 复用服务端持久 Agent Gateway Session。客户端不得在注销或退出时 DELETE 该 Session;只关闭本地事件流并清除本机 Session-id 缓存,重新访问时从 Conversation API 刷新。
|
||||
- Renderer 的异步与流式状态必须同时校验 Workspace + Conversation 身份;项目任务事件只按 Workspace 归并,避免切换会话时丢失任务或接收迟到消息。
|
||||
- 图片与视频复用同一个单图来源选择器。图片 Brief 可从当前 Workspace 的已完成作品或本地上传中选择一张参考图继续生成;视频 Brief 使用同一入口绑定首帧。两条路径都必须通过现有 Workspace Asset 上传/选择契约提交一个真实 `attachmentAssetIds`,不得用本地路径或自然语言描述代替资产身份。
|
||||
- 当前兼容协议仍通过精确 quick reply `从作品列表选择图片` 打开选择器,并由当前 Brief medium 区分用途;仅 `medium === image` 使用图生图语义,`video`、null 或缺失 medium 保持视频首帧语义。该展示文案耦合不得扩散到更多用途,后续应升级为结构化 action/purpose。
|
||||
|
||||
## Related Decisions
|
||||
|
||||
- 当前长期边界记录于 README、ADR-001、集成任务 `20260807-integrate-login-client-a4f8`、源任务 `20260810-static-release-only-a91c`、`20260812-client-built-release-makelore-7e5b` 及本次 Integration Gate;后续如改变唯一入口、凭据所有权、构建执行边界、Conversation 状态归属或重新引入客户端部署协调器,应新增 ADR。
|
||||
- 当前长期边界记录于 README、ADR-001、集成任务 `20260807-integrate-login-client-a4f8`、源任务 `20260810-static-release-only-a91c`、`20260812-client-built-release-makelore-7e5b`、`20260812-design-image-to-image-client-c91e` 及本次 Integration Gate;后续如改变唯一入口、凭据所有权、构建执行边界、Conversation 状态归属或重新引入客户端部署协调器,应新增 ADR。
|
||||
|
||||
## Last Updated
|
||||
|
||||
2026-08-12
|
||||
2026-08-13
|
||||
|
||||
@@ -13,12 +13,13 @@ This file is the integrated default-branch snapshot. Feature tasks record progre
|
||||
- `926056a`:Makelore 内置 Electron WebContents/CDP 发布前本地预览检查。
|
||||
- `5b44864`:Main-owned 本地 npm/Vite 构建、同字节 Electron 双视口预检、source+built 双归档与 artifact contract 上传。
|
||||
- `08da976` / `0ee5254`:AI 编程首次发送已知空 session 快速路径与明确上游饱和终止态投影。
|
||||
- `809364e` / `88281b8`:AI 绘画单参考图图生图选择/上传交互及其在最新客户端主线上的集成提交。
|
||||
|
||||
## Current Focus
|
||||
|
||||
客户端面向非专业用户提供“创建小游戏或小程序 → 项目配置中一键提交 → Main 本地 npm/Vite 构建 → Electron 双视口预检最终产物 → 上传 source+built 双归档与 contract → 运营审核”的唯一创建者链路。Main 对安全源码快照运行安装包内固定 npm 11.6.2 的 `npm ci --ignore-scripts`,再显式调用项目 `package-lock.json` 锁定的 Vite;Vite config/plugins 以当前桌面用户权限执行,因此只适用于用户信任的本地项目,不是 sandbox。预检由 Main 以临时 loopback origin 和 Electron WebContents/CDP 检查与最终 `built_archive` 相同的内存文件字节,覆盖桌面/移动视口、运行错误、白屏和外域访问;不使用 Playwright。该检查仍可由非官方客户端绕过,不产生可信 receipt,也不复刻生产 opaque-origin。服务端不再替客户端运行项目 Vite,而是把源码、构建归档和 contract 视为不可信输入,逐字节重算与校验并固化不可变 Release;人工审核仍不可绕过。自定义和缺少类型字段的旧项目不提供该入口。已发布作品优先使用安全投影后的 `play_url`,`runtime_url` 仅保留一个客户端版本的兼容回退。
|
||||
|
||||
AI 绘画的一个 Workspace 可包含多条 Conversation。消息、Brief、Quote 和 `turnRevision` 随 Conversation 隔离;生成任务和资产保持 Workspace 级共享。每条 Conversation 使用服务端持久 Agent Gateway Session,切换会话只重连对应事件流。
|
||||
AI 绘画的一个 Workspace 可包含多条 Conversation。消息、Brief、Quote 和 `turnRevision` 随 Conversation 隔离;生成任务和资产保持 Workspace 级共享。图片 Brief 支持文生图,以及从当前项目已完成作品或本地上传中选择一张参考图继续生成;视频复用同一选择器绑定首帧。两条路径都通过现有 Workspace Asset 契约提交一个真实 Asset ID。每条 Conversation 使用服务端持久 Agent Gateway Session,切换会话只重连对应事件流。
|
||||
|
||||
AI 编程首次发送在新建 OpenCode session 已知为空时不再等待冗余历史读取,prompt 可直接进入 Host API;普通历史会话仍刷新消息。Main AI proxy 只把明确的上游分组饱和投影为当前 OpenCode 的终止状态,配额耗尽保持独立终止态,通用限速继续保留 `429`。
|
||||
|
||||
@@ -32,6 +33,7 @@ AI 编程首次发送在新建 OpenCode session 已知为空时不再等待冗
|
||||
- 2026-08-12:一键提交前复用当前项目的内置浏览器 loopback preview,以 fresh 临时 Electron WebContents/CDP 执行桌面/移动 UX 预检;服务端仍执行唯一受控构建、不可变 Release 安全门禁和人工审核。
|
||||
- 2026-08-12:发布架构反转为 Main-owned 本地构建;固定 npm 11.6.2 按项目 lockfile 安装并执行项目 Vite,Electron 预检最终上传同字节产物,再上传 source+built 双归档和严格 contract。服务端仅校验并固化不可信字节,不再承担项目 Vite 构建。
|
||||
- 2026-08-12:AI 编程新 session 的首条 prompt 不再被已知空历史读取阻塞;明确上游分组饱和会快速终止,通用 `429` 仍保持原有限速语义。
|
||||
- 2026-08-13:AI 绘画把原视频首帧选择器泛化为单图来源选择器;图片 Brief 可选择项目作品或上传本地图作为图生图参考图,视频及未决 medium 保持历史首帧行为,成功提交后关闭弹窗。
|
||||
|
||||
## In Progress
|
||||
|
||||
@@ -62,7 +64,8 @@ AI 编程首次发送在新建 OpenCode session 已知为空时不再等待冗
|
||||
- 服务端持久 Conversation Session 不由客户端在注销或退出时删除;Main 只关闭本地流、清除本机缓存并撤销本地凭据。
|
||||
- 客户端对最终构建字节的 loopback 检查没有可信 receipt,且不复刻生产 opaque-origin;服务端必须独立重算 source/built/contract、校验不可变 Release,人工审核仍不可绕过。如未来需要不可绕过的 runtime gate,必须引入可信 verifier 并绑定精确构建产物。
|
||||
- AI proxy 的明确饱和 `429 → 400` 是与当前 OpenCode 重试契约匹配的内部投影;升级 OpenCode 或上游饱和错误文案变化时必须复核。不得把通用 `429` 或仅含 `rate_limit_exceeded` 的响应误分类为终止饱和。
|
||||
- AI 绘画单图选择器仍精确匹配 quick reply `从作品列表选择图片`,用途再从当前 Brief medium 推断;本地化或协议文案变化可能破坏入口。扩展更多素材输入前应升级为结构化 action/purpose。
|
||||
|
||||
## Last Updated
|
||||
|
||||
2026-08-12
|
||||
2026-08-13
|
||||
|
||||
@@ -39,15 +39,42 @@
|
||||
|
||||
## Outcome
|
||||
|
||||
- Not completed.
|
||||
- Merged reviewed feature commit `809364e` into the current `a03043d` client
|
||||
baseline with merge commit `88281b8`; Git resolved the overlapping
|
||||
`ImageCanvas` and page-test history without source conflicts and preserved the
|
||||
existing first-conversation work.
|
||||
- Promoted the generalized single-image picker, one-Asset attachment boundary,
|
||||
image/video/null-medium behavior, exact-string compatibility risk and
|
||||
production-smoke obligation into the current canonical project memory.
|
||||
- README now describes text-to-image, single-reference image-to-image, project
|
||||
work selection and local upload on top of the latest client product state.
|
||||
|
||||
## Verification
|
||||
|
||||
- Not run.
|
||||
- Source merge preflight used `git merge-tree` against current `main`; only the
|
||||
README paragraph needed an overlapping semantic merge and the final merge
|
||||
completed automatically.
|
||||
- `pnpm install --offline --frozen-lockfile`: passed with the pinned pnpm;
|
||||
dependencies were restored entirely from the local store.
|
||||
- `pnpm exec vitest run tests/unit/image-canvas-page.test.tsx`: `25 passed`.
|
||||
- `pnpm run typecheck`: passed.
|
||||
- `pnpm exec eslint src/pages/ImageCanvas/index.tsx
|
||||
tests/unit/image-canvas-page.test.tsx`: passed.
|
||||
- `pnpm run build:vite`: passed for Renderer, Main and Preload; emitted only the
|
||||
repository's existing dynamic-import and chunk-size warnings.
|
||||
- `git diff --check`: pending after final documentation edits.
|
||||
- `check_project_docs.py`: passed.
|
||||
- `check_doc_drift.py --task-id 20260813-integrate-i2i-client-main-5d9e`:
|
||||
passed after keeping the source task record read-only on its source branch,
|
||||
matching the repository's established Integration Gate pattern.
|
||||
- Packaged desktop and live Works Square/Bailian provider smoke were not run.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- None recorded.
|
||||
- Replace exact localized quick-reply matching with a structured asset-picker
|
||||
action/purpose before adding more input modes or changing that label.
|
||||
- Run packaged-desktop and live Works Square/Bailian image-to-image smoke after
|
||||
the matching client and server releases are deployed.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
- Conversation 持有消息、Brief、Quote 和 `turnRevision`;生成任务和资产属于 Workspace,切换 Conversation 后必须继续可见。
|
||||
- 每条 Conversation 使用服务端持久 Agent Gateway Session。客户端注销或退出时只关闭本地流并清除本机 Session-id 缓存,不删除服务端 Session。
|
||||
- Conversation 异步与流式更新必须同时核对 Workspace 和 Conversation 身份;任务事件按 Workspace 归并。
|
||||
- 图片生成支持无参考图的文生图和单参考图图生图;参考图必须来自当前 Workspace 的已完成图片 Asset,或先通过现有 Workspace 上传接口把本地图片转成 Asset,再随当前 Conversation Turn 提交唯一 Asset ID。
|
||||
- 视频首帧与图生图参考图复用单图选择器,但用途由当前 Brief medium 决定:只有明确 `image` 使用图生图语义,`video`、null 或缺失值保持视频首帧兼容语义。选择作品或上传成功后应关闭弹窗。
|
||||
- 当前 quick reply 文案匹配只是兼容契约;新增更多素材输入用途前,应改为结构化 action/purpose,不得继续依赖本地化展示字符串推断行为。
|
||||
|
||||
## Open Questions
|
||||
|
||||
@@ -31,7 +34,8 @@
|
||||
- 是否需要在生产发布链引入绑定精确 Release/digest 的可信 runtime verifier;当前客户端 loopback preflight 不能承担该职责。
|
||||
- 在一个客户端兼容版本且服务端与存量数据稳定提供 `play_url` 后,移除 `runtime_url` 回退。
|
||||
- 多 Conversation 客户端发布前需确认服务端迁移 `0033`、Conversation API 与持久 Session 契约已经部署。
|
||||
- 图生图随客户端发布前,需确认相匹配的服务端 `image_to_image` Brief/Quote/Task 冻结、私有源图复核与 Bailian edit 执行链已部署,并使用真实 Workspace Asset 完成生产 smoke。
|
||||
|
||||
## Last Reviewed
|
||||
|
||||
2026-08-12
|
||||
2026-08-13
|
||||
|
||||
@@ -9,6 +9,7 @@ Use this index for searchable, traceable evidence records.
|
||||
| 2026-08-12 | Makelore 内置浏览器发布前预检 | 本地功能验证通过;不构成可信发布证明 | `30-worklog/tasks/20260812-client-browser-preflight-c8e2.md`、`926056a` | 121 项聚焦回归、typecheck、scoped lint、三端 build 与真实 Electron 双视口 E2E 通过;loopback UX 预检无 receipt/provenance/opaque-origin parity,服务端门禁仍需生产整链验收 |
|
||||
| 2026-08-12 | Makelore Main-owned 本地静态 Release 构建 | 本地功能与 Windows 安装产物验证通过;安装器未发布 | `30-worklog/tasks/20260812-client-built-release-makelore-7e5b.md`、`5b44864` | 6 files / 129 focused tests、typecheck、scoped lint、Vite build、真实 Electron 双视口 E2E 与实际 npm/Vite smoke 通过;安装器 223,547,912 bytes,SHA-256 `08A0BB7BC66EE4AD8B120E8955B149951CD86AF53CC966C7973AD4D77A5815C1`,内置 npm 11.6.2 已由 packaged verifier 验证,但未上传或发布 |
|
||||
| 2026-08-12 | AI 编程首次会话等待与上游饱和重试 | 本地功能验证通过;真实冷启动各阶段耗时尚未遥测 | 源任务 `20260812-first-chat-fix-b84fd29c`、`08da976`、`0ee5254` | 4 个相关单测文件 228/228、typecheck、scoped lint、Vite build 与真实 Electron E2E 通过;全量单测的 3 个失败与 `main` 基线一致,修复证明 prompt 不等待已知空历史,但不宣称消除所有 runtime 冷启动耗时 |
|
||||
| 2026-08-13 | AI 绘画单参考图图生图客户端 | 本地功能验证通过;未执行安装包或真实 Provider smoke | 源任务 `20260812-design-image-to-image-client-c91e`、`809364e`、集成 `88281b8` | 聚焦页面测试覆盖图片作品选择、本地上传、视频首帧及 null-medium 兼容;typecheck、scoped lint 与 Vite build 在集成头重跑,生产部署与付费生成另行验收 |
|
||||
|
||||
## When To Add Evidence
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ Track future-facing memory: promised follow-ups, unfinished loops, timed checks,
|
||||
| 2026-08-10 | 删除客户端 `runtime_url` 兼容回退 | 一个客户端兼容版本结束,且服务端与存量数据稳定提供 `play_url` | 客户端 | Pending | 删除类型字段、读取分支和对应回归测试 |
|
||||
| 2026-08-11 | 部署并验收 AI 绘画多 Conversation 服务端契约 | 发布包含多会话客户端之前 | 客户端/服务端集成 | Pending | 确认迁移 `0033`、Conversation list/create/read/turn/confirm API、持久 Agent Session 与事件字段已上线 |
|
||||
| 2026-08-12 | 复核 AI 编程上游饱和终止态投影 | 升级 bundled OpenCode 或上游饱和错误格式时 | 客户端/OpenCode 集成 | Pending | 重新验证 retry contract;继续区分配额耗尽、明确分组饱和与通用 `429`,必要时调整或移除 `429 → 400` 内部投影 |
|
||||
| 2026-08-13 | 将 AI 绘画素材选择 quick reply 升级为结构化 action/purpose | 新增第三种素材输入用途、调整本地化文案或重构 Design Message 协议时 | 客户端/服务端集成 | Pending | 用 `select_image_asset` + `image_reference | video_first_frame` 等稳定字段替代精确中文字符串匹配,并覆盖延迟 Brief 快照兼容 |
|
||||
| 2026-08-13 | 完成图生图客户端与服务端生产整链 smoke | 相匹配客户端与服务端部署后 | 客户端/服务端集成 | Pending | 用当前 Workspace 已完成作品与本地上传各执行一次图生图,核对 Asset 所有权、Quote、任务创建、结果展示与下载;不以本地单测替代付费 Provider 验收 |
|
||||
|
||||
## Use
|
||||
|
||||
|
||||
Reference in New Issue
Block a user