fix: reduce supervisor stalls and preserve task delivery

Load Supervisor graphs only when opened, preserve source details on demand, reuse indexed story digests and window selection lists without losing keyboard or focus behavior. Route heavy UI reads through the existing worker, batch scoped queries and construct each publication snapshot once.

Keep remote cancellation responsive during model-route cleanup, remove late routes and retain reported usage after response-cap cancellation. Preserve Telegram pending replies through polling conflicts, show delivery errors and honor the final rate-limit cooldown.

Schema 62 adds lookup indexes without rewriting user content; older clients cannot open upgraded data. Large review publication still blocks Main and remains documented follow-up work. Record the future storage-service direction without performing the architecture migration.

Validation: exact staged code passed isolated full tests (6212 passed, 87 skipped), typecheck and lint. Three-round source performance comparisons, SQLite migration equivalence, native Electron interaction checks and current-source Linux x64 Host validation completed; eight external text-model requests.

Release note: Supervisor opens reviews without loading the entire graph, keeps long selection lists responsive and preserves details and keyboard navigation. Remote cancellation and Telegram reply recovery are more reliable; remote fixes require an Agent build containing this change.
This commit is contained in:
mesalogo
2026-10-05 14:18:33 +08:00
parent e50ca6d149
commit b90ff50f2a
59 changed files with 2108 additions and 265 deletions
+106
View File
@@ -0,0 +1,106 @@
# KISS 局部修复与验证
## 范围
基线为 `e50ca6d1`。先更新文档,再实测实施,完成后回填证据并提交本轮改动。
目标架构见[桌面存储方向](../architecture/desktop-storage-direction.md);独立存储服务迁移留待之后讨论。
本轮复用现有 Worker、数据库、IPC 和控件,不全面异步化存储,不更换数据库驱动,不增加通用恢复框架。
工作区已有三份宣传稿修改,以及实施期间并行加入的“删除会话后继续回顾”改动,不属于本轮提交;共享文件按片段区分。
## 实施清单
| 编号 | 局部改动 | 验收要点 | 状态 |
| --- | --- | --- | --- |
| K01 | 概览不提前加载图谱,来源正文按需读取 | 首次概览无需 graph;图谱和来源内容完整,历史导航正确 | 已实现,组件及 Electron 通过 |
| K02 | 概览索引与故事/经验批量、按项目查询 | 查询结果与排序等价;升级保留原数据,实测查询及输出规模 | 已实现,schema 61→62 数据等价验证通过 |
| K03 | 故事摘要建索引并只计算一次 | 摘要分类及时间规则不变;暖切换不重复计算 | 已实现,三轮对照及回归通过 |
| K04 | 图谱选择列表虚拟化 | DOM 有界,键盘、焦点、选中、滚动和内容访问保留 | 已实现,补齐外部 Tab 入口后 Electron 通过 |
| K05 | 监督重读取接入现有只读 Worker | 生产 UI 调用确实离开 Main,读快照一致,失败不静默回退重查询 | 已实现,真实 Worker/IPC 回归通过 |
| K06 | 发布只构造一次最终快照 | 完整结果与 checkpoint 原子提交;实测剩余 Main 阻塞,不隐藏未解决预算 | 已实现一次构造;Main 发布仍超预算,待架构迁移 |
| K07 | 远程取消清理等待及迟到路由 | 不占全局控制队列,清理后迟到安装不残留,活跃 peer 正常 | 已实现,当前源码 Linux x64 Host 通过 |
| K08 | 超容量响应保留已收到模型用量 | 不保留超限正文、不重试容量错误,实际用量不丢失或重复 | 已实现,两个协议及清理期限回归通过 |
| K09 | Telegram 启动冲突、投递错误及限流 | 待发回复不因接收冲突永久终止;错误可见;跨层遵守 retry_after | 已实现,loopback/SQLite/Electron 通过 |
## 已有审查基线
前三轮合成 SQLite:20 份结果、40,000 条消息、8,000 个事件/来源时,概览同步读取
310/328/324 ms;完整图谱 379/383/387 ms,JSON 约 25.74 MB。400 个故事、800 条经验
的响应执行 1,204 条 SQL,首次 52~65 ms。100 批次、每批 20 来源的最终发布为
567/711/740 ms。该分布是压力样本,不代表用户实际库,首次调用也不等于冷 OS 缓存。
Renderer 源码 Electron 场景中,2,000 事件产生 8,207 个 DOM 元素,出现 152~314 ms 长任务;
2,000 故事各十事件的摘要首次计算 77~81 ms,缓存路由返回仍重复计算。
原始基线脚本位于批准的临时目录,后续对照必须固定数据、版本和口径。
## 验证要求
- 对功能缺陷先运行失败回归,再修复;不放宽断言、超时或性能预算。
- 性能对照至少三轮交替执行,基线用独立临时 worktree;分别记录 Main 阻塞、查询耗时、
响应大小、Renderer 长任务及点击反馈,不能把不同探针耗时相加成端到端值。
- 数据用隔离合成 SQLite 或一致性副本,不修改 portable 原始库;索引升级遵守迁移指南。
- 真实 Electron 验证首次/热切换、历史与详情、键盘、焦点、选中和滚动;不以截断内容提速。
- 远程 Runtime 改动在共享 Linux x64 Host 验证当前源码,使用专用目录及进程;记录有界真实模型调用数。
- 最后运行完整测试、类型检查和 lint;发布准备不运行本地生产打包或已打包应用探针。
## 实施与测量结果
### 监督者读取与界面
后端保留原业务合同,文件数据库的三个 UI 读取在现有 Worker 的读快照中执行,失败直接报告,不回退 Main 重查询。概览新增匹配索引;故事/经验批量查询按项目筛选;图谱保留所有事件和关联,来源只传已有 schema 所需标题与时间,完整正文仍走来源详情。
| 测量项 | 基线 | 修复后 |
| --- | --- | --- |
| 大样本概览:调用方最大循环间隔,三轮 | 389/471/873 ms | 2.45/2.10/3.17 ms |
| 大样本图谱:调用方最大循环间隔,三轮 | 583/572/646 ms | 12.04/12.29/15.79 ms |
| 故事/经验响应的 SQL 数 | 1,204 | 6 |
| 大样本图谱 JSON 大小 | 25,742,067 字节 | 7,143,667 字节 |
| 2,000 事件图谱点击至两帧反馈 | 188~346 ms | 24~39 ms |
| 同场景挂载列表行/文档元素 | 2,000/8,207 | 24/329(首轮窗口实现) |
| 2,000 故事各十事件的首次摘要 CPU | 48~80 ms | 9~16 ms |
| 缓存路由返回的摘要 CPU | 43~74 ms | 0 ms |
| 100 批次发布的同步耗时 | 686/729/730 ms | 271/286/303 ms |
| 100 批次的快照 UPDATE 数 | 101 | 1 |
数据来自固定基线 `e50ca6d1` 与修复版三轮对照,平台为 Windows x64、Core Ultra X7 358H、Electron 44.5.1。
存储测量使用真实合成 SQLite 和 Worker,界面测量使用生产 React 组件与模拟 bridge,二者没有相加成端到端时间。
发布复测包含工作树并行删除校验,不能作为本轮独立提交的精确耗时保证。迁移前后 55 张表、32,947 行含 rowid 的哈希一致,外键及完整性检查通过,未执行正文转换或回收。
独立复审后,故事读取增加 scope/刷新版本所有权校验,避免旧编辑完成时使新读取失效。
虚拟列表额外保留逻辑首末行,保证从外部 Tab/Shift+Tab 进入时仍按完整顺序访问;最终挂载量比上述首轮测量最多多两行,后续 Electron 继续检查有界性与可见焦点。共享列表的主动滚离焦点行为保持不变。
新 Electron 回归还暴露既有消息展开测试的等待缺陷:语言切换后等到了旧节点,且帧轮询回调异常会留下未结算 Promise。测试现等待替代请求的最终渲染,帧回调异常正常拒绝;原超时及断言不放宽,相同严格场景在基线与当前源码均通过。
完整后端和前端逐轮数据分别见[后端记录](../features/conversation-supervision/progress.md#2026-10-05-监督页面读取与发布局部优化)和[界面记录](../features/conversation-supervision/frontend-progress.md)。
### 运行时与交付
K07 的路由 HTTP 清理不再占用全局控制队列;迟到安装按原 Session/operation 清除,不影响活跃 peer。
当前源码通过共享 Linux x64 的 OpenCode 与 Continue:peer 查询分别 13/46 ms,取消完成分别 176/194 ms;工具、断开恢复、测试 Agent 提升及事件重放均通过。本轮准确为 **8 次外部文本 HTTP 请求、0 次图片调用**,含首次测试触及旧请求数上限前的两次请求;各运行结束时所属进程和目录残留均为零。详见[运行时记录](../features/unified-execution/progress.md#2026-10-05-k07k08-局部修复)。
K08 超容量后立即中止并清空正文,最多消费一秒用量事件,保留原错误且不重试。OpenAI/Anthropic、已缓冲完成响应和不响应取消的迭代器均有回归。
K09 已验证启动 webhook 冲突时仍可发送已验证身份匹配的待发结果;发送错误可见且不覆盖接收错误;最后一次 429 的等待可取消并跨越驱动/发件箱边界。
Telegram 验证只使用 loopback HTTP、合成 SQLite 和真实 Electron 设置入口,没有向真实收件人发消息。详见[通道记录](../features/telegram-channel/progress.md)。
### 最终检查
将本轮 59 个路径的暂存内容应用到 `e50ca6d1` 的隔离工作树,排除并行删除功能和宣传稿后执行完整验收。验证时暂存树为 `31e6199b91cb703ddffa3806807326143064a7f1`;随后只补充文档中的验收结果,没有再改代码。暂存代码、测试与独立工作树逐文件核对一致。
| 命令 | 最终结果 |
| --- | --- |
| `npm test` | 523 文件通过、15 跳过;6,212 用例通过、0 失败、87 跳过,832.51 秒 |
| `npm run typecheck` | Main、Agent、Renderer 全部通过,7.36 秒 |
| `npm run lint` | 通过,24.24 秒 |
| `git diff --cached --check` | 通过 |
完整测试使用本机缓存的 Runtime 二进制及配置,包含原生 OpenCode、监督者布局、消息展开和 Telegram Electron 场景;未开启外部模型验收开关。首次隔离测试因缺少 Runtime 缓存多跳过 13 项,不作为最终结果;补齐已有缓存后完整重跑得到上表计数。并行实施期间的其他失败轮次保留在各组记录中,不与最终结果混算。
日志、JSON 测试结果、跳过清单、暂存快照及文件哈希位于批准临时目录 `opencode/kiss-staged-validation-Bmc3dm`,以 `final-verification.json`、`snapshot.json` 和 `test.log` 为索引。验证前后原工作区 77 个已变更文件逐字节未变;未暂存的并行修改完整保留。本轮没有生产打包、推送或发布。
## 剩余限制
- 大批量发布仍在 Main,约 271~303 ms,未达到 16 ms 预算;保留原事务及持久化语义,后续讨论迁移。
- 故事完整响应仍约 3.32 MB,曾有一次 19.74 ms 的调用方间隔;图谱正文统计在 Worker 仍需数百毫秒。
- 未预载的源码模块首次进入仍约 0.31~0.34 秒;一轮小图谱首开出现 55 ms 长任务,没有宣称所有预算达标。
- 未覆盖完整生产窗口 IPC 的端到端性能、低端机节流、macOS/ARM64、签名包安装或真实 Telegram 平台收发。
- schema 62 按既有规则禁止旧客户端打开;独立存储服务、全仓异步化和发布版本号调整均不属于本轮。
@@ -1,5 +1,7 @@
# 桌面端性能改造(第一期,参照 VS Code 架构)结项报告
2026-10-05 校正:本文保留第一期测量截面,开头结论只适用于当时已测场景。生产监督者首次进入和最终发布未被这些场景覆盖,后续实测发现阻塞并开展[局部修复](./kiss-local-fixes-2026-10-05.md)。`perf:check` 的历史回归上限也不等于性能原则的全部预算。
- **时间:** 2026-10-02 至 2026-10-04
- **范围:** Desktop 的 Electron Main、Preload、Renderer 及其后台线程。远程主机(Agent、SSH、远程 Runtime)的稳定性和性能不在本期范围,下一期单独审查。
- **结论:** 本期计划内的工作已完成。用户日常能感受到的卡顿(打字、流式输出、切换会话、滚动、启动、写库)都已测量并修复。剩下的工作是架构上的长期项(存储接口异步化、独立数据进程),风险高,已经写明理由,留到后续单独立项。
@@ -72,7 +74,7 @@ Main 卡顿的数据来自真实数据,以及 5 万个文本块的知识库。
| Markdown 解析放到后台线程 | 需要重写渲染流程。标准机上流式输出已经不卡,只有低端机上的长回答还有余量 |
| 窗口提前加载,接口请求排队等待 | 可省 200–300 ms,但要改动所有接口的注册顺序和首次运行流程 |
| 会话队列移出 App | 和发送、恢���、中断联系太紧,拆出来的风险大于收益 |
| 性能阈值接入 CI | 仓库目前没有 CI 配置 |
| 性能阈值接入 CI | 当期未将性能基准接入已有 CI;原文“仓库没有 CI 配置”有误 |
## 4. 已知问题和下一步