合并最新master到M0A-2开发分支
同步 origin/master 至 3c457feb4c
保留 M0 固定 owner 验证、本人 smoke、试玩执行者与动态 Canvas 谱系合同
通过 114 项完成合同回归、动态 Canvas 精确回归及格式编码检查
This commit is contained in:
@@ -3273,7 +3273,7 @@
|
||||
"none",
|
||||
"pixelArt"
|
||||
],
|
||||
"description": "可选生成风格,当前识别 none 与 pixelArt。省略、null、空字符串或 none 按无风格处理,提交给 provider 的提示词与未带该字段时逐字一致;pixelArt 仅支持普通图片(kind 省略)和 character,会在提示词末尾追加一行像素风约束(普通图片为「画面为像素风格」,character 为「角色主体为像素风格」)并在回图后执行像素规整。未知字符串或不支持该风格的 kind 按 none 继续生成并返回 unsupported-image-style 告警;非字符串值返回 400。"
|
||||
"description": "可选生成风格,当前识别 none 与 pixelArt。省略、null、空字符串或 none 按无风格处理,提交给 provider 的提示词与未带该字段时逐字一致;pixelArt 仅支持普通图片(kind 省略)和 character,会在提示词末尾追加一行像素风约束(普通图片为「画面为像素风格」,character 为「角色主体为像素风格」)并在回图后执行像素规整。规整成功时直接持久化一格一像素的逻辑分辨率 PNG,不恢复到 size、imageSize、provider 回图或 canvasCompletion.placeholder 的尺寸;width/height 及关联 resource/asset 尺寸均为最终 PNG 的实际值。未知字符串或不支持该风格的 kind 按 none 继续生成并返回 unsupported-image-style 告警;非字符串值返回 400。"
|
||||
},
|
||||
"size": {
|
||||
"type": "string",
|
||||
@@ -3385,7 +3385,7 @@
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "带项目上下文生成时,服务端据此直接写入画布完成态并返回最新项目快照。"
|
||||
"description": "带项目上下文生成时,服务端据此直接写入画布完成态并返回最新项目快照。placeholder 只参与占位与完成落点,不约束最终媒体像素尺寸;pixelArt 规整成功时结果图层使用最终逻辑分辨率 PNG 的实际尺寸。"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -3578,11 +3578,13 @@
|
||||
},
|
||||
"width": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
"minimum": 1,
|
||||
"description": "最终持久化 PNG 的实际像素宽度;pixelArt 规整成功时为逻辑网格宽度,不保证等于 size、imageSize、provider 回图或画布 placeholder 宽度。"
|
||||
},
|
||||
"height": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
"minimum": 1,
|
||||
"description": "最终持久化 PNG 的实际像素高度;pixelArt 规整成功时为逻辑网格高度,不保证等于 size、imageSize、provider 回图或画布 placeholder 高度。"
|
||||
},
|
||||
"sourceType": {
|
||||
"type": "string",
|
||||
@@ -3698,7 +3700,7 @@
|
||||
"none",
|
||||
"pixelArt"
|
||||
],
|
||||
"description": "可选生成风格,当前识别 none 与 pixelArt。省略、null、空字符串或 none 按无风格处理,提交给 provider 的提示词与未带该字段时逐字一致;pixelArt 会在提示词末尾追加一行「每个图标素材均为像素风格」并启用图标图集像素规整。未知字符串按 none 继续生成并返回 unsupported-image-style 告警;非字符串值返回 400。"
|
||||
"description": "可选生成风格,当前识别 none 与 pixelArt。省略、null、空字符串或 none 按无风格处理,提交给 provider 的提示词与未带该字段时逐字一致;pixelArt 会在提示词末尾追加一行「每个图标素材均为像素风格」并启用图标图集像素规整。规整成功时直接持久化一格一像素的逻辑分辨率透明 PNG,不恢复到 imageSize、provider 回图或 canvasCompletion.placeholder 的尺寸;spritesheetWidth/spritesheetHeight 及关联 resource/asset 尺寸均为最终 PNG 的实际值。未知字符串按 none 继续生成并返回 unsupported-image-style 告警;非字符串值返回 400。"
|
||||
},
|
||||
"model": {
|
||||
"type": "string",
|
||||
@@ -3756,7 +3758,7 @@
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "带项目上下文生成时,服务端据此直接写入画布完成态并返回最新项目快照。"
|
||||
"description": "带项目上下文生成时,服务端据此直接写入画布完成态并返回最新项目快照。placeholder 只参与占位与完成落点,不约束最终媒体像素尺寸;pixelArt 规整成功时结果图层使用最终逻辑分辨率 PNG 的实际尺寸。"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
@@ -3919,7 +3921,7 @@
|
||||
"unsupported-image-style",
|
||||
"multiple-generation-warnings"
|
||||
],
|
||||
"description": "生成成功但后处理发生非阻断降级时的稳定原因码。"
|
||||
"description": "生成成功但后处理发生非阻断降级时的稳定原因码。dimension-restore-fallback 只描述进入可选 pixelArt 处理前的交付尺寸归一结果:无法安全归一时,在该处理边界保留 provider 回图尺寸;它不描述或约束 pixelArt 成功后的最终尺寸,最终产物尺寸仍以逻辑分辨率 PNG 为准。"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
@@ -3945,11 +3947,13 @@
|
||||
},
|
||||
"spritesheetWidth": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
"minimum": 1,
|
||||
"description": "最终持久化 spritesheet PNG 的实际像素宽度;pixelArt 规整成功时为逻辑网格宽度,不保证等于 imageSize、provider 回图或画布 placeholder 宽度。"
|
||||
},
|
||||
"spritesheetHeight": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
"minimum": 1,
|
||||
"description": "最终持久化 spritesheet PNG 的实际像素高度;pixelArt 规整成功时为逻辑网格高度,不保证等于 imageSize、provider 回图或画布 placeholder 高度。"
|
||||
},
|
||||
"iconImageSrcs": {
|
||||
"type": "array",
|
||||
@@ -4948,7 +4952,7 @@
|
||||
}
|
||||
},
|
||||
"additionalProperties": true,
|
||||
"description": "其它生成类型或历史结果的兼容 compact result。背景音乐(audioKind=background-music)与不带 audioKind 的图片、视频、图标序列帧、角色动作和 UI 拆解结果都落在这里。该 fallback 明确排除 audioKind=sound-effect,避免吞掉 SFX 专用分支。"
|
||||
"description": "其它生成类型或历史结果的兼容 compact result。背景音乐(audioKind=background-music)与不带 audioKind 的图片、视频、图标序列帧、角色动作和 UI 拆解结果都落在这里。pixelArt 图片的 width/height、图标结果的 spritesheetWidth/spritesheetHeight 及关联 resource/asset 尺寸均表示最终逻辑分辨率 PNG 的实际值,不保证等于请求档位、provider 回图或画布 placeholder。该 fallback 明确排除 audioKind=sound-effect,避免吞掉 SFX 专用分支。"
|
||||
},
|
||||
"ExternalEditorGenerationCompletedResult": {
|
||||
"oneOf": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AI 游戏创作项目开发工作台 PRD
|
||||
|
||||
更新时间:`2026-08-05`(实时 manifest 与资源焦点状态机收口)
|
||||
更新时间:`2026-08-10`(现有 Godot 项目入口与项目根绑定)
|
||||
|
||||
## 1. 产品定位
|
||||
|
||||
@@ -83,6 +83,13 @@
|
||||
- 未开放选项使用“视觉不可用但可点击说明原因”,不使用无法触发说明的原生 `disabled`。
|
||||
- 普通用户暂不开放 Agent.md 编辑和自定义 Skill 安装;后续必须先定义来源审核、版本、权限、沙箱和回滚合同。
|
||||
|
||||
### 3.7 现有 Godot 项目
|
||||
|
||||
- 首页和项目组复用同一个“打开 Godot 项目”动作,用户选择的目录必须包含普通文件 `project.godot`。
|
||||
- 该目录直接成为当前项目根;后续文件读取、修改、命令 cwd、对话、Runtime 和最近项目记录都绑定这个根目录,不复制工程,也不建立 `game/`、`assets/`、`memory/`、`exports/` 平行目录。
|
||||
- 首次打开只在项目根创建 `.agent/` 元数据;已有 `.agent/manifest.json` 时读取并保留。Godot 源码、场景、资源和项目配置继续使用原目录结构。
|
||||
- Godot 项目使用 `standard` Run Profile,避免套用 Web 原型的 `game/index.html`、本地 HTTP 预览和自主 Web 游戏完成门;本期不提供 Godot 内嵌运行预览。
|
||||
|
||||
## 4. 工作台状态机
|
||||
|
||||
### 4.1 主视窗
|
||||
|
||||
@@ -6922,3 +6922,55 @@
|
||||
- 一致性:`start-tauri-dev.mjs` 是端口选择权威,最终端口通过 Tauri CLI `--config` 覆盖 `build.devUrl`,通过 `GENARRATIVE_AGC_VITE_PORT` 传给 `beforeDevCommand` 和配套后端端口解析器,并通过 Vite CLI `--port` 启动严格监听。父启动器选定端口后,子启动器只允许严格使用同一端口,配套后端漂移必须跳过该预留端口,竞态占用必须失败关闭。
|
||||
- 安全边界:动态端口不恢复旧 Vite 复用。无法证明 worktree 归属的监听器仍不复用、不主动终止;同用户多 worktree 通过段内漂移并行,不通过共享未知服务并行。
|
||||
- 验证:公共端口映射、Linux 默认槽位与段内漂移、非 Linux 兼容漂移、Tauri 动态配置、启动前预检、进程树收束、AGC typecheck / 配置门禁、编码检查和差异检查必须通过。
|
||||
|
||||
## 2026-08-10 完美像素最终持久化逻辑分辨率 PNG
|
||||
|
||||
- 背景:SpriteFusion Pixel Snapper 上游在网格采样后直接输出 `(列切线数 - 1) × (行切线数 - 1)` 的逻辑图,每个检测单元恰好对应一个输出像素。Genarrative 首版在此后增加了 nearest 输入尺寸恢复;当输入宽高不能被逻辑列数、行数整除时,最近邻只能把同一逻辑像素分配到 `floor / ceil` 数量不等的目标列或行,最终物理像素块宽窄不一。已有 `128 → 64` 的整数倍测试没有覆盖该问题。
|
||||
- 决策:生成请求勾选 `style="pixelArt"` 与已有图片手动 `POST /api/editor/images/pixel-art-snaps` 共用同一输出语义:snapper 直接编码并持久化唯一的逻辑分辨率 PNG,不再 nearest 恢复到源图、RGBA 输入、业务交付或 generation dialog 占位尺寸。成功输出宽高固定为 `(columns.len() - 1) × (rows.len() - 1)`,允许与输入、交付和占位尺寸不同;响应、project resource、账号素材和结果 layer 一律记录最终 PNG 的实际宽高。
|
||||
- 保留边界:普通图片和角色在规整前执行的 Lanczos 交付尺寸归一继续保留;角色 / 图标的平底网格分析源与透明 RGBA 采样源仍必须同尺寸,Alpha 覆盖、Alpha 加权 RGB、二值 Alpha、P30 步长估算、确定性采样、输入上限、deadline、strict 无网格拒绝和失败降级尺寸守卫全部不变。这些约束保护输入坐标系、资源安全或失败路径,不构成成功输出与输入同尺寸的承诺。
|
||||
- 持久化边界:数量增量保持不变。普通图片只保存一张最终逻辑主图;角色保留一张 provider 原图与一张最终透明逻辑主图;图标保留一张 provider 原图、一张最终透明逻辑图集和原有成功切片;手动完美像素只保存一张最终逻辑 PNG。不得另外保存输入尺寸恢复版、像素化前后双份主图、预览、诊断或报告,不修改 asset kind、队列类型、数据库 schema、路由或请求 / 响应字段形状。
|
||||
- 跨版本重放:手动入口算法指纹升为 `perfect-pixel-v2`。同一稳定 operation 已有结果时,candidate object key 相同才继续既有 exact replay;key 不同或既有稳定资源缺 key 时,必须在 preflight 与 OSS PUT 前返回 `409 + operationResultAlreadyExists=true`,由客户端 GET 权威项目收口,不得冒充本次请求已经设置 `resultPersistenceStarted`。preflight 到最终提交之间仍无数据库 reservation,滚动发布必须排空旧算法实例,不能把该护栏解释为消除了并发 TOCTOU。
|
||||
- 历史边界:本条覆盖 2026-07-28 首发决策中“逻辑结果 nearest 恢复交付尺寸 / 逻辑图不持久化”和 2026-07-30 手动入口中“右侧新增同尺寸 PNG / 不保存逻辑低分辨率图”的旧口径;旧条目作为历史记录保留,不回写改造。
|
||||
- 关联文档:`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`、`docs/【编辑器】画板角色形象生成入口设计-2026-06-15.md`、`docs/【编辑器】画板图标素材生成入口设计-2026-06-15.md`、`docs/【编辑器】图片画布结构化持久化与迁移回滚方案-2026-07-19.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
|
||||
|
||||
## 2026-08-10 AGC 默认使用 Codex CLI 作为节点 Agent
|
||||
|
||||
- 决策:AGC AppData 配置新增 `agentMode=codex_cli|provider`,默认切到 `codex_cli`,原 HTTP Provider 实现、配置和显式回退能力保持不变。External Runner 和现有 manifest DAG 不分叉;每个节点请求在现有 Provider lifecycle 外壳内选择执行器。
|
||||
- 安全:Codex CLI 只负责结构化推理。它在空临时目录、ephemeral、忽略用户配置、read-only、never approval、禁用 shell tool 的边界内运行;项目读写、命令、MCP、Canvas、权限、revision、验证、receipt 和 reconciliation 仍由 AGC Runtime 执行。Codex 认证留在用户级 CLI,任何凭据和认证文件都不进入项目事实。
|
||||
- 恢复:执行模式和 CLI 身份进入 Provider 配置指纹;模式或 CLI 变化会使旧 retry/handoff 作废并沿现有恢复合同处理,禁止跨模式复用成功交接或自动重放未知结果。
|
||||
- 关联:`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md` V1.51,以及 `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md` 的“2026-08-10 Codex CLI Agent 执行模式”。
|
||||
|
||||
## 2026-08-10 AGC 默认切换为 Codex app-server 长期节点 Agent
|
||||
|
||||
- 决策:新增 `agentMode=codex_app_server` 并设为默认,保留 V1.51 的一次性 `codex_cli` 与原 `provider`。External Runner 内按有效 Responses 凭据/路由及 `projectId/agentId/sessionId/runId` 为每个权威节点隔离长期 app-server;稳定节点 run 对应独立进程和 ephemeral thread,节点请求对应串行 turn,但 AGC lifecycle、handoff、manifest、Agent DB 和 finalization 仍是唯一 durable owner。单节点 stdio/进程失败只能影响本节点,不得把其它并发 Agent 一并置为 reconciliation。
|
||||
- 配置:有无 AGC LLM Key 都只支持 `openai_responses`;非空 Key 映射后 base URL 与逐 Agent model/effort 生效,Key 只经专用环境变量;空 Key 只桥接用户 Codex `auth.json`,移除继承环境 Key。`stream=true` 复用现有 durable final-reply delta;`webSearchEnabled=true`、`openai_chat / anthropic` 必须显式切换 `provider`,不得静默忽略已有 LLM 配置。
|
||||
- 安全与恢复:app-server 使用隔离临时 `CODEX_HOME` 与 OS HOME,只桥接认证,不加载用户 MCP/config/skills/hooks;启动前关闭 web/multi-agent/shell/browser/plugin/image 等原生能力,固定 read-only、network off、never approval,AGC 是唯一 ToolHost。取消覆盖 turn-start 回包前窗口并只发送单 turn interrupt;已开始 turn 的连接/终态未知直接标记 reconciliation,明确 failed/interrupted 不自动重试。模式与 durable 指纹取同一配置快照。
|
||||
- 资源与退出:pool 按实际凭据快照/base URL/API kind/CLI 版本和节点 run 身份隔离;空 AppData Key 只允许桥接一次性读取的有界 `auth.json` 快照,并用同一字节快照生成池指纹,宿主 `CODEX_API_KEY` 对 app-server 与一次性 CLI 都必须移除。节点进程与 thread 均有上限并只淘汰 inactive LRU;stdout NDJSON 与 stderr 无换行记录均有硬上限,stderr 原文不得写入错误或日志,只记录固定分类、总字节数、SHA-256 与可取得的退出状态。Runner 正常、强制、watchdog 退出显式关池;Linux child 绑定 parent-death signal,避免 Runner 被强杀后遗留带凭据孤儿进程。
|
||||
- 兼容迁移:已有 AppData 未写 `agentMode` 时,仅当全局及逐 Agent 都是 `openai_responses` 才迁入 app-server;任何 `openai_chat / anthropic` 路由保持 `provider`,防止项目自动恢复先于用户改配置而批量失败。新安装仍默认 app-server;已确认兼容 Responses 的旧端点可由用户显式切换且继续使用原 model/base URL/API Key。
|
||||
- 关联:`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md` V1.52。
|
||||
|
||||
## 2026-08-10 Supervisor steer 改为 LLM 判定后的条件中断
|
||||
|
||||
- 决策:根 Project Supervisor 收到运行中消息后继续原 Run,先由独立 LLM 生成非终态回复并判断 `interruptCurrentProvider`。状态询问、解释和不冲突补充默认不中断;只有明确停止、改向或在途方案会过期时才可请求中断。过程回复持久进入原 conversation,但不得调用终态 `respond_to_user`。
|
||||
- 时序:steer durable 入队后不先通知 Runner。`false` 或判定失败才调用只唤醒的 `runtime.steer`;`true` 直接调用 `runtime.interrupt_for_steer_decision`。后者必须读取已持久化判定,并只中断 `appliedSteerCursor < steer.sequence` 的旧 Provider;新规划 Provider、工具和外部副作用不可被误杀。
|
||||
- 失败:判定调用、协议解析或持久化失败时公开回复“继续当前任务”,在下一安全边界应用 steer,绝不退化为默认中断。External Runner 与本地进程内执行保持同一语义。
|
||||
- 关联:`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md` V1.53,以及 `docs/project-memory/shared-memory/pitfalls.md` 的“Supervisor steer 不能只有内部排队事件”。
|
||||
|
||||
## 2026-08-10 AGC 普通 release 固定连接 dev API
|
||||
|
||||
- 决策:普通 AGC Tauri release 的平台认证与客户端 API 固定访问 `https://dev.genarrative.world/api/*`;本地 `npm run agc` 继续使用 Vite `/api` 代理,普通网页构建继续使用同源相对路径,game-chat release 继续绕过平台登录。
|
||||
- 传输边界:dev 公网入口不接受 Tauri WebView 的跨域 OPTIONS 预检,因此 release 使用 `tauri-plugin-http` 原生 transport。插件的 npm 依赖只归属 AGC 子包及其 lockfile,根 H5 package 与根 lockfile 不得引入任何 Tauri guest 依赖。插件 capability 与前端 URL 解析双重限制为 `https://dev.genarrative.world/api/*`,不为 WebView CSP 增加远程 `connect-src`,也不开放任意 HTTP(S) 目标。
|
||||
- 会话边界:插件默认 Cookie Store 持久化 refresh Cookie;访问 Token 继续保存在现有客户端存储并通过 Authorization header 发送,不把 Token、Cookie 或登录正文写入日志、配置文件或仓库。
|
||||
|
||||
## 2026-08-10 AGC monorepo 构建强制复用单一 React runtime
|
||||
|
||||
- 根因:AGC 子目录存在独立 `node_modules` 时,AGC 源码会解析子目录 React,而仓库共享组件解析根目录 React;登录页不依赖共享 Hooks,进入首页后才触发 `Cannot read properties of null (reading 'useCallback')` 并白屏。
|
||||
- 决策:AGC Vite 配置必须对 `react` 与 `react-dom` 启用 `resolve.dedupe`,release 和本地构建统一复用仓库根 React runtime。登录后内容保留错误边界,渲染异常必须显示可恢复提示,不能再次退化为无提示白屏。
|
||||
|
||||
## 2026-08-10 AGC 打开现有 Godot 项目
|
||||
|
||||
- 项目根决策:项目首页与项目组提供同一“打开 Godot 项目”能力;被选目录需包含普通文件 `project.godot`,选中目录本身即为文件工具、命令与 Agent Runtime 的唯一项目根,不复制工程或建立第二套工作区。
|
||||
- 元数据决策:首次导入只创建并保留项目根下的 `.agent/manifest.json`、`.agent/agent.db`、`.agent/logs/` 与 `.agent/runtime/`;不得创建默认 Web 原型的 `game/`、`assets/`、`memory/`、`exports/`。已有有效 `.agent` 项目只读复用身份,不覆盖 manifest。
|
||||
- Windows 锁文件决策:提升权限进程新建 `.agent/.manifest.json.lock` 时,Windows 可能把 owner 设为 `Administrators`。仅在固定锁路径已取得不共享独占句柄并确认是普通、非 reparse、单链接文件后,才初始化为当前 `TokenUser`;随后再次复核句柄并执行原有 owner/DACL 校验,不放宽既有异常对象的安全规则。
|
||||
- Provider Schema 决策:`agent.route_manifest.missingAssetSlots` 不再广告 OpenAI-compatible 代理拒绝的 `uniqueItems`;Runtime 继续排序去重,Schema 子集门禁新增该关键字,真实 Provider smoke 必须在发布前证明工具目录可被接受。
|
||||
- 运行决策:Godot 项目提交给 Project Supervisor 时使用 `standard` Run Profile,避免触发 Web 专用 `game/index.html`、HTTP preview 与自主 Web 完成门。Godot 编辑器启动和内嵌运行预览不在本切片范围。
|
||||
|
||||
@@ -147,6 +147,23 @@
|
||||
- 验证:用 deferred graph Promise 断言终态前 Tauri layout read/update 调用均为 0;图就绪后首次坐标直接按最终深度生成,旧 scope 迟到结果无效,手动坐标不变且相同自动布局不增加 revision。
|
||||
- 关联:`apps/ai-game-creator-shell/src/view/project-development/index.tsx`、`apps/ai-game-creator-shell/src/view/project-development/useProjectResourceCanvasLayout.ts`、`apps/ai-game-creator-shell/src-tauri/src/project/resource_dependency_graph.rs`。
|
||||
|
||||
## 等价 Runtime 投影刷新不能清空资源依赖图(2026-08-10)
|
||||
|
||||
- 现象:专业 Agent 运行期间,资源画布中的卡片按轮询节奏整批消失并立即恢复;停止产生新的 Runtime 时间戳后闪烁减弱或消失。
|
||||
- 原因:专业 Agent 轮询会重建结果数组;资源内容虽然相同,前端图读取 effect 仍因数组引用变化重新执行,并先把图和布局置空。布局位置暂时缺失时,所有资源卡都会返回 `null`。
|
||||
- 处理:用包含项目与资源输入的语义 scope key 稳定图请求参数,等价输入不重复读取;同一项目的资源集合确实变化时,异步刷新期间保留上一个已解析图和布局,只有首次加载或切换项目才启用空图屏障。刷新失败继续展示旧快照,不能用瞬态失败清空画布。
|
||||
- 验证:AppSurface 先用全新但内容相同的 Agent 结果数组 rerender,断言图读取仍只有一次且原卡片 DOM 保持连接;再增加真实资源并延迟第二次图响应,断言旧卡片在刷新窗口持续挂载,新图返回后新增卡片正常出现。
|
||||
- 关联:`apps/ai-game-creator-shell/src/view/project-development/index.tsx`、`apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts`。
|
||||
|
||||
## Supervisor steer 不能只有内部排队事件(2026-08-10)
|
||||
|
||||
- 现象:自主制作期间继续向项目总控发消息,用户消息已进入同一 Run,当前 Provider 也被中断并重新规划,但普通工作台短暂的提交状态消失后一直没有回复,直到整轮制作最终收束。
|
||||
- 原因:steer 只持久化用户消息与内部 `steer.queued` 事件;公开事件投影又明确排除 `steer.*`。普通工作台提交后会用后端 conversation 覆盖本地消息,因此仅追加临时前端气泡也无法稳定跨刷新显示。
|
||||
- 处理:根 Project Supervisor 的 steer 进入 durable `queued` 后,先写“正在判断、当前任务继续”的公开确认,再由独立 `steer-decision` LLM turn 返回自然语言回复和 `interruptCurrentProvider`。状态询问、解释和不冲突补充默认不中断;明确停止、改向或会使在途方案过期时才允许请求中断。判定和回复按 `run + steer` 持久幂等,刷新后仍可见;判定失败时继续当前任务,并在下一安全边界应用 steer。
|
||||
- 并发边界:steer 入队、Runner `runtime.steer` 通知都不得直接触发 Provider interrupt。Codex app-server 的判定使用独立节点,不能等待主节点 turn 锁;判定为 true 后也只能中断 `appliedSteerCursor < steer.sequence` 的旧 Provider 请求,已经消费该 steer 后启动的新请求不可被误杀。已经开始的工具和外部动作不强杀,完成 observation 后再消费 steer。
|
||||
- 验证:真实 mock LLM 回归必须覆盖状态询问回复且 `interruptCurrentProvider=false`;持久重放只保留一条语义回复;steer 入队后旧 Provider 继续运行,判定为 true 后才中断;新规划 Provider 的 cursor 已包含该 steer 时即使旧判定为 true 也不能中断。前端同秒多条消息保持“用户补充 → 判断提示/语义回复”的关联顺序。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/interaction.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/steering.rs`、`apps/ai-game-creator-shell/src-tauri/src/runner/dispatch.rs`、`apps/ai-game-creator-shell/src/features/agent-runtime/model.ts`。
|
||||
|
||||
## Jenkins 异步备份不能用 nohup 脱离作业
|
||||
|
||||
- 现象:Stdb Publish 成功,上传日志只留下“已获取进程锁 / 上传已有备份 / 目标对象”,没有成功或可捕获错误;本地 tar.gz 和 `uploadStatus=deferred` manifest 每次发布后继续增长。
|
||||
@@ -4135,6 +4152,7 @@
|
||||
|
||||
- 现象:延迟重试携带比既有行更旧的调用方时间,回填图片序列字段时若无条件写入,会使 `updated_at` 倒退,导致基于时间戳的同步看不到更新或排序错误。
|
||||
- 处理:同源图片序列字段只允许 `None → Some`,非空冲突失败关闭;发生回填时 `updated_at = max(existing.updated_at, request_timestamp)`。legacy 音频 repair 不派生资源级图片序列或通用时长,重放继续精确匹配。
|
||||
|
||||
## 历史钱包消费不能从最近流水或通用订单快照推算
|
||||
|
||||
- 现象:后台用户详情要展示累计花费时,直接复用只返回最近 50 条的 `list_profile_wallet_ledger`,或在充值订单每行使用的通用钱包快照里扫描该用户全部流水。
|
||||
@@ -4202,7 +4220,9 @@
|
||||
- 原因:不是业务递归。debug 构建中 pending action continuation、后台 task queue 和 Agent 主循环各自形成大型 async poll frame;恢复路径在同一次 poll 调用链直接进入下一层状态机,累计超过 worker 默认栈。
|
||||
- 处理:整个 pending continuation、它进入的后台主循环,以及完成、取消或失败后 drain 同 Agent 后续队列时,都必须跨越独立 Tokio task 轮询边界,使上层 poll 先退栈后再轮询下一层状态机。传入边界的 future 必须先装箱;若泛型 helper 直接持有大型 future,即使随后 `spawn`,调用方 async frame 仍会把它保留在默认 worker 栈上。边界必须保留结构化取消语义;当前使用 boxed future 与 `JoinSet`,父 continuation 被丢弃时同步 abort 子任务。不得只增大 CI 的 `RUST_MIN_STACK`,否则生产默认栈仍可能崩溃。
|
||||
- 验证:失败用例必须在未设置 `RUST_MIN_STACK` 时通过;同时覆盖 policy batch 全组、拒绝 pending 后重规划并 drain 下一任务,以及 pending/cancellation 回归,证明恢复不重复生成 isolated spawn、队列继续推进且父任务取消不遗留后台子任务。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/pending_execution.rs`。
|
||||
- 2026-08-10 补充:Provider、Codex CLI 与 Codex app-server 合并到同一个模式分发后,即使本轮实际选择普通 Provider,未装箱的组合 future 仍携带最大分支状态;委派子任务完成后回流父 Agent 的既有回归会在默认 Tokio worker 栈稳定溢出,单独运行同样失败,扩大 `RUST_MIN_STACK` 才通过。持久重试 helper 与非持久压缩路径都必须在构造完整物理 Provider request 后、进入下层泛型 control/lifecycle helper 前装箱;不要逐个扩大 queue worker 栈,也不要等到底层 helper 内部再装箱已经进入调用方 frame 的泛型 future。
|
||||
- 2026-08-10 验证:未设置 `RUST_MIN_STACK` 时运行 `background_agent_runtime_can_delegate_task_to_other_agent`,并追加 `provider_retry_`、`provider_handoff_`、`response_stream_` 与 Native shell 完整门禁;测试只能以默认 worker 栈通过,不能把 CI 环境变量当修复。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/pending_execution.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/provider_retry.rs`。
|
||||
|
||||
## Provider 可扩展不能用一个全局 protocol 枚举代替实例隔离
|
||||
|
||||
@@ -4455,6 +4475,7 @@
|
||||
- 原因:正式 SFX handler 把计费、翻译、provider、持久化和写回内联在一个 future 中;分层测试只能证明单个 helper,不能证明组合顺序和“失败后不继续”。同时若把 mock 流程另写一遍,它本身又可能与生产逻辑漂移。
|
||||
- 处理:抽出单一 Worker 编排函数和计费 / stage adapter。生产 adapter 代理现有正式实现:OSS 后只准备 asset object / binding 候选,项目资源、账号素材、画布和 job 终态通过同一原子提交落库;测试 adapter 逐段记录调用与注入失败。组合矩阵同时断言 charge / refund、LLM / provider / OSS / writeback 计数、稳定 reason code 和权威值等值。ElevenLabs 二进制、MIME、大小、timeout 和 MP3 仍由 loopback adapter 测试负责,组合 mock 不替代协议测试。
|
||||
- 验证:自动 / 手动时长 × Loop 四组合成功;余额不足;翻译、HTTP、无效音频、时长探测、OSS PUT / HEAD、asset confirm / bind、项目资源、账号素材和画布写回逐点失败;所有 job provider POST `<= 1`,预扣后失败 refund `= 1`。
|
||||
|
||||
## 生成结果的稳定 ID 和 job 终态都不能代替 durable receipt(2026-08-06)
|
||||
|
||||
- 现象:Provider / OSS 已成功,但项目资源、账号素材、binding、画布和 job 只完成一部分;不确定结果重放时,有时又复制一批素材或重复推进 canvas revision。inline 路径在进程重启后尤其无法判断前一次提交是否整笔完成。
|
||||
@@ -4482,3 +4503,46 @@
|
||||
- 原因:`normalize_generated_asset_folder_id` 只处理 `project`、旧 `folder-*` 和默认目录 ID 的兼容映射,不读取 SpacetimeDB;真正的 `require_owned_asset_folder` 位于生成结果持久化末端。把“失败会退款”误当成副作用补偿,漏掉退款不能撤销 provider 请求与 OSS PUT。
|
||||
- 处理:所有付费编辑器生成在队列 enqueue 前和 worker / inline 执行前复用只读 `preflight_editor_generation_target_and_return`,按认证 owner 校验可选项目及归一化目录;读取失败和归属不匹配一律失败关闭。helper 返回 canonical 项目与目录并覆写后续入队 / worker / 原子准备使用的 payload,不能校验 trim 后的项目却持久化原始空白值。角色图片、角色动作、图标 spritesheet 与 UI 提取省略目录时按实际默认目录预检;默认目录允许尚未创建,自定义目录必须存在且 owned。预检不替代最终 procedure 复验,也不保证跨外部调用的目录锁定。
|
||||
- 验证:源码顺序回归必须覆盖图片生成、图片修改、图标 spritesheet、UI 设计图提取、视频、角色动作、SFX 与 BGM 的 enqueue / direct 两层,证明纯本地格式和 `data:` / `blob:` 稳定引用门禁先执行,canonical target 在预检后写回 payload,远端引用解析、generation input rebuild、扣费、入队、provider 与 OSS 均留在预检之后;模块侧扫描证明预检只调用 runtime identity、项目、目录只读校验且不含 insert / update / delete,并覆盖带空白项目、`project`、旧 `folder-*`、默认目录 ID、自定义目录与 `None` 归一化。
|
||||
|
||||
## 非整除 nearest 会让逻辑像素块宽窄不一(2026-08-10)
|
||||
|
||||
- 现象:像素规整后的图片虽然保持了源图宽高,放大观察却能看到相邻逻辑块占用的物理列数或行数不同,表现为部分块更宽、部分块更窄;整数倍样例看起来正常,换一张网格数不能整除输入尺寸的图才复现。
|
||||
- 原因:逻辑图宽高为检测后的列数、行数。把 `C × R` 的逻辑图用 nearest 恢复到 `W × H` 时,只要 `W % C != 0` 或 `H % R != 0`,目标栅格就只能在不同逻辑像素间分配 `floor / ceil` 数量的列或行;nearest 能避免混色,却不能让非整数缩放后的块严格等大。只用 `128 × 128 → 64 × 64 → 128 × 128` 这类整数倍测试会掩盖问题。
|
||||
- 处理:最终资产直接编码一格一像素的逻辑分辨率 PNG,不再执行输入 / 交付尺寸 nearest 恢复,也不要求成功输出与源图或占位尺寸相等。普通图片和角色的前置 Lanczos 交付尺寸归一仍用于确定检测输入;平底网格源与透明 RGBA 源仍必须同尺寸,不能把“取消输出同尺寸”误解为放开两个内部采样坐标系。
|
||||
- 验证:使用至少一组逻辑列数或行数不能整除输入尺寸的图片,断言输出宽高等于切线数减一而不是输入宽高;同时核对响应、project resource、账号素材和结果 layer 都记录最终 PNG 实际尺寸,且只持久化一个最终 PNG,没有输入尺寸恢复版、诊断图或额外资源。失败降级用例继续验证 Alpha / 交付尺寸守卫,不应因成功输出改为逻辑分辨率而删除。
|
||||
- 关联:`server-rs/crates/platform-image/src/pixel_art_snapper.rs`、`server-rs/crates/api-server/src/editor_project.rs`、`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`。
|
||||
|
||||
## Codex CLI 节点不能把进程终态当成 Runtime 提交证据(2026-08-10)
|
||||
|
||||
- 现象:`codex exec` 已启动或退出码为 `0`,但 JSONL 没有 `turn.completed`;或者已出现 `thread.started`,Runner 随后退出,重启时误以为节点已完成。GUI 进程的 PATH、安装或登录状态与交互终端不同时,还可能在默认模式下静默落回 HTTP Provider。
|
||||
- 原因:CLI 进程、Provider lifecycle、retry/handoff 和 Runtime finalization 是连续但不同的 durable owner;本地进程退出不能代替现有账本的原子提交与回读。模式切换若不进入配置指纹,还会把另一执行模式的 retry/handoff 当成当前结果。
|
||||
- 处理:Codex CLI 必须只作为新的节点推理适配器,继续经过原 Runtime 的 lifecycle、retry、handoff、receipt、revision、verification 和 reconciliation。只接受完整 JSONL `turn.completed` 与可验证的最终消息;`started` 无 `completed`、超时、异常退出或输出破损都继续走原失败/核对边界。`agentMode`、CLI 版本和影响输出的固定参数必须纳入配置指纹;CLI 不可用时显式报错,不得静默切回 Provider。
|
||||
- 验证:确定性回归覆盖 stdin prompt、空临时 cwd、read-only/no-shell/ephemeral 参数、structured tool call 转换、缺失终态、超时进程组回收和 stderr 不泄漏;真实 smoke 必须显式 opt-in,并分开报告 CLI 协议成功与本机认证/网络结果。
|
||||
|
||||
## 模拟 Provider 的测试不能继承生产默认 Agent 模式(2026-08-11)
|
||||
|
||||
- 现象:生产默认切到 `codex_app_server` 后,HTTP mock Provider 测试不再收到请求并超时;只验证 retry/handoff identity 的纯单测还会在未安装 Codex CLI 的 CI Runner 上直接失败。本机安装了 Codex 时,相关遗漏可能被掩盖。
|
||||
- 原因:测试只构造 `agentLlm` 或直接调用读取全局配置的 identity helper,没有显式固定 `agentMode`;缺省配置按正式产品合同选择 `codex_app_server`,测试因此意外依赖本机 CLI 和认证环境。
|
||||
- 处理:测试若验证 HTTP Provider 协议或 mock 请求,必须在测试配置中显式写入 `agentMode: provider`;只验证 Provider retry/handoff 数据结构的纯单测应调用显式接收模式的 identity helper。不得把生产默认模式改回 Provider,也不得仅为单测向通用 CI 镜像安装 Codex CLI。
|
||||
- 验证:在 PATH 不含 Codex CLI 的环境运行 response-stream identity、MCP Runtime 和平台素材 mock 回归;同时保留独立的 Codex CLI/app-server 可用性与协议测试,防止 Provider 测试替代正式模式覆盖。
|
||||
|
||||
## 空 MCP 覆盖不会清除 Codex 用户配置中的 MCP(2026-08-10)
|
||||
|
||||
- 现象:以 `codex app-server -c 'mcp_servers={}'` 启动后,`thread/start` 仍发出用户配置中各 MCP server 的 startup 事件;若直接把这种进程当 AGC 节点 Agent,会出现 Codex 与 AGC 两套 ToolHost、副作用和审批边界。
|
||||
- 原因:Codex `-c` 对 table 做配置合并,空 table 不是“删除已有所有条目”。长期 app-server 与一次性 `codex exec --ignore-user-config` 的配置隔离能力不同,不能照搬参数后假设用户配置已清空。
|
||||
- 处理:为 AGC app-server 创建权限受限的临时 `CODEX_HOME`,只桥接已有 `auth.json`,不带入用户 `config.toml`、MCP、skills、hooks 或项目 rules;model/provider/effort 全部由 AGC 显式传入。server→client 请求一律拒绝,原生工具 item 一律协议失败。临时 HOME 和认证桥接不得写入项目、日志或持久账本。
|
||||
- 验证:协议 smoke 必须观察 `thread/start` 后没有 MCP startup 事件;fake server 还要断言 API Key 不在 argv、初始化只一次、结构化输出回到 AGC ToolHost。只看到 `initialize` 成功不能证明安全隔离成立。
|
||||
|
||||
## 只隔离 CODEX_HOME 仍会加载用户 Skill,且 Codex 原生工具默认不全关闭(2026-08-10)
|
||||
|
||||
- 现象:app-server 虽然使用临时 `CODEX_HOME` 和 read-only turn,仍可能发现 `$HOME/.agents/skills`,并默认提供 cached web search、multi-agent 及其它稳定原生能力;等 `item/completed` 后再拒绝已经太晚,工具调用和额外模型成本可能已发生。
|
||||
- 原因:Codex 的用户 Skill 发现根是 OS HOME,不是 `CODEX_HOME`;`dynamicTools=[]` 也只清空宿主动态工具,不会移除 Codex 内建工具。read-only/network off 是副作用防线,不等于从模型工具目录删除能力。
|
||||
- 处理:同时隔离 `HOME / USERPROFILE / APPDATA / LOCALAPPDATA`,并在临时 workspace 创建空 `.git` 作为仓库发现边界,防止继续向父目录(例如 `/tmp`)发现 `.codex/.agents`;启动前设置 `web_search="disabled"`、`agents.enabled=false`,并关闭 shell/unified exec/browser/plugin/image/workspace dependency 等原生 feature;接收 `item/started` 时只允许消息、计划、推理和压缩等被动 item,其余立即 interrupt。配置中的 `webSearchEnabled=true` 必须失败关闭并提示切 `provider`。
|
||||
- 验证:fake app-server 检查 argv 不含 Key、专用 Key 只在环境、继承 `CODEX_API_KEY` 被移除、HOME 指向临时目录、web/multi-agent/shell 关闭;另覆盖 turn-start 回包前 drop 最终只发一次对应 interrupt。
|
||||
|
||||
## 多 Agent 共享一个 Codex app-server 会放大单点终态丢失(2026-08-10)
|
||||
|
||||
- 现象:多个节点最初已有 `started -> completed`,随后一个 app-server stdio 连接关闭,同一秒多个仍在途节点一起进入 `needs-reconciliation`;单看 threadId 不同会误以为节点已经进程隔离。
|
||||
- 原因:pool 只按 LLM 凭据和路由复用进程,节点身份只用于进程内 thread map。任一 stdout framing、子进程退出或连接故障都会 drain 整个进程的 pending/turn router,使所有共享节点同时失去可信终态。
|
||||
- 处理:pool key 必须包含 `projectId + agentId + sessionId + runId`,每个权威节点直接持有独立 app-server 子进程;同节点 turn 还要串行,不能向同一 thread 并发 `turn/start`。只发送当前 CLI schema 定义的字段;stderr 使用有界内存尾部并先脱敏再进入 Runner 诊断。
|
||||
- 验证:至少两个节点并发各跑多轮,确认存在两个 app-server PID;终止其中一个后只有对应节点进入 reconciliation,另一个仍能收到 `turn/completed`。旧 AppData 缺 `agentMode` 且含非 Responses 路由时必须保留 `provider`,不能在项目自动恢复时批量失败。
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
- 新增 Markdown 文档时,文件名必须以分类标签开头,格式为 `【标签名】中文标题-日期.md`;只在任务需要时重命名历史文档,避免无关大 diff。
|
||||
- 涉及中文文本时注意 UTF-8 编码和乱码排查。
|
||||
- 涉及后端时遵循 DDD 分层,不把业务真相下沉到前端或临时兼容层。
|
||||
- 对已明确退役且不存在现役调用方、公开契约、持久化数据、活跃实例或迁移要求的对象,不新增历史兼容代码、维持退役行为的防御性兼容测试、墓碑注释或墓碑文档;权威文档直接更新为当前状态。公开 API、持久化数据、SpacetimeDB schema、跨版本重放、活跃实例和正式迁移仍须保留最小化、白名单化的必要兼容及契约或迁移测试,并在迁移完成后同步删除。
|
||||
- 运行时日志禁止对完整配置、应用状态或 provider client 做递归 `Debug` 输出;当前 `AppConfig`、`AppState`、`AppStateInner`、`SpacetimeClientConfig` 与 `SpacetimeClient` 必须保持封闭的手写安全摘要,并用唯一哨兵测试锁定顶层与可独立格式化路径。其它仍使用派生 `Debug` 的历史 provider 类型不得新增整对象日志调用,后续按类型独立脱敏。新增字段默认不进入摘要,确需排障时只增加枚举、数值、布尔值或是否配置等非敏感字段。
|
||||
- `packages/shared` 用于前后端 DTO、公开契约及跨页面复用的无业务真相 UI 组件和纯工具;不得把领域规则、后端副作用或正式状态放入其中。
|
||||
- 修改 `/api/external/v1` 的路由、HTTP 方法、请求 / 响应 DTO、请求头、状态码、鉴权或异步语义时,必须同批更新 `docs/openapi/genarrative-external-v1.openapi.json` 和对应契约测试;Rust 实现与 OpenAPI 未对齐时不得完成、提交或发布。
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1592,6 +1592,58 @@ V1.49 已经让 `agent-runtime-core` 能在不依赖 Provider 的情况下独立
|
||||
- core conformance 覆盖第三方 fake Provider 注册/调用、重复与未知 ID、能力不匹配零调用和 stream callback。`platform-llm` 覆盖三种 descriptor、request/response/tool-call/stream/error 双向转换与实例隔离;AGC 覆盖 interaction 实际走 registry 及原 fallback 语义。
|
||||
- 完成后运行 core conformance、`cargo test -p platform-llm --manifest-path server-rs/Cargo.toml`、AGC interaction/config 定向回归、Tauri `cargo check --tests`、`npm run ai-game-creator-shell:check`、`npm run check:encoding` 和 `git diff --check`;独立 core 生成的 `Cargo.lock/target` 交付前清理。
|
||||
|
||||
## V1.51 Codex CLI 节点执行模式
|
||||
|
||||
V1.51 在不替换现有 Provider、Runner 和 Runtime 事实源的前提下增加第二种节点 Agent 执行器。AppData `agentMode` 只接受 `codex_cli / provider`,默认 `codex_cli`;显式 `provider` 继续执行 V1.29-V1.43 的原 HTTP LLM 路径。Runner 不新增模式参数,每次节点请求从当前 AppData 配置解析模式。
|
||||
|
||||
### 执行与协议
|
||||
|
||||
- 每次 Runtime 节点的 tool-plan、格式修复、上下文压缩或 final-reply 请求仍先构建既有 `LlmRunRequest`、捕获同一 Provider snapshot,并进入原 started/completed lifecycle。`codex_cli` 分支启动一次 `codex exec`,把 prompt 经 stdin 输入,把当前函数目录转换为 structured-output schema,并把终态 JSONL 转回现有 `LlmRunResponse / LlmToolCall`。
|
||||
- Codex CLI 只充当推理 Agent,不充当第二个 ToolHost。调用固定使用空临时 cwd、`--skip-git-repo-check --ephemeral --ignore-user-config --ignore-rules --sandbox read-only --disable shell_tool` 和 never approval;不得加载项目 `AGENTS.md`、用户 MCP/plugin/hook 或执行项目命令。所有项目读写、命令、MCP、Canvas、权限、pending、receipt、revision 与 verification 继续由 AGC Runtime 执行。
|
||||
- prompt 和 schema 有界,prompt 只走 stdin,不进入 argv;stdout/stderr 有独立上限,持久审计只保存模式、版本、退出分类、字符数和指纹,不保存 prompt、函数参数、CLI 认证、本机路径或原始错误正文。CLI 非零退出、缺少终态 agent message、JSONL/schema 损坏和超限输出统一失败关闭并走既有安全错误摘要。
|
||||
|
||||
### 生命周期与恢复
|
||||
|
||||
- Codex child 绑定当前 request future 并设置 drop kill;steer、取消、暂停、Runner draining 和 GUI owner 丢失继续沿现有 Provider interruption 收束。started 后没有 completed 的请求继续进入 `needs-reconciliation`,不得重新启动同一 request slot。
|
||||
- 由于 CLI shell、MCP 和项目写入被禁用,Codex 请求本身没有项目副作用;但其响应交接仍可能处在未知窗口,必须继续使用 V1.41/V1.43 的 handoff 与零重放规则。`agentMode`、CLI 稳定身份和影响输出的 CLI 参数进入 `providerConfigFingerprint`,跨模式或 CLI 漂移必须作废旧 retry/handoff,不能当作同一请求恢复。
|
||||
- 同 wave 并发仍由现有 per-Agent lane 和 scheduler 决定;一个节点只启动一个 Codex 子进程,依赖节点只在原 manifest 终态门满足后启动。CLI 模式不新增 Codex 内部子 Agent,也不把 Codex session 当 AGC Session 或恢复事实。
|
||||
|
||||
### 配置与验收
|
||||
|
||||
- `check_game_creator_llm_config` 在 CLI 模式只检查固定 Codex 可执行文件可启动并返回受支持版本,不要求 LLM API Key;Provider 模式保持既有检查。配置 UI 显示全局模式,始终保留旧 LLM/逐 Agent/MCP/Editor 配置;切换模式不清空任何旧值。
|
||||
- fake Codex fixture 必须覆盖 argv/stdin、structured calls、final text、非零退出、挂起取消、损坏/超限 JSONL、无 shell/MCP 参数和并发节点;真实 smoke 只复用用户已有 Codex 登录态。旧 Provider smoke 继续作为回退模式门禁,不能被新 CLI smoke 替代。
|
||||
|
||||
## V1.52 Codex app-server 长期节点 Agent 模式
|
||||
|
||||
V1.52 保留 V1.51 一次性 `codex_cli` 和原 HTTP `provider`,新增 `codex_app_server` 并切为默认。External Runner 按实际 LLM 凭据、Responses 路由与 `projectId / agentId / sessionId / runId` 为每个权威节点隔离长期 `codex app-server --stdio` 子进程;节点 run 在自己的进程内映射一个 ephemeral Codex thread,每次权威 `LlmRunRequest` 快照映射一个串行 turn。Codex thread 不是持久恢复真相,Runner 重启后仍只依据 AGC lifecycle、retry/handoff、manifest、Agent DB 与 finalization 重建工作。
|
||||
|
||||
### 配置、认证与安全边界
|
||||
|
||||
- `apiKind` 在有无 API Key 时都必须为 `openai_responses`;非空 Key 由 app-server 启动参数注册隔离 model provider,base URL 和 `wire_api=responses` 显式生效,Key 仅通过专用环境变量传入,不进入 argv、日志、项目或指纹明文。`openai_chat / anthropic` 不伪装兼容,配置检查明确要求切换 `provider`。API Key 为空时只使用用户现有 Codex `auth.json` 登录态,model 与 reasoning effort 仍取当前有效 Agent LLM 配置;继承的 `CODEX_API_KEY` 必须移除,避免实际账号与池/账本身份不一致。
|
||||
- app-server 使用带空 `.git` 边界的临时 cwd、隔离 `CODEX_HOME` 和隔离 OS `HOME / USERPROFILE / APPDATA`,让仓库发现停在临时 workspace,并只桥接用户已有 `auth.json`;不得沿临时目录父级加载配置/skills,也不加载用户 `config.toml`、用户 skills、MCP、hooks 或项目 rules。启动前显式设置 `web_search="disabled"`、`agents.enabled=false`,并关闭 shell、unified exec、浏览器、插件、图像、workspace dependency 等原生能力;thread/turn 固定 never approval、read-only、network disabled,并只发送当前 Codex CLI schema 声明的字段。任何 server→client 审批/交互请求失败关闭,任何非被动 item 在 `item/started` 即中止。AGC Runtime 继续是唯一 ToolHost,因此 `webSearchEnabled` 在本模式必须为 `false`;需要原 Provider 联网检索时切换 `provider`。
|
||||
- Pool key 绑定本次实际凭据快照指纹、base URL、API kind、Codex CLI 版本与权威节点 run 身份:非空 AppData Key 指纹绑定实际注入的专用环境变量字节,空 Key 则先一次性读取有界 `auth.json`、按同一份字节生成指纹并复制进隔离 `CODEX_HOME`,登录态变化后不得复用旧池连接。最多保留 32 个节点进程,仅淘汰没有外部 lease 的 LRU 连接。每个连接最多保留 128 个 inactive LRU thread,但正常只服务自己的节点身份。Provider 配置指纹另外绑定模式、CLI 版本、app-server 协议、model/effort、安全参数和 output schema 合同。逐 Agent override 与不同节点不得共享进程。
|
||||
|
||||
### turn、取消与恢复
|
||||
|
||||
- JSON-RPC stdout 使用有界 NDJSON 行,stderr 按固定块排空并对无换行单条记录设置硬上限;两条路径在没有换行时都不得无限增长。stderr 原文不进入错误、Runner 日志或持久记录,只累计固定分类、总字节数与 SHA-256,并同时记录可取得的 exit status。协议继续使用单调 request ID、有界 pending RPC map 与 turn event router;initialize 每个进程 generation 只执行一次。`stream=true` 的 final-reply 把 `item/agentMessage/delta` 转成现有 `LlmStreamDelta`,半句仍只是可丢失展示缓存;只有 `turn/completed` 且最终 agent message 满足 output schema 后才转换为 `LlmRunResponse / LlmToolCall`,随后仍走既有成功 handoff 原子写入和回读。
|
||||
- 当前 request future 被取消、暂停或 drop 时只发送对应 `turn/interrupt`;取消状态从 `turn/start` 写出前就建立,若取消与 turn ID 回包乱序,双方通过共享槽位恰好一次补发 interrupt。异常路径立即删除本地 turn router,orphan pending RPC 在 30 秒后自清理。app-server EOF、损坏 JSON、`turn/start` 回包丢失或已开始 turn 的等待超时属于终态未知,必须进入 `needs-reconciliation`,仅关闭当前节点进程且不得作为瞬态错误自动重放同一 request slot;其它节点进程继续运行。明确 `failed / interrupted` 是确定失败,不做 transport retry。
|
||||
- 执行模式与 Provider 配置指纹必须来自同一次配置快照;不能先捕获 executor、再重新读取 `agentMode` 生成 durable identity。Runner 正常/强制/watchdog 退出都会显式关闭池;Linux 子进程额外设置 parent-death signal,Runner 被 SIGKILL 时也不能遗留持有凭据的 app-server。
|
||||
- 每个 turn 输入仍是 AGC 构建的完整权威消息快照,因此复用 thread 会累计完整轮次历史;这只影响进程内推理上下文和 token,不改变 AGC durable owner。后续若改为增量消息协议,必须另行版本化 request fingerprint 与恢复合同,不能静默改变本模式输入语义。
|
||||
|
||||
### 验收
|
||||
|
||||
- fake app-server 覆盖 initialize、thread/start、turn/start、structured output、delta、turn-start 回包前取消、凭据只进专用环境变量、隔离 OS HOME、原生能力关闭和跨配置/CLI 版本 pool 隔离;定向测试覆盖三态默认/round-trip、unknown terminal reconciliation 与旧 `codex_cli/provider` 回归。真实模型 smoke 为 ignored/显式 opt-in,避免自动消耗用户 Provider。
|
||||
|
||||
## V1.53 Supervisor 运行中非终态回复与 LLM 条件中断
|
||||
|
||||
V1.53 把根 Project Supervisor 的 same-run steer 从“收到消息立即中断”改为“先回复并判断、按需中断”。用户消息仍先进入原 run 的 durable steer ledger 与 conversation;公开确认明确说明正在判断且当前任务继续运行。随后由独立 LLM turn 调用严格 `runtime_steer_decision`,一次返回自然语言 `reply`、`interruptCurrentProvider` 与安全原因。该回复按 steer 身份持久幂等,是制作过程中的非终态对话,不调用 `respond_to_user`,也不关闭 task、Goal、Run 或 finalization。
|
||||
|
||||
- 命令层在 durable 入队后不得先通知或唤醒 External Runner,避免 Runner 抢先消费 steer 后让判定快照漂移。判定为 `false` 或判定失败时,才发送只校验 ledger 并唤醒任务的 `runtime.steer`;该 RPC 必须固定返回 `providerInterrupted=false`。判定为 `true` 时直接发送 `runtime.interrupt_for_steer_decision`,由该 RPC 完成条件中断并唤醒同一 run。本地进程内路径遵循同一顺序。
|
||||
- 状态询问、解释、鼓励、确认和不冲突补充默认不中断;只有明确停止、改向,或继续当前方案会产生明显过期结果时才允许 `true`。判定使用当前有效 `provider / codex_cli / codex_app_server` 模式;app-server 以独立 synthetic 节点运行,不能等待主节点的 turn gate。
|
||||
- 条件中断必须先读取已持久化 decision,并只允许中断注册时 `appliedSteerCursor < steer.sequence` 的旧 planning/final-reply Provider。若旧请求已自然结束,或新 Provider 已消费该 steer 后启动,则返回 `providerInterrupted=false`,不得误杀新规划。工具、外部副作用、确认、process session、Git、receipt 和 finalization 始终不强杀,在下一安全边界消费 steer。
|
||||
- LLM 判定、解析或持久化失败时写入关联的非终态 fallback 回复,保持当前任务运行,并在下一安全边界应用已排队 steer;失败不能退回“默认中断”。判定与回复按 `agentId / runId / steerId` 幂等,冲突终态失败关闭。
|
||||
- 验收必须覆盖判定 LLM 的 `true / false` 协议、公开回复幂等、入队本身不中断、`runtime.steer` 有活动 Provider 时仍不中断、缺失 decision 拒绝条件中断、`false` decision 不中断、`true` decision 只中断旧 cursor,以及判定失败后同一 run 继续。
|
||||
|
||||
## 验收命令
|
||||
|
||||
- `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml structured_plan_ -- --nocapture`
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -52,7 +52,7 @@ v1 只开放以下能力:
|
||||
图片生成、图标 spritesheet 和 UI 素材提取的 completed compact `result` 可携带可选结构化 `warning { code, reason }`;任务查询顶层 `warning` 是可直接展示的有界摘要。外部 OpenAPI 当前公开四个稳定 `code`:
|
||||
|
||||
- `postprocess-failed-source-preserved`:生成成功,但透明处理、像素规整等后处理未完成,接口保留仍可使用的原图或进入该步骤前的结果。
|
||||
- `dimension-restore-fallback`:provider 回图无法安全收口到目标交付尺寸,接口保留实际回图尺寸。
|
||||
- `dimension-restore-fallback`:该告警只描述进入可选 `pixelArt` 处理前的交付尺寸归一结果;无法安全归一时,在该处理边界保留 provider 回图尺寸。它不描述或约束 `pixelArt` 成功后的最终尺寸;若随后像素规整成功,最终产物仍是逻辑分辨率 PNG,不能据此推断最终宽高等于 provider 回图。
|
||||
- `unsupported-image-style`:请求的图片后处理风格未知或不适用于当前生成类型,接口按无风格继续生成。
|
||||
- `multiple-generation-warnings`:同一成功响应合并了不同 `code` 的多条非阻断告警,具体原因按顺序拼接在 `reason`。
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# 图片画布结构化持久化与迁移回滚方案
|
||||
|
||||
更新时间:`2026-08-10`
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
图片画布当前把全部图层和生成对话框整体序列化到 `editor_canvas.layers_json`。该字段接近原 256 KiB 上限时,资源登记仍可成功,而布局保存会返回 `413`;任务完成后重新读取后端旧快照,会把前端尚未持久化的参考图和生成结果从画布移除。
|
||||
@@ -76,7 +78,7 @@ worker 完成生成任务时,`api-server` 先把 Provider / OSS 结果准备
|
||||
|
||||
`POST /api/editor/images/pixel-art-snaps` 的完美像素化不是 external job completion:它免费、在当前 HTTP 请求内 inline 执行,不创建任务行,也没有 `job_id / worker_id / lease_token`。前端仍须先创建关闭 composer 的右侧 generation dialog,再解析或上传源图以取得稳定引用,随后 flush 包含该占位的当前布局,最后把稳定源媒体引用和带非空 `dialogId` 的 `canvasCompletion` 一次提交;结构化 / legacy canvas 的完成分流继续由后端决定,前端不能直接写表或本地补造正式 layer。
|
||||
|
||||
端点级并发排队、像素读取、静态 PNG / JPEG / WebP 编码门禁、解码、输入限制、legacy 网格步长估算、CPU 并发排队、规整和 PNG 编码全部发生在持久化前。两层排队的位置不同:端点级闸在首次 IO 之前,因此队列满的 `503` 早于任何 SpacetimeDB 读取和 OSS 下载返回;CPU 排队仍在下载之后、规整之前,等待超预算返回 `504`。两者都在持久化前失败,零写入结论不变。strict 与生成风格使用同一 profile、峰值估算、单轴步长补全、walker、采样和编码;仅在横纵两轴都未检测到步长、legacy 即将进入统一网格兜底时拒绝,任一轴已检测到步长时行为和输出完全一致。任一步失败、超时或不适用时不执行最终 OSS PUT,不创建 asset object、`editor_project_resource`、`editor_asset` 或结果 layer;不得保存原图副本、逻辑低分辨率图、诊断图或前后对比图冒充结果。处理成功时只 PUT 一张最终 PNG,并至多各创建一个 project resource 和一个账号素材;源图已有正式 project resource 时,结果资源的 `source_resource_id` 指向该资源。
|
||||
端点级并发排队、像素读取、静态 PNG / JPEG / WebP 编码门禁、解码、输入限制、legacy 网格步长估算、CPU 并发排队、规整和 PNG 编码全部发生在持久化前。两层排队的位置不同:端点级闸在首次 IO 之前,因此队列满的 `503` 早于任何 SpacetimeDB 读取和 OSS 下载返回;CPU 排队仍在下载之后、规整之前,等待超预算返回 `504`。两者都在持久化前失败,零写入结论不变。strict 与生成风格使用同一 profile、峰值估算、单轴步长补全、walker、采样和编码;仅在横纵两轴都未检测到步长、legacy 即将进入统一网格兜底时拒绝,任一轴已检测到步长时行为和输出完全一致。任一步失败、超时或不适用时不执行最终 OSS PUT,不创建 asset object、`editor_project_resource`、`editor_asset` 或结果 layer;不得保存原图副本、诊断图或前后对比图冒充结果。处理成功时,snapper 直接编码并 PUT 唯一一张 `(columns.len() - 1) × (rows.len() - 1)` 逻辑分辨率 PNG,不再 nearest 恢复到源图或交付尺寸,并至多各创建一个 project resource 和一个账号素材;源图已有正式 project resource 时,结果资源的 `source_resource_id` 指向该资源。结果 resource、asset、响应与 layer 使用最终 PNG 的实际宽高,不要求与源图或 generation dialog 占位尺寸相等,也不得另存输入尺寸恢复版。
|
||||
|
||||
该零写入保证只覆盖首个最终 PNG PUT 前的可预判与处理阶段。进入持久化后,PNG / asset object、project resource、账号素材与 canvas completion 仍跨 OSS 和多个 SpacetimeDB procedure,沿用既有非事务顺序;后段失败可以保留此前已经确认的对象或记录,不做自动删除补偿,也不由客户端重放请求。调用方应按 `task_id / object_key / resource_id` 重新读取权威项目和素材快照后显式收口。
|
||||
|
||||
@@ -87,6 +89,8 @@ worker 完成生成任务时,`api-server` 先把 Provider / OSS 结果准备
|
||||
3. CAS 冲突时不得拿新 revision 原样重放旧整包;按当前项目保存冲突规则重新读取权威快照并显式收口;
|
||||
4. 客户端回包时若本地 dialog 已删除,不应用完成快照或写历史;现有布局 CAS 没有 deletion tombstone,completion 先提交、删除保存后冲突的极端竞态仍按权威快照收口。客户端不得为该 unsafe POST 配置 `EDITOR_REQUEST_RETRY_OPTIONS`。请求字节可能已发出后的 transport 异常或 `408 / 425 / 429 / 502 / 503 / 504` 不自动重放,先通过 GET 核对项目 / 素材快照,再由用户显式决定是否再次执行;Bearer 中间件在 handler 前拒绝请求后的既有认证恢复继续保留。
|
||||
|
||||
generation dialog 的 placeholder 宽高只参与占位与完成落点,不是结果媒体尺寸约束;completion 必须使用最终 PNG 资源的实际宽高构造结果 layer,不能为了匹配 placeholder 再缩放或拒绝逻辑分辨率结果。
|
||||
|
||||
## 4. 存量迁移
|
||||
|
||||
迁移按 canvas 执行 `backfill → hash 核对 → activate`,并保持幂等:
|
||||
@@ -128,6 +132,6 @@ SpacetimeDB 必须先于依赖新 procedure / bindings 的 API 发布;前端
|
||||
- structured 模式下 typed 列而非扩展 JSON 决定几何、层级、分组、显示 / 锁定、资源引用、`asset_kind_override` 和 dialog 状态;标签展示和类型能力判断统一按 `override ?? resource default`。修改当前图层标签与清除覆盖都保持 `resource_id` 和资源行数量不变;复制共享同一资源并复制 override,随后各副本可独立修改 override。两个客户端基于同一 revision 写入时只允许一个成功,冲突方重载后端最新快照,不换上新 revision 原样重放旧整包。细粒度 batch mutation 是取消 2 MiB 兼容入口的后续项,不冒充为本次已完成。
|
||||
- worker completion 已使用 durable receipt 与统一原子提交;V2 布局 CAS、object/resource/asset/binding、job 终态和 receipt 在同一 procedure 结果内返回。故障注入必须证明资产校验失败与 canvas revision 冲突均为零部分写入,成功后重放不新增记录、事件或 revision。
|
||||
- structured 快照刷新后,上传参考图、生成结果、占位与 dialog 状态均可恢复;资源存在但布局写入失败时不会伪装为保存成功。
|
||||
- 完美像素处理失败 / 超时时 OSS、resource、asset 和 layer 均无新增;成功时只有一个最终 PNG、至多一个 project resource 和一个账号素材。处理中占位删除已先持久化时,完成请求不复活 dialog 或结果 layer;回包时本地占位已删除则不应用完成快照,已成功创建的资源 / 素材仍可读取;传输结果未知时客户端不自动重放 unsafe POST。
|
||||
- 完美像素处理失败 / 超时时 OSS、resource、asset 和 layer 均无新增;成功时只有一个逻辑分辨率最终 PNG、至多一个 project resource 和一个账号素材,所有宽高均取该 PNG 实际值且允许与源图 / 占位不同。处理中占位删除已先持久化时,完成请求不复活 dialog 或结果 layer;回包时本地占位已删除则不应用完成快照,已成功创建的资源 / 素材仍可读取;传输结果未知时客户端不自动重放 unsafe POST。
|
||||
- 回滚重组结果经 schema 校验、canonical hash / 资源引用核对且不超过 2 MiB;超限或不一致时明确拒绝且 structured 快照仍可读取。
|
||||
- 完成 `npm run spacetime:generate`,确认 Rust 表字段、migration、生成 bindings、HTTP DTO 与前端 `assetKindOverride` 形状一致;再运行 `npm run check:spacetime-runtime-access`、`npm run check:spacetime-schema`、相关 Rust / API / 前端定向测试、`npm run check:encoding` 和 `git diff --check`。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
日期:`2026-06-15`
|
||||
|
||||
更新时间:`2026-08-07`
|
||||
更新时间:`2026-08-10`
|
||||
|
||||
## 背景
|
||||
|
||||
@@ -75,11 +75,11 @@
|
||||
- 图标素材面板增加紧凑的 `像素艺术` 勾选项。选择保存于现有生成器快照,并可随现有请求和队列 payload 传递;不写入用户可见 `generationInputs`、素材元数据或新建的持久化记录。
|
||||
- `style` 省略、为 `null`、空字符串或 `"none"` 时按内部 `None` 处理且不告警;`"pixelArt"` 启用像素规整。未知字符串按 `None` 继续生成,并通过既有通用 `warning` 返回 `unsupported-image-style`;非字符串 JSON 仍返回 `400`。
|
||||
- 2026-08-01 修订:`"pixelArt"` 不再只是后处理,同时向提交给 provider 的提示词末尾追加独立一行约束。图标链路使用「每个图标素材均为像素风格」,**不得**使用「画面为像素风格」——图集生成后要按纯色抠像,绿幕底必须保持平整,画面级像素化要求会与同一段提示词里的「纯色背景必须平整无纹理、无渐变」互相拆台;一张图内是多个彼此分离的素材,需要逐个点名,避免模型只把其中一部分做成像素块。注入发生在 `build_editor_icon_spritesheet_prompt` 返回之后,该函数签名和输出契约不变。约束句只随工程化提示词写入**原图 spritesheet** 的 `editor_project_resource` prompt 列;透明结果的 prompt 列是 `"去除纯色背景"`,自动拆分的切片是 `"自动拆分图集"`,两者都不含约束句。与普通图片和角色形象不同,本链路**响应体**的 `prompt` 字段返回的也是含约束句的工程化提示词,而不是用户输入——图标请求本身没有 `prompt` 字段(收的是 `iconDescriptions`),因此调用方(含外部 API v1)能直接看到绿幕子句、间距要求和本次新增的像素约束。以上 prompt 列写入与响应字段规则都是既有行为,与 `web/master` 一致,本次只是让被回传的模板多了一行。不新增 OSS PUT、项目资源、图集画布项或切片画布项。尚未约束各素材共用同一像素块大小(`estimate_step_size` 取全图相邻峰间距的第 30 百分位,块大小不一时步长估计会偏),等实测。
|
||||
- 图标链路以已持久化的带纯色背景 provider 原图实际尺寸为基准;BgFilter 正常成功后,把 Alpha 蒙版回贴到该同尺寸平底原图,再执行像素规整。网格分析源使用平底 provider 原图,RGBA 采样源使用 Alpha 已回贴的透明图;规整结果不再经过独立的最终尺寸处理,直接上传透明 spritesheet,成功后才进入原有连通域自动拆分。
|
||||
- 图标链路以已持久化的带纯色背景 provider 原图实际尺寸为基准;BgFilter 正常成功后,把 Alpha 蒙版回贴到该同尺寸平底原图,再执行像素规整。网格分析源使用平底 provider 原图,RGBA 采样源使用 Alpha 已回贴的透明图;这两份内部输入仍必须同尺寸。规整结果按一格一输出像素直接编码为逻辑分辨率透明 spritesheet,不再经过独立的最终尺寸处理,成功后才进入原有连通域自动拆分。
|
||||
- 首版固定参数为分析色数 `16`、Alpha 覆盖阈值 `0.375`、像素格尺寸自动检测、固定色板关闭、K-means 最大采样 `262144`。单格颜色按 `Σ(A × RGB) / ΣA` 进行 Alpha 加权;覆盖率 `Σ(A / 255) / N >= 0.375` 且 `ΣA > 0` 时输出硬 Alpha `255`,否则输出严格 `[0,0,0,0]`。分析色数不限制最终输出色数。
|
||||
- 像素规整 CPU 工作使用进程级最大并发 `2`;取得并发许可的排队时间与实际处理时间共享最多 `30` 秒预算,同时不得晚于当前请求 deadline,最终以两者中更早者为准。输入图片任一边不得超过 `10000` 像素,总像素不得超过 `8294400`;超限、排队超时或处理超时均保留 Alpha 已回贴的透明图并走非致命降级,随后仍可进入原有自动拆分。
|
||||
- 逻辑低分辨率图只存在内存;snapper 在规整内部使用 nearest 恢复到当前 RGBA 输入尺寸,即前述平底 provider 原图的实际尺寸。图标链路不执行角色链路的前置 Lanczos 交付尺寸归一,nearest 也不是规整后的独立交付尺寸恢复。实现应复用 Alpha 回贴阶段读取的平底 provider 原图;必要时最多增加一次读取已有 provider 对象的 OSS GET,不得增加 OSS PUT。
|
||||
- 开启或关闭像素风格都保持现有 provider 原图、透明图集和实际成功切片的持久化与画布数量不变。禁止上传逻辑低分辨率图、像素化前后双份图集、预览或诊断图,也不新增 asset kind、项目资源、画布 item、任务类型或数据库字段。
|
||||
- snapper 直接把逻辑分辨率图编码为最终透明 spritesheet;不得再用 nearest 或其它插值恢复到前述平底 provider 原图尺寸。图标链路继续不执行角色链路的前置 Lanczos 交付尺寸归一,但最终透明图集宽高仍可以与规整输入不同。实现应复用 Alpha 回贴阶段读取的平底 provider 原图;必要时最多增加一次读取已有 provider 对象的 OSS GET,不得增加 OSS PUT。
|
||||
- 开启或关闭像素风格都保持现有 provider 原图、透明图集和实际成功切片的持久化与画布数量不变。开启时透明图集本身就是唯一的逻辑分辨率 PNG;禁止另存输入尺寸恢复版、像素化前后双份图集、预览或诊断图,也不新增 asset kind、项目资源、画布 item、任务类型或数据库字段。资源、响应和画布结果使用最终 PNG 的实际宽高,不要求与 provider 原图或生成占位尺寸相等。
|
||||
- 图标图集的 BgFilter `flat` 调用固定使用 `cross_check=on`。BgFilter 最终失败、Alpha 比例漂移超过 `5%`、provider 原图修复性回读失败、Alpha 回贴失败或透明图完整解码失败时,都统一只保留 provider 原图且不拆分,像素规整不运行;像素规整自身失败但透明图仍通过完整解码和尺寸守卫时,才保留该透明图并继续上传和拆分,通过通用 `warning` 非致命提示,不退款。`sliceWarning` 继续只表达可信透明图成功后的自动拆分失败。
|
||||
|
||||
## 去背与保存
|
||||
@@ -103,7 +103,7 @@
|
||||
- 默认提示文本会完整进入 prompt;用户输入不再被解析为素材数量。例如“各种敌人头像:骷髅 哥布林 强盗 龙 蝙蝠等”只是一段完整需求,不代表必须生成或拆出 `6` 个素材。
|
||||
- 默认打开图标素材面板时选中 `nanobanana2 / 1:1 / 1K`;模型切换后,角色和图标素材面板之间沿用上次选择的模型。
|
||||
- 图标素材生成请求必须带 `model`、`aspectRatio` 和 `imageSize`;`nanobanana2` 请求体必须包含 `generationConfig.imageConfig.aspectRatio/imageSize`,`gpt-image-2` 请求必须包含文档映射后的 `size`。
|
||||
- 图标素材面板可选择 `style: "none" | "pixelArt"`;`none` 完整保持原处理路径,且提交给 provider 的提示词与未带该字段时逐字一致,`pixelArt` 在提示词末尾追加「每个图标素材均为像素风格」并在 Alpha 回贴后、自动拆分前执行内存像素规整,最终 OSS PUT、项目资源、图集画布项和切片画布项数量不得因此增加。
|
||||
- 图标素材面板可选择 `style: "none" | "pixelArt"`;`none` 完整保持原处理路径,且提交给 provider 的提示词与未带该字段时逐字一致,`pixelArt` 在提示词末尾追加「每个图标素材均为像素风格」并在 Alpha 回贴后、自动拆分前执行内存像素规整,直接持久化逻辑分辨率透明图集;该图集可以与规整输入尺寸不同,最终 OSS PUT、项目资源、图集画布项和切片画布项数量不得因此增加。
|
||||
- 图标素材生成可以上传普通附加参考图;提交时图标主规范图走 `referenceId`,且只提交当前 owner 的项目资源 ID 或素材 ID。普通附加参考图单独走 `referenceImageSrcs`,继续允许稳定 `objectKey` / 项目资源 ID / 素材 ID,但禁止 Data URL / Blob URL。两类引用都写入 `generationInputs.references`,不得用普通附加参考图协议放宽主规范边界。
|
||||
- 透明背景处理和自动拆分都成功后,画布同时出现透明 spritesheet 主图、其右侧的 provider 原图,以及从原图右侧铺开的全部有效连通域图标图层,图标依次命名为 `素材 N`;透明图集成功但拆分失败时仍出现透明主图与右侧原图,透明背景处理最终失败时只出现 provider 原图。
|
||||
- 选中透明图集图层时显示 `拆分图集`;点击后源图集显示扫描蒙层与 `拆图中` 状态,工具栏按钮同步切换为旋转图标和 `拆图中` 并禁用重复提交。完成后恢复工具栏,不新增第二张图集,只在 provider 原图右侧追加自动识别的独立素材,并同步写入素材库。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
日期:`2026-06-15`
|
||||
|
||||
更新时间:`2026-08-07`
|
||||
更新时间:`2026-08-10`
|
||||
|
||||
## 背景
|
||||
|
||||
@@ -69,8 +69,8 @@
|
||||
- 角色 provider 回图先按统一业务像素矩阵执行交付尺寸归一:允许无放大恢复时使用 Lanczos 重采样并居中裁切,无法安全恢复时保留 provider 实际尺寸并返回非阻断告警。归一后的带纯色背景图先持久化并作为 BgFilter 输入;BgFilter 正常成功后,把 Alpha 蒙版回贴到这张同尺寸平底原图,再执行像素规整并上传透明主图。网格分析源使用已收口到实际交付尺寸的平底原图,RGBA 采样源使用 Alpha 已回贴的透明图;软 Alpha 只参与单格覆盖率和 Alpha 加权 RGB 计算,输出 Alpha 硬化为 `0 / 255`。
|
||||
- 首版参数固定为分析色数 `16`、Alpha 覆盖阈值 `0.375`、像素格尺寸自动检测、固定色板关闭、K-means 最大采样 `262144`。单格覆盖率 `Σ(A / 255) / N >= 0.375` 且 `ΣA > 0` 时输出 `A=255`,颜色按 `Σ(A × RGB) / ΣA` 计算;否则输出 `[0,0,0,0]`。分析色数不限制最终输出色数。
|
||||
- 像素规整 CPU 工作使用进程级最大并发 `2`;取得并发许可的排队时间与实际处理时间共享最多 `30` 秒预算,同时不得晚于当前请求 deadline,最终以两者中更早者为准。输入图片任一边不得超过 `10000` 像素,总像素不得超过 `8294400`;超限、排队超时或处理超时均保留 Alpha 已回贴的透明图并走非致命降级。
|
||||
- 逻辑低分辨率图只存在内存;snapper 在规整内部使用 nearest 恢复到当前 RGBA 输入尺寸,该输入已经是前述 Lanczos 归一后的交付尺寸,或尺寸归一无法安全执行时保留的 provider 实际尺寸。nearest 不是新的交付尺寸归一,规整完成后也不再执行第二次 Lanczos 或其它尺寸恢复。实现应复用 Alpha 回贴阶段读取的已持久化平底原图;必要时最多增加一次读取已有 provider 对象的 OSS GET,不得增加 OSS PUT。
|
||||
- 开启或关闭像素风格都保持现有 provider 原图与透明主图两份产物、项目资源和画布图层数量不变。禁止上传逻辑低分辨率图、像素化前后双份主图、预览或诊断图,也不新增 asset kind、画布 item 或任务类型。
|
||||
- snapper 把每对相邻横纵切线围成的采样单元各压成一个输出像素,并把这张逻辑分辨率图直接编码为最终透明 PNG;不得再用 nearest 或其它插值恢复到当前 RGBA 输入尺寸。前述 Lanczos 交付尺寸归一继续保留,它只定义网格分析源与 RGBA 采样源的共同坐标系;两份内部输入仍必须同尺寸,但最终 PNG 宽高可以与该输入不同。实现应复用 Alpha 回贴阶段读取的已持久化平底原图;必要时最多增加一次读取已有 provider 对象的 OSS GET,不得增加 OSS PUT。
|
||||
- 开启或关闭像素风格都保持现有 provider 原图与透明主图两份产物、项目资源和画布图层数量不变。开启时透明主图本身就是唯一的逻辑分辨率 PNG;禁止另存输入尺寸恢复版、像素化前后双份主图、预览或诊断图,也不新增 asset kind、画布 item 或任务类型。资源、响应和画布结果使用最终 PNG 的实际宽高,不要求与生成交付尺寸或占位尺寸相等。
|
||||
- 本功能不修改 BgFilter `flat` 调用、`cross_check=on`、fallback、Alpha 回贴或默认关闭 despill 的现状。BgFilter 最终失败时沿用只保留 provider 原图的既有收口且不运行像素规整;像素规整自身失败时保留已成功的透明图并继续原有持久化,通过通用 `warning` 非致命提示,不退款。
|
||||
|
||||
- `kind = "character"` 时,后端不直接把前端文本当完整生图提示词,而是把文本作为 `角色设定` 填入固定提示词骨架:
|
||||
@@ -119,7 +119,7 @@
|
||||
- `从画布中选择` 后点击已有画布图片可绑定为角色规范,`Esc` 可退出点选状态。
|
||||
- 上传常规参考图后缩略图右下角显示序号。
|
||||
- 输入角色设定并生成时,请求包含 `kind: "character"`、角色设定 prompt、参考图数组、`model`、`screenColor`、`aspectRatio` 和 `imageSize`。
|
||||
- 角色面板可选择 `style: "none" | "pixelArt"`;`none` 的处理路径和产物保持不变,且提交给 provider 的提示词与未带该字段时逐字一致,`pixelArt` 在提示词末尾追加「角色主体为像素风格」并在 Alpha 回贴后执行内存像素规整,最终 OSS PUT、项目资源和画布图层数量不得增加。
|
||||
- 角色面板可选择 `style: "none" | "pixelArt"`;`none` 的处理路径和产物保持不变,且提交给 provider 的提示词与未带该字段时逐字一致,`pixelArt` 在提示词末尾追加「角色主体为像素风格」并在 Alpha 回贴后执行内存像素规整,直接持久化逻辑分辨率透明 PNG;该 PNG 可以与规整输入尺寸不同,最终 OSS PUT、项目资源和画布图层数量不得增加。
|
||||
- 默认打开角色生成面板时选中 `nanobanana2 / 1:1 / 1K`;切换到 `gpt-image-2` 后再次打开角色或图标素材面板应沿用该模型。
|
||||
- 生成成功后在占位图位置创建 `assetKind: "character"` 图层,右上角显示 `角色` 标签,布局保存包含该字段。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user