WIP: fix/引用持久化 #365

Draft
k88936 wants to merge 39 commits from fix/ref-persistent into master
Member

close #360

after:
shotmd-1789472209.jpg

close #360 after: ![shotmd-1789472209.jpg](/attachments/143b5bd0-cd46-4082-a496-79c23f34d708)
k88936 added 1 commit 2026-09-15 14:56:38 +08:00
新增 DirectProject 用户 Response item 契约
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 4m35s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 4m34s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m36s
Project CI / Backend tests (pull_request) Failing after 10s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 4m31s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 4m46s
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m32s
Project CI / Frontend tests (pull_request) Successful in 4m0s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m34s
Project CI / Native shell tests (pull_request) Successful in 6m35s
dfd6fadedf
新增 Rust canonical user item 与 Codex wire 转换模块

增加 ts-rs 绑定目录及生成文件检查边界

更新聊天素材引用规范与里程碑实施计划
k88936 added 2 commits 2026-09-15 15:27:18 +08:00
将 direct_runtime 与 codex_app_server 改为目录模块

拆分 user item 的模型、校验与 wire 投影文件

抽离 DirectProject 历史注入载荷构造 seam
抽离 DirectProject 身份解析模块
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 2m16s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 2m20s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 2m4s
Project CI / Backend tests (pull_request) Failing after 18s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 1m54s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m22s
Project CI / Repository checks (pull_request) Failing after 9s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m20s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m36s
Project CI / Frontend tests (pull_request) Successful in 3m45s
Project CI / Native shell tests (pull_request) Successful in 5m27s
5ec40c8b83
将项目 canonical identity 与 digest 放入独立文件

保持 Codex app-server 线程池调用接口不变
k88936 added a new dependency 2026-09-15 15:51:56 +08:00
k88936 added 7 commits 2026-09-15 16:48:56 +08:00
移除 game-creator-conversation.v1 读取 fallback

历史注入前逐项投影 canonical user item 为 Codex message

无效 item 在持久化前失败关闭
拒绝资源引用额外身份字段与未知 content part

补充历史 item wire 投影边界测试

同步 DirectProject 历史文档为无 fallback 合同
移除 DirectCodexTurnReference 平行 DTO 与渲染路径

将引用数量上限收回 canonical user item 校验模块
覆盖 Lexical 文本与引用交错顺序

验证资源引用只发送稳定 resourceId
标记 canonical、wire 与失败关闭验收项

同步实施计划为进行中状态
按 Lexical 顺序构造 message.content

DirectProject payload 改为发送 userItem

策略重试保留同一 canonical item
收紧历史测试与注释口径
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 2m17s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 2m7s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m7s
Project CI / Backend tests (pull_request) Failing after 19s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 2m19s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 2m17s
Project CI / Repository checks (pull_request) Failing after 11s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m26s
Project CI / AI game creator shell web tests (pull_request) Failing after 3m43s
Project CI / Frontend tests (pull_request) Failing after 4m6s
Project CI / Native shell tests (pull_request) Successful in 7m29s
17716347e2
移除 legacy 投影描述

将历史测试统一为 Response item 合同
Author
Member
  • 1. apps/ai-game-creator-shell/src/App.tsx:6490directTurnInput.userItem 重复赋值

    • 当前实现:对象字面量已经写入 userItem: effectiveUserItem,后面又再次赋同一值。
    • 问题判断:有效但仅属死代码,不改变行为。
    • 处理:已删除重复赋值。提交:2c623bb57(移除 DirectProject 回合输入的重复赋值)。
  • 2. apps/ai-game-creator-shell/src/App.tsx:6070 非 DirectCodex 路径提前创建回合身份

    • 当前实现:handleChatSubmit 无条件创建 DirectCodex 回合 ID 和 user item,随后旧 Supervisor/策划路径也会接收到该可选 ID。
    • 问题判断:有效的轻微一致性问题;会做无用工作,并可能让策划回合使用错误前缀身份。
    • 处理:仅 DirectCodex 产品运行时创建 ID 和 user item,其他路径交给各自执行器生成身份。提交:b3b5d7799(按运行模式创建 DirectProject 回合输入)。
  • 3. direct_project_history.rs:185-190 删除 legacy 行投影导致历史读取失败

    • 当前实现:DirectProject reader 对非 response_item 行失败关闭。
    • 问题判断:review 把旧通用 conversation 行当成了本次必须兼容的输入,但里程碑明确“legacy conversation 行不提供 fallback”;本次不做迁移、不加 fallback 符合设计。
    • 处理:不改代码,保留 fail-closed 边界。
  • 4. codex_app_server/mod.rs:15-16 顶层 sha2 import 未使用

    • 当前实现:该文件后续仍使用 Sha256/Digest 计算输出、认证和配置摘要。
    • 问题判断:过时误报,删除会导致编译失败。
    • 处理:不改代码。
  • 5. ResourceReferenceInput.tsx sameDraft 比较 content 造成反复回写

    • 当前实现:输入区已按 Home 模式改为 Lexical EditorState 单一 authority;文本、引用和 canonical content[] 都从该 state 读出。
    • 问题:原先的 sameDraftValue / sameCanonicalDraft 是旧双状态同步的补偿,会造成重复比较和潜在回写。
    • 处理:删除两层 draft 比较;外部清空/替换走编辑器 handle,普通输入只由 Lexical OnChangePlugin 产生。
  • 6. ResourceReferenceInput.tsx:205-210 资源引用到 content part 的映射重复

    • 当前实现:组件内重复构造 resource/runtime-region 两种 part。
    • 问题判断:有效的低风险维护问题,字段新增时存在漂移风险。
    • 处理:复用 chatReferenceToContentPart。提交:f213987f9(复用资源引用的统一内容映射)。
  • 7. resourceReferences.ts content 缺失时把 text/references 拼成猜测输入

    • 当前实现:DirectProject user item 只接受从 Lexical EditorState 派生的 canonical content[];转换入口不再读取 text + references 猜测顺序。
    • 问题:旧回退会重复表达引用并丢失编辑顺序,也会掩盖调用方没有 canonical content 的错误。
    • 处理:删除 legacy fallback;DirectProject 缺少 user item 时直接失败关闭,首轮使用显式 canonical input_text 构造。
  • 8. resourceReferences.ts:130-132 嵌套三元表达式

    • 当前实现:content 回退优先级用嵌套三元表达。
    • 问题判断:不改变行为的可读性问题。
    • 处理:改成显式 if/else 三分支。提交:a543b75cf(拆开聊天草稿内容分支判断)。
  • 10. wire.rs:43-44 校验与 wire 投影重复读取 manifest

    • 当前实现:wire 投影先校验,再单独读取 manifest;prompt 调用链还会再次进入 wire。
    • 问题判断:有效的低风险性能问题。
    • 处理:校验函数返回已读取的 manifest,wire 投影复用它。提交:f2030a616(复用 DirectProject 用户输入校验读取的 manifest)。
  • 11. model.rs:67-69 未使用的 DirectCodexUserMessageEnvelope

    • 当前实现:类型仅定义/内部 re-export,代码库无调用,生成目录也没有对应绑定。
    • 问题判断:有效的死 API 面;删除不影响现有调用方。
    • 处理:移除类型及 re-export。提交:cd2edd696(移除未使用的 DirectProject 输入信封类型)。
  • 12. direct_runtime/user_input.rs 附件未进入 DirectProject 模型 prompt

    • 当前实现:附件/图片继续使用现有 DirectCodexTurnAttachment sidecar;canonical user item 不新增附件 part。
    • 问题:此前 command 只把附件写入 audit,没有调用既有的有界路径映射渲染,模型收不到附件和图片信息。
    • 处理:DirectProject command 在 canonical item 投影后调用 render_direct_codex_user_prompt;图片、Markdown 和其它文件统一输出原名、项目路径、类型、大小、状态。附件-only 输入允许在 sidecar 渲染前保持空 canonical 文本。
  • 13. direct_runtime/mod.rs:4169 两个互斥分支克隆整个 optional JSON

    • 当前实现:两个分支都对不再使用的 direct_user_item 调用 .clone()
    • 问题判断:有效的低风险性能问题。
    • 处理:在互斥分支中直接移动值。提交:22e830ff9(避免 DirectProject 回合输入的无必要克隆)。
  • 14. ResourceReferenceInput.tsx:192-194 空白 text node 进入 canonical content

    • 当前实现:引用后的空格和换行也会生成 input_text,Rust 校验拒绝 trim 后为空的 part。
    • 问题:带引用的常见提交可能失败,属于高影响输入行为。
    • 处理:编辑器读取时跳过纯空白 part、合并相邻文本。提交:3c7b02b9f(过滤 DirectProject 编辑器的空白内容 part)。
  • 15. direct_project_history_wire.rs:18-21 标准历史 item 被重新投影为错误 wire 形状

    • 当前实现:标准 assistant/tool 等非 user item 原样透传;user canonical item 经过 direct_codex_user_item_to_response_item 后,文本 part 当前明确生成为 type: "input_text"
    • 问题判断:review 依据的是旧中间状态;当前源码和 response_item_projection_uses_input_text_not_turn_input_text 测试已覆盖该口径,不需要迁移或 fallback。
    • 处理:不改代码。
  • 16. codex_app_server/mod.rs:2661-2663 canonical AGC part 写入聊天历史后读取丢失

    • 当前实现:追加原始 canonical item,但聊天历史读取只提取 text content part。
    • 问题:纯引用消息或含引用消息在重载后可能显示为空/被过滤。
    • 建议:扩展 history reader 读取 canonical part,或在写入 chat projection 时明确生成安全文本投影;需先定历史真相边界。
  • 17. App.tsx:6072 chatContent 可能携带空白 input_text

    • 当前实现:前端把 Lexical 原始 content 直接传给 converter,引用分隔空格/换行不会被过滤。
    • 问题:与第 14 条同源,会被 Rust 校验拒绝。
    • 处理:在统一 chatComposerDraftToDirectCodexUserItem 转换入口过滤纯空白 input_text。提交:35733f0e3(过滤 canonical 草稿中的空白输入 part)。
  • 18. App.tsx:743-745 规划 V2 提交后未清理引用草稿

    • 当前实现:planning-v2 分支只清空文本,未清空 references/content。
    • 问题判断:有效的低风险状态残留问题。
    • 处理:提交规划回合时同步清空 chatReferenceschatContent。提交:c266ae7b5(清理策划模式提交后的聊天草稿)。
  • 19. direct_codex_user_item/wire.rs:26-30 response item 使用 text 而非 input_text

    • 当前实现:direct_codex_user_item_to_wire_input 内部确实使用 type: "text",但它只服务 turn/start prompt;历史 response item 走另一个投影函数,并明确改成 type: "input_text"
    • 问题判断:review 把两个不同 wire seam 混为一谈;当前实现已分离,不能据此判定“历史投影使用 text”。
    • 处理:不改代码。
  • 21. direct_runtime/user_input.rs:51-62 显式校验与空 prompt 分支重复/不可达

    • 当前实现:调用 direct_codex_user_item_to_prompt 已包含校验和空 prompt 失败,外层再次校验并检查空字符串。
    • 问题判断:有效的低风险重复逻辑。
    • 处理:复用投影函数的错误收口,删除重复校验和不可达分支。提交:1da106af7(避免重复校验 DirectProject 用户输入)。
- [x] 1. `apps/ai-game-creator-shell/src/App.tsx:6490` 的 `directTurnInput.userItem` 重复赋值 - 当前实现:对象字面量已经写入 `userItem: effectiveUserItem`,后面又再次赋同一值。 - 问题判断:有效但仅属死代码,不改变行为。 - 处理:已删除重复赋值。提交:`2c623bb57`(移除 DirectProject 回合输入的重复赋值)。 - [x] 2. `apps/ai-game-creator-shell/src/App.tsx:6070` 非 DirectCodex 路径提前创建回合身份 - 当前实现:`handleChatSubmit` 无条件创建 DirectCodex 回合 ID 和 user item,随后旧 Supervisor/策划路径也会接收到该可选 ID。 - 问题判断:有效的轻微一致性问题;会做无用工作,并可能让策划回合使用错误前缀身份。 - 处理:仅 DirectCodex 产品运行时创建 ID 和 user item,其他路径交给各自执行器生成身份。提交:`b3b5d7799`(按运行模式创建 DirectProject 回合输入)。 - [x] 3. `direct_project_history.rs:185-190` 删除 legacy 行投影导致历史读取失败 - 当前实现:DirectProject reader 对非 `response_item` 行失败关闭。 - 问题判断:review 把旧通用 conversation 行当成了本次必须兼容的输入,但里程碑明确“legacy conversation 行不提供 fallback”;本次不做迁移、不加 fallback 符合设计。 - 处理:不改代码,保留 fail-closed 边界。 - [x] 4. `codex_app_server/mod.rs:15-16` 顶层 `sha2` import 未使用 - 当前实现:该文件后续仍使用 `Sha256`/`Digest` 计算输出、认证和配置摘要。 - 问题判断:过时误报,删除会导致编译失败。 - 处理:不改代码。 - [x] 5. `ResourceReferenceInput.tsx` `sameDraft` 比较 content 造成反复回写 - 当前实现:输入区已按 Home 模式改为 Lexical `EditorState` 单一 authority;文本、引用和 canonical `content[]` 都从该 state 读出。 - 问题:原先的 `sameDraftValue` / `sameCanonicalDraft` 是旧双状态同步的补偿,会造成重复比较和潜在回写。 - 处理:删除两层 draft 比较;外部清空/替换走编辑器 handle,普通输入只由 Lexical `OnChangePlugin` 产生。 - [x] 6. `ResourceReferenceInput.tsx:205-210` 资源引用到 content part 的映射重复 - 当前实现:组件内重复构造 resource/runtime-region 两种 part。 - 问题判断:有效的低风险维护问题,字段新增时存在漂移风险。 - 处理:复用 `chatReferenceToContentPart`。提交:`f213987f9`(复用资源引用的统一内容映射)。 - [x] 7. `resourceReferences.ts` content 缺失时把 text/references 拼成猜测输入 - 当前实现:DirectProject user item 只接受从 Lexical `EditorState` 派生的 canonical `content[]`;转换入口不再读取 `text + references` 猜测顺序。 - 问题:旧回退会重复表达引用并丢失编辑顺序,也会掩盖调用方没有 canonical content 的错误。 - 处理:删除 legacy fallback;DirectProject 缺少 user item 时直接失败关闭,首轮使用显式 canonical `input_text` 构造。 - [x] 8. `resourceReferences.ts:130-132` 嵌套三元表达式 - 当前实现:content 回退优先级用嵌套三元表达。 - 问题判断:不改变行为的可读性问题。 - 处理:改成显式 `if/else` 三分支。提交:`a543b75cf`(拆开聊天草稿内容分支判断)。 - [x] 10. `wire.rs:43-44` 校验与 wire 投影重复读取 manifest - 当前实现:wire 投影先校验,再单独读取 manifest;prompt 调用链还会再次进入 wire。 - 问题判断:有效的低风险性能问题。 - 处理:校验函数返回已读取的 manifest,wire 投影复用它。提交:`f2030a616`(复用 DirectProject 用户输入校验读取的 manifest)。 - [x] 11. `model.rs:67-69` 未使用的 `DirectCodexUserMessageEnvelope` - 当前实现:类型仅定义/内部 re-export,代码库无调用,生成目录也没有对应绑定。 - 问题判断:有效的死 API 面;删除不影响现有调用方。 - 处理:移除类型及 re-export。提交:`cd2edd696`(移除未使用的 DirectProject 输入信封类型)。 - [x] 12. `direct_runtime/user_input.rs` 附件未进入 DirectProject 模型 prompt - 当前实现:附件/图片继续使用现有 `DirectCodexTurnAttachment` sidecar;canonical user item 不新增附件 part。 - 问题:此前 command 只把附件写入 audit,没有调用既有的有界路径映射渲染,模型收不到附件和图片信息。 - 处理:DirectProject command 在 canonical item 投影后调用 `render_direct_codex_user_prompt`;图片、Markdown 和其它文件统一输出原名、项目路径、类型、大小、状态。附件-only 输入允许在 sidecar 渲染前保持空 canonical 文本。 - [x] 13. `direct_runtime/mod.rs:4169` 两个互斥分支克隆整个 optional JSON - 当前实现:两个分支都对不再使用的 `direct_user_item` 调用 `.clone()`。 - 问题判断:有效的低风险性能问题。 - 处理:在互斥分支中直接移动值。提交:`22e830ff9`(避免 DirectProject 回合输入的无必要克隆)。 - [x] 14. `ResourceReferenceInput.tsx:192-194` 空白 text node 进入 canonical content - 当前实现:引用后的空格和换行也会生成 `input_text`,Rust 校验拒绝 trim 后为空的 part。 - 问题:带引用的常见提交可能失败,属于高影响输入行为。 - 处理:编辑器读取时跳过纯空白 part、合并相邻文本。提交:`3c7b02b9f`(过滤 DirectProject 编辑器的空白内容 part)。 - [x] 15. `direct_project_history_wire.rs:18-21` 标准历史 item 被重新投影为错误 wire 形状 - 当前实现:标准 assistant/tool 等非 user item 原样透传;user canonical item 经过 `direct_codex_user_item_to_response_item` 后,文本 part 当前明确生成为 `type: "input_text"`。 - 问题判断:review 依据的是旧中间状态;当前源码和 `response_item_projection_uses_input_text_not_turn_input_text` 测试已覆盖该口径,不需要迁移或 fallback。 - 处理:不改代码。 - [x] 16. `codex_app_server/mod.rs:2661-2663` canonical AGC part 写入聊天历史后读取丢失 - 当前实现:追加原始 canonical item,但聊天历史读取只提取 `text` content part。 - 问题:纯引用消息或含引用消息在重载后可能显示为空/被过滤。 - 建议:扩展 history reader 读取 canonical part,或在写入 chat projection 时明确生成安全文本投影;需先定历史真相边界。 - [x] 17. `App.tsx:6072` chatContent 可能携带空白 input_text - 当前实现:前端把 Lexical 原始 content 直接传给 converter,引用分隔空格/换行不会被过滤。 - 问题:与第 14 条同源,会被 Rust 校验拒绝。 - 处理:在统一 `chatComposerDraftToDirectCodexUserItem` 转换入口过滤纯空白 `input_text`。提交:`35733f0e3`(过滤 canonical 草稿中的空白输入 part)。 - [x] 18. `App.tsx:743-745` 规划 V2 提交后未清理引用草稿 - 当前实现:planning-v2 分支只清空文本,未清空 references/content。 - 问题判断:有效的低风险状态残留问题。 - 处理:提交规划回合时同步清空 `chatReferences` 和 `chatContent`。提交:`c266ae7b5`(清理策划模式提交后的聊天草稿)。 - [x] 19. `direct_codex_user_item/wire.rs:26-30` response item 使用 `text` 而非 `input_text` - 当前实现:`direct_codex_user_item_to_wire_input` 内部确实使用 `type: "text"`,但它只服务 turn/start prompt;历史 response item 走另一个投影函数,并明确改成 `type: "input_text"`。 - 问题判断:review 把两个不同 wire seam 混为一谈;当前实现已分离,不能据此判定“历史投影使用 text”。 - 处理:不改代码。 - [x] 21. `direct_runtime/user_input.rs:51-62` 显式校验与空 prompt 分支重复/不可达 - 当前实现:调用 `direct_codex_user_item_to_prompt` 已包含校验和空 prompt 失败,外层再次校验并检查空字符串。 - 问题判断:有效的低风险重复逻辑。 - 处理:复用投影函数的错误收口,删除重复校验和不可达分支。提交:`1da106af7`(避免重复校验 DirectProject 用户输入)。
k88936 added 10 commits 2026-09-15 17:51:07 +08:00
区分 turn/start 的 text 与历史 message 的 input_text

将 AGC 私有引用转换为标准 input_text

新增回归测试避免未知 variant text
删除已在对象初始化时设置的 userItem 重复赋值。
让 Lexical 草稿读取复用 chatReferenceToContentPart,避免引用字段映射分叉。
将资源草稿转换的三种回退路径改为显式分支,保持现有优先级并提升可读性。
规划 V2 提交时同步清空资源引用和 canonical content,避免切回 DirectProject 后复用旧输入。
在互斥的观察器分支中移动 optional user item,避免深层 JSON 克隆。
删除未被调用且未生成到前端绑定的 DirectCodexUserMessageEnvelope,收窄内部 API。
复用 canonical 到 prompt 投影函数中的校验,删除不可达空 prompt 分支。
仅在 DirectCodex 产品运行时生成 direct clientTurnId 和 user item,避免旧 Supervisor 与策划链路复用错误身份。
复用 DirectProject 用户输入校验读取的 manifest
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 1m44s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 2m19s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 2m19s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 2m17s
Project CI / Backend tests (pull_request) Failing after 11s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m17s
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m26s
Project CI / Frontend tests (pull_request) Failing after 3m5s
Project CI / AI game creator shell web tests (pull_request) Failing after 2m51s
Project CI / Native shell tests (pull_request) Successful in 6m21s
f2030a616f
让校验返回已读取的 manifest,wire 投影复用同一份数据,避免一次输入重复读取项目清单。
k88936 added 4 commits 2026-09-15 23:55:39 +08:00
跳过纯空白文本节点并合并相邻文本,避免引用后的分隔空格和换行触发 Rust 空输入校验。
在统一 user item 转换入口移除纯空白 input_text,覆盖恢复草稿和所有提交路径。
新增可复用的 RichTextInput Lexical 输入外壳。

让首页输入与资源引用输入共享编辑器、回车提交和禁用状态。

保留首页附件与图片粘贴节点能力,并移除 DirectProject 草稿 legacy fallback。

统一聊天草稿 canonical content 状态并更新资源引用测试。
收敛输入编辑器单一状态并补齐附件投影
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 2m6s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 1m49s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 1m56s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 2m2s
Project CI / Backend tests (pull_request) Failing after 11s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m19s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m46s
Project CI / Repository checks (pull_request) Failing after 15s
Project CI / Frontend tests (pull_request) Failing after 3m54s
Project CI / AI game creator shell web tests (pull_request) Failing after 3m13s
Project CI / Native shell tests (pull_request) Successful in 7m14s
87b798322e
聊天与快速编辑输入统一由 Lexical 编辑器持有唯一当前状态

App 通过输入句柄读取草稿,移除跨视图 EditorState 和字符串镜像

DirectProject 将附件与图片 sidecar 投影纳入 prompt,支持附件-only 输入

迁移润色测试并更新 DirectProject 里程碑验收记录
kdletters added this to the 陶泥儿gameAgent project 2026-09-16 12:11:45 +08:00
kdletters moved this to 评估中 in 陶泥儿gameAgent on 2026-09-16 12:12:21 +08:00
k88936 added 2 commits 2026-09-16 13:06:39 +08:00
合并主线回合队列、工具流展示与活动回合管理

保留 Lexical 单一输入状态及附件图片 sidecar 投影

收敛 DirectProject user item 校验、历史恢复与图片预算

同步输入链路里程碑和历史异常恢复文档
内联 DirectProject 附件与图片内容
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 5m30s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 5m35s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 5m54s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 6m1s
Project CI / Backend tests (pull_request) Failing after 9s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m52s
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m41s
Project CI / Frontend tests (pull_request) Failing after 3m54s
Project CI / AI game creator shell web tests (pull_request) Failing after 3m41s
Project CI / Native shell tests (pull_request) Successful in 6m9s
46e3cd9744
新增附件与图片 canonical content part 及 ts-rs 绑定

移除 DirectProject Tauri 附件 sidecar 追加路径

修正前端引用字段与生成类型适配

补充附件图片顺序投影测试并同步里程碑文档
k88936 added 9 commits 2026-09-16 16:25:06 +08:00
- 仅在非纯聊天模式清空聊天编辑器

- 保留纯聊天模式恢复的会话草稿
- 准备命令草稿前先清空编辑器

- 避免提交用户上一轮选择的素材引用
- 为快速编辑输入区绑定编辑器句柄

- 润色回调同时更新面板状态与编辑器文本
- 用 React 状态同步编辑器当前文本

- 让按钮禁用态随用户输入即时更新
- 仅在初始内容实际非空时跳过初始化回调

- 保证快速编辑首次输入同步到宿主状态
- 在编辑器发出空草稿时重置润色结果

- 清除本轮发送提醒确认标记
- 编辑器尚未恢复时跳过空草稿持久化

- 保留已有会话草稿等待输入区完成恢复
- 回填前比较编辑器当前文本

- 防止输入区 onChange 与宿主回调形成循环
补充DirectProject canonical内容严格边界计划
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
f4b496caca
- 明确 content-only 输入与最终空内容校验

- 规划删除 userItem 兜底并修正 Direct caller
Author
Member

Review 复核与处理结果

以下结论以当前代码为准;review.txt 只是临时清单,不纳入任何提交。

  • 1. apps/ai-game-creator-shell/src/App.tsx:4375-4377 总控纯聊天草稿恢复后被立即清空(high)

    • 当前实现:打开项目后先恢复草稿,随后无条件清空编辑器。
    • 问题:清空触发 OnChangePlugin,空文本覆盖刚恢复的草稿。
    • 处理:纯聊天模式只恢复草稿;非纯聊天模式才清空。已提交 b60750191(修复总控草稿恢复后被清空)。
    • 建议:保留总控草稿恢复测试覆盖导航/重载。
  • 2. apps/ai-game-creator-shell/src/App.tsx:4618 准备建议命令时残留旧引用(medium)

    • 当前实现:replaceText() 按设计保留当前编辑器中的引用节点。
    • 问题:建议命令应从干净草稿开始,否则上一轮素材引用会随命令提交。
    • 处理:准备命令前先 clear()replaceText()。已提交 30e27abc6(修复建议命令草稿残留引用)。
    • 建议:需要保留引用时新增明确的整体草稿替换 API。
  • 3. apps/ai-game-creator-shell/src/view/project-development/index.tsx:8127-8130 快速编辑润色结果未进入编辑器(medium)

    • 当前实现:输入区只在首次挂载应用 initialDraft;润色回调只更新 panel 状态。
    • 问题:Lexical 仍显示旧文本,下一次编辑会把旧文本写回父状态。
    • 处理:绑定 ResourceReferenceInputHandle,润色时幂等回写编辑器文本。已提交 d5c4e0e78fc0fd846f
    • 建议:继续保持编辑器为唯一输入真相,回填前比较文本。
  • 4. apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx:1010-1012 润色按钮不会随输入启用(high)

    • 当前实现:渲染读取只在 OnChangePlugin 中变更的 ref。
    • 问题:ref 变更不触发 React 重渲染,按钮可能一直禁用。
    • 处理:新增 draftText state,编辑器变更时同步,按钮改读 state。已提交 0b9d16e8f(修复润色按钮无法感知输入)。
    • 建议:ref 用于事件闭包,state 仅用于渲染派生状态。
  • 5. apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx:644-645 空初始草稿吞掉首次编辑(medium)

    • 当前实现:无论初始草稿是否产生变化都设置跳过初始化回调。
    • 问题:空初始化不触发 Lexical 变更,第一次真实输入被误吞。
    • 处理:仅初始文本非空或有引用时跳过。已提交 645d806fe(修复空初始草稿吞掉首次编辑)。
    • 建议:保留空草稿首次输入回归测试。
  • 6. apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx:867-868 清空草稿后润色状态残留(medium)

    • 当前实现:重置 effect 只在挂载时执行,后续 ref 变化不会触发。
    • 问题:“恢复原文”按钮和发送确认标记可能残留到下一轮。
    • 处理:空草稿由 OnChangePlugin 同步重置润色结果和确认标记。已提交 64a52005f(修复清空草稿后润色状态残留)。
    • 建议:文本与引用都为空才视为新一轮。
  • 7. apps/ai-game-creator-shell/src/App.tsx:3083-3084 初始化阶段空持久化覆盖总控草稿(high)

    • 当前实现:effect 读取尚未恢复的编辑器并立即持久化。
    • 问题:空写入删除 sessionStorage 中的已有草稿。
    • 处理:空草稿时跳过该 effect;用户真实清空仍由输入变更回调处理。已提交 fa99d9ad6(避免总控草稿初始化误删)。
    • 建议:以后用显式 seeded 状态表达恢复时序。
  • 8. apps/ai-game-creator-shell/src/features/project-workspace/resourceReferences.ts:121-123 canonical content 为空时丢失文本/引用(high)

    • 这里的“转换函数”是 chatComposerDraftToDirectCodexUserItem(draft, id):把输入框的 ChatComposerDraft 转成 Rust/Direct Codex 接收的 DirectCodexUserItem,其中 content 是唯一 canonical 消息内容。
    • 它为什么过滤:原实现把纯空白 input_text(引用后的分隔空格、段落换行)在转换函数里又过滤了一遍。这个过滤其实已经由 Lexical 投影层做过(Rust validate_direct_codex_user_item 会拒绝空 input_text),属于重复过滤,只会让人误以为“转换函数在替用户改写内容”。
    • “回退调用”具体指 App.tsxuserItem ?? chatComposerDraftToDirectCodexUserItem(...)?? 左边没传 userItem 时才执行右边的兜底构造,而兜底传的是 { text: prompt, references, content: [] }。首页首轮创建也走这条兜底。此时 prompt/references 有值、content 却是空数组,最终 user message 的文本与引用被静默丢掉。
    • 处理:按「修调用方、保持 canonical 契约严格」落地——转换函数原样传递 draft.content,不再做二次过滤;ChatComposerDraft 删掉 text / references,只保留 content;删除 executeChatAgentReplyuserItem 兜底分支,首页首轮、普通聊天提交、运行中队列出队、策略确认重试全部显式构造 canonical user item;发送前只在最终 content 上判断是否全空(hasMeaningfulDirectCodexContent),不做预过滤;旧 Planner / legacy Supervisor caller 显式构造纯文本 item 并留迁移 TODO。已提交 41366dd71
    • 建议:新入口统一走 directCodexUserItemFromContent(content, id);需要文本的地方(草稿持久化、队列 chip、润色判据)用 directCodexContentToPromptText(content, assets) 从 content 派生,不要再引入并行的文本字段。
  • 9. apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx:641-643 快速编辑 initialDraft 单次应用导致润色后显示旧文本(high,和第 3 条重复)

    • 当前实现/问题:与第 3 条同一根因,编辑器与宿主 prompt 脱节。
    • 处理:已由第 3 条的 editor handle 回填覆盖,无额外代码变更;详见 d5c4e0e78fc0fd846f
    • 建议:后续评审将本条与第 3 条合并。
# Review 复核与处理结果 以下结论以当前代码为准;`review.txt` 只是临时清单,不纳入任何提交。 - [x] 1. `apps/ai-game-creator-shell/src/App.tsx:4375-4377` 总控纯聊天草稿恢复后被立即清空(high) - 当前实现:打开项目后先恢复草稿,随后无条件清空编辑器。 - 问题:清空触发 `OnChangePlugin`,空文本覆盖刚恢复的草稿。 - 处理:纯聊天模式只恢复草稿;非纯聊天模式才清空。已提交 `b60750191`(修复总控草稿恢复后被清空)。 - 建议:保留总控草稿恢复测试覆盖导航/重载。 - [x] 2. `apps/ai-game-creator-shell/src/App.tsx:4618` 准备建议命令时残留旧引用(medium) - 当前实现:`replaceText()` 按设计保留当前编辑器中的引用节点。 - 问题:建议命令应从干净草稿开始,否则上一轮素材引用会随命令提交。 - 处理:准备命令前先 `clear()` 再 `replaceText()`。已提交 `30e27abc6`(修复建议命令草稿残留引用)。 - 建议:需要保留引用时新增明确的整体草稿替换 API。 - [x] 3. `apps/ai-game-creator-shell/src/view/project-development/index.tsx:8127-8130` 快速编辑润色结果未进入编辑器(medium) - 当前实现:输入区只在首次挂载应用 `initialDraft`;润色回调只更新 panel 状态。 - 问题:Lexical 仍显示旧文本,下一次编辑会把旧文本写回父状态。 - 处理:绑定 `ResourceReferenceInputHandle`,润色时幂等回写编辑器文本。已提交 `d5c4e0e78`、`fc0fd846f`。 - 建议:继续保持编辑器为唯一输入真相,回填前比较文本。 - [x] 4. `apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx:1010-1012` 润色按钮不会随输入启用(high) - 当前实现:渲染读取只在 `OnChangePlugin` 中变更的 ref。 - 问题:ref 变更不触发 React 重渲染,按钮可能一直禁用。 - 处理:新增 `draftText` state,编辑器变更时同步,按钮改读 state。已提交 `0b9d16e8f`(修复润色按钮无法感知输入)。 - 建议:ref 用于事件闭包,state 仅用于渲染派生状态。 - [x] 5. `apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx:644-645` 空初始草稿吞掉首次编辑(medium) - 当前实现:无论初始草稿是否产生变化都设置跳过初始化回调。 - 问题:空初始化不触发 Lexical 变更,第一次真实输入被误吞。 - 处理:仅初始文本非空或有引用时跳过。已提交 `645d806fe`(修复空初始草稿吞掉首次编辑)。 - 建议:保留空草稿首次输入回归测试。 - [x] 6. `apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx:867-868` 清空草稿后润色状态残留(medium) - 当前实现:重置 effect 只在挂载时执行,后续 ref 变化不会触发。 - 问题:“恢复原文”按钮和发送确认标记可能残留到下一轮。 - 处理:空草稿由 `OnChangePlugin` 同步重置润色结果和确认标记。已提交 `64a52005f`(修复清空草稿后润色状态残留)。 - 建议:文本与引用都为空才视为新一轮。 - [x] 7. `apps/ai-game-creator-shell/src/App.tsx:3083-3084` 初始化阶段空持久化覆盖总控草稿(high) - 当前实现:effect 读取尚未恢复的编辑器并立即持久化。 - 问题:空写入删除 sessionStorage 中的已有草稿。 - 处理:空草稿时跳过该 effect;用户真实清空仍由输入变更回调处理。已提交 `fa99d9ad6`(避免总控草稿初始化误删)。 - 建议:以后用显式 seeded 状态表达恢复时序。 - [x] 8. `apps/ai-game-creator-shell/src/features/project-workspace/resourceReferences.ts:121-123` canonical `content` 为空时丢失文本/引用(high) - 这里的“转换函数”是 `chatComposerDraftToDirectCodexUserItem(draft, id)`:把输入框的 `ChatComposerDraft` 转成 Rust/Direct Codex 接收的 `DirectCodexUserItem`,其中 `content` 是唯一 canonical 消息内容。 - 它为什么过滤:原实现把纯空白 `input_text`(引用后的分隔空格、段落换行)在转换函数里又过滤了一遍。这个过滤其实已经由 Lexical 投影层做过(Rust `validate_direct_codex_user_item` 会拒绝空 `input_text`),属于重复过滤,只会让人误以为“转换函数在替用户改写内容”。 - “回退调用”具体指 `App.tsx` 的 `userItem ?? chatComposerDraftToDirectCodexUserItem(...)`:`??` 左边没传 `userItem` 时才执行右边的兜底构造,而兜底传的是 `{ text: prompt, references, content: [] }`。首页首轮创建也走这条兜底。此时 `prompt`/`references` 有值、`content` 却是空数组,最终 user message 的文本与引用被静默丢掉。 - 处理:按「修调用方、保持 canonical 契约严格」落地——转换函数原样传递 `draft.content`,不再做二次过滤;`ChatComposerDraft` 删掉 `text` / `references`,只保留 `content`;删除 `executeChatAgentReply` 的 `userItem` 兜底分支,首页首轮、普通聊天提交、运行中队列出队、策略确认重试全部显式构造 canonical user item;发送前只在最终 content 上判断是否全空(`hasMeaningfulDirectCodexContent`),不做预过滤;旧 Planner / legacy Supervisor caller 显式构造纯文本 item 并留迁移 TODO。已提交 `41366dd71`。 - 建议:新入口统一走 `directCodexUserItemFromContent(content, id)`;需要文本的地方(草稿持久化、队列 chip、润色判据)用 `directCodexContentToPromptText(content, assets)` 从 content 派生,不要再引入并行的文本字段。 - [x] 9. `apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx:641-643` 快速编辑 `initialDraft` 单次应用导致润色后显示旧文本(high,和第 3 条重复) - 当前实现/问题:与第 3 条同一根因,编辑器与宿主 prompt 脱节。 - 处理:已由第 3 条的 editor handle 回填覆盖,无额外代码变更;详见 `d5c4e0e78`、`fc0fd846f`。 - 建议:后续评审将本条与第 3 条合并。
k88936 added 4 commits 2026-09-16 18:55:02 +08:00
- 移除 chatComposerDraftToDirectCodexUserItem 对纯空白 input_text 的预过滤,原样传递 draft.content
- ChatComposerDraft 只保留 canonical content,删除 text / references 旧字段
- 新增 directCodexContentToPromptText、hasMeaningfulDirectCodexContent、directCodexUserItemFromContent 供 caller 与展示派生
- 删除 executeChatAgentReply 的 userItem 兜底分支,首页首轮、队列出队、普通提交与策略重试显式构造 canonical user item
- QueuedChatTurn 只保存 clientTurnId 与 userItem,队列 chip 文案由 content 派生
- 旧 Planner / legacy Supervisor caller 显式构造纯文本 item 并留下迁移 TODO
- 资源输入区对外只暴露 canonical content,内部文本草稿改为文本 → content 重建
- 迁移草稿、润色、队列与 appSurface 测试 fixture 到 content-only
- 更新 canonical content 里程碑与实施计划文档结论
- 移除 DirectCodexUserContentPart 的 agc_image_reference 分支与对应 ts-rs 绑定
- Rust 校验与 Codex wire 投影只保留 agc_attachment_reference
- 更新附件顺序投影测试的用例名、输入与断言
- 同步聊天素材功能说明、用户 Response item 里程碑与实施计划
- 在决策日志记录上传文件统一走附件 part、不保留图片兼容分支
- App.tsx 增加 supervisorChatDraftHydratedRef 守卫的挂载水合:独立总控聊天窗口挂载走 loadProjectConversation,不经过 openWorkspace,此前 sessionStorage 里的草稿只写不读,重载后为空
- 仅在 supervisorChatOnly、存在持久化草稿且输入框已挂载时回填一次,避免覆盖用户后续输入
修正 Godot 直接回合用例对 canonical content 的断言
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
edfd1f9143
- appSurface Godot 用例不再断言被裁剪过的纯文本,改为断言编辑器实际提交的 canonical content(Shift+Enter 与组合态 Enter 插入的换行原样保留)
Some checks are pending
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
This pull request has changes conflicting with the target branch.
  • apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx
  • docs/project-memory/shared-memory/decision-log.md
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin fix/ref-persistent:fix/ref-persistent
git checkout fix/ref-persistent
Sign in to join this conversation.