返回 DeepSeek-Reasonix
INBOX_QUEUE_IMPLEMENTATION.zh-CN.md
根目录 / docs / INBOX_QUEUE_IMPLEMENTATION.zh-CN.md
1 # 消息队列:行内编辑与排序的实现和验证
2
3 日期:2026-09-21。变更在本地工作区;未发布安装包。
4
5 ## 用户可见行为
6
7 - 正在运行时,普通发送及发送快捷键默认加入下一轮队列;“引导当前轮”是独立操作。结构化指令和图片仍通过独立轮次执行。
8 - 队列与输入区连在一起,默认显示两条;点击编辑时在原消息行打开完整多行正文,不自动展开其他条目。编辑中的行只展示正文、附件/引用与“取消 / 保存”。
9 - 编辑时隐藏主输入区、上下文附件和固定文件栏,保持挂载以保留主草稿及附件。保存或取消后恢复输入区与焦点。停止当前任务的入口在编辑时移到队列上方,退出编辑后恢复原有主输入区按钮。
10 - 保存原位更新消息,保留 ID、顺序、附件、引用和幂等身份。`Ctrl/⌘ + Enter` 保存,`Esc` 仅退出编辑,不停止当前任务。取消时未改动的正文直接清理;已改动或冲突的正文保留临时草稿供恢复。
11 - 手柄支持鼠标拖拽,也支持空格拾取、方向键移动、空格放下。更多菜单提供上移、下移、移到队首、移到队尾及删除。
12 - “暂停队列”收纳在标题的更多菜单中;暂停后显示状态及“继续队列”入口。只暂停后续派发,当前任务继续运行。暂停期间仍可编辑、排序和删除;保存不会自动恢复执行。
13 - 已接纳的引导显示接收状态,不提供编辑或排序。blocked/uncertain 条目明确标示原因,并提供显式重试。
14 - 发生内容冲突、消息已执行、会话变化或保存回包丢失时,保留修改;可读取最新版本,或把修改追加回主输入框。读取最新版本前,旧修改也会保留在草稿列表。
15 - 停止当前任务不再删除待处理消息,也不会把截断的预览文本恢复到输入框。
16
17 ## 从 ZCode 移植的部分
18
19 来源为 `zai-org/ZCode` 的 `872ad960de7ec172591f7e1952f7849229f94521`,
20 `packages/ui/src/v4/ConversationQueuePanel.tsx`:
21
22 - `@dnd-kit/core`、`sortable`、`utilities` 的排序结构;
23 - 独立拖拽手柄、纵向边界约束、保持缩放为 1 的行变换;
24 - 紧凑列表、折叠/展开、基于 ID 和目标锚点的移动;
25 - 最初版本采用在主输入区处理队列编辑的交互;用户随后选定 A 方案,已改为原消息行内编辑、编辑期间隐藏主输入区。
26
27 `desktop/frontend/licenses/ZCode.txt` 保留 Apache-2.0 许可与改动声明。
28 样式使用 Reasonix 已有字体、色彩、按钮、Popover 和主题变量。
29 编辑采用原位保存;不会采用 ZCode 原实现的“删除条目、回填输入框、重发入队”。
30
31 ## 数据与并发规则
32
33 | 层 | 实现 |
34 | --- | --- |
35 | Store | `ContentVersion` 绑定不可变正文 blob 与 checksum;保存做正文版本比较,移动做 Inbox revision 比较;移动只改 pending 槽位 |
36 | 派发 | `TransitionPrepared` 在同一磁盘事务中检查状态、正文版本、暂停状态和当前队首;过时候选重新选取 |
37 | Controller | `InboxQueue` 固定原 Store;read 返回完整正文;保留原 envelope,引用变化时重新冻结;旧 update/append/refresh 路径也使用版本检查 |
38 | Desktop | `InboxQueueForTarget` 校验 tab、sessionPath、generation、selection;本地操作持有既有 admission fence |
39 | Remote | `inbox-mutations-v1` 能力协商,`POST /inbox/queue` 与 expected-session header;不支持时展示升级提示,不回退到本地 |
40 | Frontend | 编辑草稿与主输入草稿分别保存,scope 包含会话及主机身份;快照按 revision 单调应用;拖拽与菜单统一使用 before-item 锚点 |
41
42 `POST /inbox/queue` 请求为 `{sessionPath, request}`。操作包括 snapshot、read、edit、move、delete、pause、retry、steer、enqueue_steer。
43 移动到队尾时客户端明确传 `beforeItemId: null`。结果包含 outcome、reason、权威 snapshot,以及可选 edit/receipt。
44
45 保存超时后只查询一次 snapshot,不自动再次保存或创建新消息。编辑草稿保存在独立的内存与 sessionStorage 中,支持会话切换、组件重新挂载和同一页面刷新;不承诺退出应用后保留未保存草稿。已保存正文、队列顺序和暂停状态由 Store 持久化。
46
47 ## 验证证据
48
49 ### 行内编辑 Bug 复查(2026-09-21)
50
51 - 修复离开并返回同一会话后,旧保存回包清掉新编辑草稿的问题。每次挂载拥有独立操作身份,异步完成时同时核对操作身份与草稿对象;失效回包不再更新快照、草稿或忙碌状态。
52 - 修复切走会话后,延迟完成的目标捕获仍发出队列操作的问题。捕获目标、提交请求及处理回包前后均检查当前操作是否有效;失效保存失败也不会继续发送状态核对请求。
53 - 修复会话 selection 变化后“读取最新版本”仍复用旧目标、无法恢复的问题。显式读取最新版本重新捕获当前目标,并保留原修改到恢复列表;普通保存仍校验原目标和正文版本。
54 - 修复焦点位于编辑区按钮时 `Esc` 无效的问题。键盘处理覆盖整个编辑区,同时保留输入法组合保护,避免冒泡触发停止任务。
55
56 新增确定性生命周期测试覆盖延迟保存成功、目标捕获、完整正文读取、保存失败,以及 selection 变化后的恢复。三个相关 React 测试文件、测试类型检查和生产构建通过。浏览器预览验证保存按钮聚焦时 Esc 能退出、恢复主草稿及焦点,当前任务继续运行,控制台无警告或错误。本轮仅修改前端,未重跑 Go 或安装包测试。
57
58 ### 此前行内编辑验证
59
60 本次行内编辑改造额外验证:
61
62 - 原行挂载、单一编辑器、只显示取消与保存、不自动展开队列;主附件 DOM 身份和主草稿在保存及取消后保持不变。
63 - `Esc` 不触发停止;无修改取消不会生成恢复提示;已修改的取消可以继续编辑。
64 - 保存冲突仍保留行内正文;消息离开队列时转为明确的恢复区,停止任务也不会丢弃这些文字。
65 - 浏览器在 1280×720、900×700 验证保存、取消、焦点恢复、临时草稿恢复、键盘排序、指针拖拽和标题菜单暂停。以下 Go 验证为前一阶段后端实现的已有结果,本轮只改前端,没有重跑 Go 套件。
66
67 - Store 确定性双 writer 测试:保存先完成则旧正文派发失败,排序先完成则旧队首派发失败,过时的引用失败不能把新状态改为 blocked;已开始执行的条目不可编辑。
68 - Controller 实际调度测试:暂停 → 编辑第二条 → 移到队首 → 恢复;runner 先收到第二条的新正文,再收到原第一条。
69 - 保存长正文及空白、完整 envelope 保留、正文冲突、丢失锚点、重启后顺序及暂停状态保留。
70 - Desktop + httptest Serve:远程完整读取和保存、旧服务能力拒绝、selection 变化和远端 foreground 变化拒绝。
71 - React 回归:主草稿保留、默认入队与显式引导分开、保存不重发、停止不撤回队列、冲突草稿恢复、丢失回包只查询一次、不同 scope 的草稿隔离;同路径切换远程主机后,允许新主机较低的队列 revision,不保留旧主机条目。
72 - 浏览器使用生产组件和开发预览数据验证编辑、保存、暂停、菜单置顶、键盘排序和拖拽;1440×1024 与 900×700 编辑态可用。预览不连接真实模型或生产会话。
73 - 前端生产构建、TypeScript、ESLint、CSS/层边界及包体预算检查;保持原预算。
74 - Go Store/Controller/Serve 包测试,以及 Desktop Inbox/host ownership 测试;针对编辑、排序和实际派发运行 race 检查。
75
76 主要验证命令:
77
78 ```sh
79 go test ./internal/sessioninbox ./internal/control ./internal/serve
80 go test -race ./internal/sessioninbox ./internal/control -run 'TestVersionedAppend|TestInboxQueue|TestPreparedQueue|TestQueuePause'
81 cd desktop
82 go test . -run 'Test.*Inbox|TestHostCommandOwnership'
83 cd frontend
84 pnpm build
85 pnpm test:typecheck
86 node --import ./scripts/css-stub-register.mjs --import tsx src/__tests__/inbox-queue-lifecycle.test.tsx
87 node --import ./scripts/css-stub-register.mjs --import tsx src/__tests__/inbox-queue-editor.test.tsx
88 node --import ./scripts/css-stub-register.mjs --import tsx src/__tests__/composer-queue-integration.test.tsx
89 ```
90
91 复现入口:`cd desktop/frontend && pnpm dev --host 127.0.0.1 --port 5191`,打开 `http://127.0.0.1:5191/?mock=guidance`。
92 浏览器预览仅用于开发,生产构建会移除该 fixture。视觉检查见 `docs/INBOX_QUEUE_DESIGN_QA.md`。
93
94 ## 明确边界
95
96 - 结构化调用的偏移量与指令实体不能安全地被纯文本编辑,因此显示明确的暂不支持提示;仍可排序和删除。
97 - 当前未在用户原报错会话或安装包中复现;无法断言截图那一次失败的唯一根因。
98 - 当前未创建 PR、推送、安装新包或部署远程服务;本地验证不代表这些步骤已完成。
99
99 lines MARKDOWN