From 7745264990e5c2362fb6272a47fe68cc581c02f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Mon, 21 Sep 2026 21:23:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5canonical=20content=E9=87=8C?= =?UTF-8?q?=E7=A8=8B=E7=A2=91=E8=90=BD=E5=9C=B0=E7=BB=93=E6=9E=9C=E4=B8=8E?= =?UTF-8?q?=E6=B6=A6=E8=89=B2=E5=8F=A3=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 里程碑与实施计划状态改为 implemented 记录润色按 token 原位恢复引用与附件、被改写 part 末尾补位 记录遗留 TODO:润色删掉 token 时无法反推原位置 --- ...Project composer canonical content闭环-2026-09-21.md | 15 ++++++++++++--- ...roject composer canonical content闭环-2026-09-21.md | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/docs/project-memory/plans/【实施计划】DirectProject composer canonical content闭环-2026-09-21.md b/docs/project-memory/plans/【实施计划】DirectProject composer canonical content闭环-2026-09-21.md index 501900fe8..0fba5d3df 100644 --- a/docs/project-memory/plans/【实施计划】DirectProject composer canonical content闭环-2026-09-21.md +++ b/docs/project-memory/plans/【实施计划】DirectProject composer canonical content闭环-2026-09-21.md @@ -3,7 +3,7 @@ | 字段 | 值 | | --------- | --- | | Milestone | `docs/project-memory/plans/【里程碑】DirectProject composer canonical content闭环-2026-09-21.md` | -| Status | planned | +| Status | implemented | | Owner | Codex | ## 交付结果 @@ -14,7 +14,7 @@ 1. **锁定当前失败面**:补一个最小回归测试,先证明 `applyDraftToRoot` 对含 `agc_attachment_reference` 的 root 重建会丢附件,并记录 Direct 当前的三份并行状态与附件 sidecar 合并点。 2. **收窄编辑器接口**:把 `ChatComposerDraft` 改成 content-only;将 `ResourceReferenceInput` 的受控恢复改为 `initialContent` / `content` 语义,删除 Direct 使用的 `value` + `references` 同步 effect。保留 `ChatReference` 仅用于 picker 节点创建和只读投影。 -3. **替换所有 root 写入**:删除 `buildDraftSegments` / `applyDraftToRoot` 的 Direct 调用;提供一个完整的 `applyContentToRoot`(或同等深模块接口),保留文本换写、引用和附件的顺序与字段。AI 润色改为“读取 content → 只替换文本 part 的受控变换 → 按原序写回 content”,禁止用 prompt 文本重新解析 chip。 +3. **替换所有 root 写入**:删除 `buildDraftSegments` / `applyDraftToRoot` 的 Direct 调用;提供一个完整的 `applyContentToRoot`(或同等深模块接口),保留文本换写、引用和附件的顺序与字段。AI 润色改为“读取 content → 对回包文本按 token 扫描 → 原位换回真 part;被改写的 part 末尾补位”,引用与附件同一套口径。 4. **收口 Direct controller**:以 `content[]` 作为草稿事实源;上传完成的附件在一个明确的 `append`/`merge` seam 合并,不再长期维护 `chatInput`、`chatReferences`、`chatContent` 三份状态。prompt 只在调用边界派生,队列和策略重试保留原 user item。 5. **隔离非 Direct caller**:Planning V2 和资源快速编辑按各自需求选择 content-only 或独立文本 adapter;不得为了兼容它们把旧字段放回共享 Direct 接口。若快速编辑只需要文本,使用不承诺引用/附件语义的窄接口。 6. **补齐验收证据并清理**:删除无调用方的旧 helper、字段和注释;更新测试 fixture、专题文档和本计划状态。完成后把稳定结论合并回功能说明/共享记忆,并删除已完成的临时计划。 @@ -34,7 +34,7 @@ - `content[]` 是唯一可发送事实;任何 `prompt`、label、chip 文案都是派生值。 - `agc_attachment_reference` 不属于 `ChatReference`,不能借 `references` 传递。 -- 文本润色只允许改变文本 part;若产品决定重排/删除引用,必须显式产生新的 content 变换,不得通过字符串 token 猜测。 +- 润色回包只按 token 反解析引用与附件(`draftScanToken` 与出站 `directCodexContentToPromptText` 同口径);token 被删掉时不猜位置,只把该 part 补在末尾,保证不丢。 - Direct 初始首轮、普通提交、队列、权限确认重试都使用同一个 `DirectCodexUserItem` 语义。 ## 验证命令 @@ -53,3 +53,12 @@ git diff --check - 附件目前在 Direct controller 里作为待发 sidecar,若直接移入编辑器必须同步处理上传失败、移除、清空和项目切换;任何阶段都不能把附件只留在展示 chip 而未进入 user item。 - 润色服务只返回文本,不能让其响应覆盖原 content;失败时保留原 content。回滚使用 Git revert,不增加运行时开关或兼容分支。 - 工作树已有用户未提交修改,实施时只 stage 本里程碑涉及的 hunk。 + +## 落地结果 + +- 编辑器接口收窄为 content-only:`ResourceReferenceInput` 只接 `initialContent` / `onChange`,`ChatComposerDraft` 只剩 `content`;`applyDraftToRoot` 与受控 `value` / `references` 同步 effect 均删除。 +- 所有 root 写入统一走 `applyContentToRoot`;润色走 `applyPolishedTextToRoot`,对引用与附件做同一套 token 扫描并在原位置换回真 part,被改写的 part 末尾补位。 +- Direct controller 去掉 `chatInput` / `chatReferences` / `chatContent`,附件在提交边界合成进同一份 canonical content;Planning 与其它 legacy 消费方改用 `directCodexContentToLegacyContentDto` 单向取文本。 +- 删除无调用方的 `EMPTY_CHAT_COMPOSER_DRAFT`。 +- 回归证据:`resourceReferenceInput`(含附件 round-trip、润色原位恢复、润色末尾补位)、`resourceReferences`、`chatPromptPolish`、`usePromptPolish`、`resourceCanvasAssetGenerationReferences`、全量 `appSurface`、AGC typecheck、`check:encoding`、`git diff --check`。 +- 遗留 TODO:润色服务把 token 一起删掉时无法反推原位置;需要精确恢复时由产品补带位置信息的润色协议。 diff --git a/docs/project-memory/plans/【里程碑】DirectProject composer canonical content闭环-2026-09-21.md b/docs/project-memory/plans/【里程碑】DirectProject composer canonical content闭环-2026-09-21.md index 022560c43..abe3ecafa 100644 --- a/docs/project-memory/plans/【里程碑】DirectProject composer canonical content闭环-2026-09-21.md +++ b/docs/project-memory/plans/【里程碑】DirectProject composer canonical content闭环-2026-09-21.md @@ -3,7 +3,7 @@ | 字段 | 值 | | ----------- | --- | | Version | 1.0 | -| Status | planned | +| Status | implemented | | Date | 2026-09-21 | | Parent Spec | `docs/【功能说明】AGC聊天素材引用-2026-09-08.md` | | Related ADR | `docs/adr/【ADR】DirectProject独立聊天容器与工作台钱包布局-2026-09-18.md` | @@ -41,7 +41,8 @@ - `ChatComposerDraft`、`ResourceReferenceInput` 的 Direct 使用面和 Direct composer props 不再暴露 `text` / `references` 双轨草稿。 - 代码中不存在 Direct 路径对 `applyDraftToRoot(value, references)`、`replaceText(text)` 或等价 legacy 重建器的调用。 -- `content[]` 中交错的文本、资源引用、运行区域引用、Skill 和附件经过:初始恢复 → 读取 → 润色回写 → 再读取,顺序和值完全一致。 +- `content[]` 中交错的文本、资源引用、运行区域引用、Skill 和附件经过:初始恢复 → 读取 → 润色回写 → 再读取,part 一个不少。 +- 润色回包还留着 `@显示名` / `$名称` / `@附件名` 时,对应 chip 在原位置复活;token 被整体改写掉的 part 补在末尾,不丢。 - 附件-only、文本+附件、资源引用+附件、文本+资源引用+附件四类提交均只生成一份 canonical user item,附件字段完整保留。 - 队列入队、出队、策略确认重试复用同一份 `userItem.content`,不从 prompt 文本重建。 - Direct 提交清理草稿后,待发附件和 editor content 同时清空;失败或取消不会悄悄丢失待发附件。 @@ -52,3 +53,12 @@ - ResourceReferenceInput 纯投影/回写测试:包含附件节点的 round-trip 与润色回写不丢附件。 - Direct composer appSurface:四类 content 组合、队列、策略重试及清理语义。 - 类型检查、定向 Vitest、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`。 + +## 落地结果 + +- `ChatComposerDraft` 只剩 `content`;`ResourceReferenceInput` 的对外接口是 `initialContent` + `onChange` + `getDraft()`,受控 `value` / `references` 与 `applyDraftToRoot` 已删除。 +- 编辑器 root 回写只剩 `applyContentToRoot`(完整 content,含附件)一条路径;清空、初始恢复、润色回写都走它。 +- Direct composer 提交时把 editor content 与待发附件 sidecar 合成同一份 canonical content;controller 不再持有 `chatInput` / `chatReferences` / `chatContent`。 +- Planning 提交与 legacy 消费方通过单向 `directCodexContentToLegacyContentDto` 取文本,不回写编辑器。 +- 润色回写(`applyPolishedTextToRoot`)对引用与附件用同一套 token 扫描(`draftScanToken`):token 存活则原位换回真 part,被改写的 part 末尾补位;附件不再丢出 canonical content。 +- 遗留 TODO:润色服务整体改写文本、连 token 一起删掉时,前端无法反推原位置,只能末尾补位;需要精确恢复时由产品补带位置信息的润色协议。