fix: preserve drafts, canvas edits, and remote Continue tools

Keep paragraph formatting and checklist todos when removing canvas pages,
and preserve accepted undo/redo history after oversized input is rejected.
Merge restored queued text into the latest conversation draft and retain
image delivery when OCR returns image references and generated warnings only.

Deliver session MCP servers to bridged remote Continue Execute while keeping
Ask read-only and preserving local model-profile isolation. Add regression
coverage and update feature documentation. Correct stale conversation-limit
and forced-color assertions and the measured Electron layout test deadline.

Validation: 4,826 tests passed, 67 skipped; full typecheck and lint passed.
Current-source Linux x64 Execute/Ask/Execute MCP delivery passed, using 10
real text-provider requests and no image-provider requests. Image generation
itself was not exercised. Staged whitespace checks passed before commit.

Release note: 修复恢复队列时覆盖新输入、画布删页丢失清单格式及超限输入清空撤销历史的问题;图片 OCR 无正文时保留原图发送方式,远程 Continue Execute 正确保留会话 MCP 工具。
This commit is contained in:
mesalogo
2026-09-19 23:09:48 +08:00
parent 375b2159c8
commit a3b7a27045
29 changed files with 664 additions and 60 deletions
@@ -11,6 +11,8 @@ src/main/context-manager.ts
src/main/context-manager.test.ts
src/main/conversation-attachment-storage.ts
src/main/conversation-attachment-storage.test.ts
src/main/document-extracted-text.ts
src/main/document-extracted-text.test.ts
src/main/document-parsing-service.ts
src/main/document-parsing-service.test.ts
src/main/document-parsing-settings-store.ts
@@ -92,6 +94,7 @@ docs/features/document-processing/chat-attachments-technical-design.md
docs/features/document-processing/implementation.md
docs/features/document-processing/progress.md
docs/features/document-processing/changed-paths.md
docs/quality/recurring-defects.md
```
`scripts/paddleocr-vl-probe.mjs` 和导航 README 原有未提交内容保留,本轮未修改。
@@ -54,6 +54,9 @@ HTTP 请求固定返回 Markdown 图片、关闭调试可视化。高级布尔
会话资产的 `request.json` 保存已转换的请求内容,用于恢复内存 context;原件字节单独保存,
缩放和 JPEG 请求副本不覆盖原图。提取图片文件使用 UUID 无扩展名,MIME 在清单记录。
图片显式 OCR 后生成解析文件。切回原图保留已有结果,并重新进入图片能力校验。
HTTP OCR、显式图片提取及结果完整程度共用 `hasExtractedDocumentText`;图片引用与生成的
缺图警告只作预览/诊断,不算正文。无正文的显式提取失败并保留原草稿;有有效插图的文档
结果仍可保存为仅图片,不因缺图警告改判为可发送文本。
`ConversationAttachmentStorage` 的专用 SQLite schema 1 保存描述、路径与
`draft/message/queue/parsing` 引用,不在这些描述字段内存入原图 Base64。纯图片无需解析清单。
@@ -85,7 +88,8 @@ Main 先保存资产,再保存草稿或接受队列;消息、分支建立独
队列保存接受时的附件和发送方式。入队、分发、实际执行分别检查图片能力。
分发失败保留队列及可恢复错误,队列预览只读;“恢复到草稿”先合并并保存附件引用,
再移除队列项,文字用空行追加,超限保持原队列。恢复后的文字由 Renderer 草稿管理。
再移除队列项,文字用空行追加,超限保持原队列。Renderer 请求恢复时不传入旧草稿文本,
收到队列正文后通过原会话的函数式状态更新追加到最新草稿,保留等待期间的编辑和清空。
文件附件的启动恢复不再把提前保存的用户消息误认为 Runtime 已接受并删除队列。
## 界面与边界
@@ -26,7 +26,8 @@ L-I3(FR-I2、FR-I3;US-I3、US-I11):附件身份、原始名称与来源
单独记录为图片或提取文字。只有 OCR 返回非空可靠文字且结果保存成功,才切到提取文字;
显示名派生为“原文件名 · 提取文字”。提取文字模式只拼入文本,不同时传原图或把解析中
提取的其他图片自动附加。失败、取消、空文字保持原方式;用户可显式切回图片并重新校验
能力。重试采用当前已保存 OCR 设置,开始时说明来源;旧结果在新结果成功前保持可用。
能力。图片引用及解析器生成的缺图警告不算提取文字,即使同时保存了其他有效图片也不例外。
重试采用当前已保存 OCR 设置,开始时说明来源;旧结果在新结果成功前保持可用。
## 选图与发送
@@ -153,6 +154,8 @@ L-H7(FR-H10、FR-H11;US-H11、US-H13):知识库文档独立持有正文
取消正在生成的回复保留已发送输入。会话删除和项目删除均使用同一引用清理规则。
目标已有草稿时,将恢复文字以空行追加、附件按来源去重合并,提交前校验合并后的数量与
容量;超限则保留队列及原草稿,提示先发送或整理草稿,不覆盖已有输入。
恢复等待期间允许继续编辑;文字追加到恢复完成时该会话的最新草稿,不覆盖期间的输入,
也不复活已清空的旧文字。切换会话不会改变原恢复目标。
L-H9(FR-I5、FR-H9、FR-H10;US-I8、US-I9):从聊天或知识库选出的图片在添加成功时
已是会话独立副本,其来源名称、定位和源 ID 随附件保存。来源删除或重解析不删除副本,
+29 -1
View File
@@ -2,7 +2,7 @@
## 状态
当前状态以 [2026-09-19 实现与验证](#2026-09-19-实现与验证)、[附件操作布局复验](#2026-09-19-附件操作布局复验)及[全局浮层复验](#2026-09-19-全局浮层复验)为准。
当前状态以 [2026-09-19 实现与验证](#2026-09-19-实现与验证)、[附件操作布局复验](#2026-09-19-附件操作布局复验)、[全局浮层复验](#2026-09-19-全局浮层复验)及[空正文与草稿恢复修正](#2026-09-19-空正文与草稿恢复修正)为准。
以下至“菜单核对检查”的内容是实施前历史记录,保留原日期与原调用数。
2026-09-18:完成规划文档和独立 HTTP 探索脚本。FR-H1 至 FR-H12 均未完成生产实现,
@@ -330,3 +330,31 @@ Worker 整体回收),是具体实现对比,保留原文。本次新增内
最终 `npm test`:403 个文件通过、9 个跳过,4,793 项通过、67 项跳过,耗时 909.69 秒。
`npm run typecheck`、`npm run lint` 及隔离目录的 Electron Vite 生产构建通过;
相关文档的 48 个相对文件链接有效,`git diff --check` 通过。
## 2026-09-19 空正文与草稿恢复修正
对应 L-I3、L-H7、L-H8。修复前已复现:无识别文字、有效插图与缺图警告并存时,
警告被当作正文,显式提取后请求没有原图;队列恢复等待期间输入的文字也会被旧草稿覆盖。
实现和判定归属见[生产实现说明](./implementation.md),未增加持久状态或修改数据 schema。
- 解析、结果完整程度和 HTTP Provider 共用提取正文判定。8 个解析/存储/共享 UI 测试文件
203 项通过,其中 loopback HTTP 回归覆盖缺图警告、正文存在与否及保存后的 `images-only`。
- 生产 `App` 的 6 项回归通过,覆盖空草稿、已有草稿、恢复期间编辑、清空、失败及切换会话。
IPC 响应由测试控制完成时机,不能称为完整桌面到 Main 的新增端到端验收。
- 当前源码在隔离 Electron 中通过真实 `nativeImage`、HTTP 客户端、附件 SQLite/文件存储、
`reparseDraft` 与 `enrichRequest` 复验:仅图片及图片加缺图警告均拒绝文字切换,
草稿仍引用原附件,发往 Runtime 的请求保留一张图片;真实正文控制组仍切为文字发送。
三次请求均发往本机合成 OCR 服务,外部 OCR/文本/图像 Provider 请求为 0。
- 本轮 OCR 判断和草稿合并仍位于 Desktop,共用同一 Main 请求构造与 Renderer 草稿机制;
没有远端 OCR 分支、Agent 协议或模型桥变更,不据此扩大远端视觉模型验收结论。
验证用的临时 fixture、Electron profile 和数据库已清理。首次 OCR 探针因临时目录的模块
解析失败,调整启动器的依赖路径后通过;新会话切换测试最初遗漏全局队列读取,修正
fixture 后通过。上述均为验证工具问题,不修改产品行为来满足错误 fixture。
合并画布与 Continue 修正后的 `npm test` 完整结束:405 个文件通过、9 个跳过,
4,826 项通过、67 项跳过,耗时 982.48 秒,无失败。最终 `npm run typecheck`、
`npm run lint` 及助手数据库 101 项单独复验均通过。会话列表测试更新为无 100 条截断的
既定行为,共享高对比度测试检查全部 forced-colors 块;没有为旧断言恢复产品限制。
隐藏 Electron 窗口的双帧等待实测令布局场景耗时约 63 秒,因此只把测试子进程期限从
60 秒改为 90 秒,并对自有临时目录增加有界删除重试;完整布局断言未减少。