Repository navigation
fix(chat): avoid reparsing idle history during recovery - #8175
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; runtime_reported; model=gpt-6.1-sol; provider=OpenAI; reasoning_effort=max
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
长期使用个人助手或管家的用户:原 Bot 检查积压消息时,历史记录越多,当前消息的处理与回传越容易被后台扫描拖慢。
一次检查 36 条旧请求,原路径反复解析历史正文约需 15–16 秒;新路径只在文件变化后重读元数据,同一历史与完整恢复计划保持一致,三组成对观测约需 2.1–2.3 秒。
新增和改写的队列输入、stop/new 与后续来源仍进入原规则;终态未变化正文不再被每轮重新解析。
不改变队列、额度、重放、消息消费者或授权政策;不代原 Bot 执行业务,不把已送达进展当成业务完成。
安装后原服务的持续响应、上游模型可用性,以及每条历史欠办的执行和原受众最终回传,仍须分别验收。
改动思路 / Approach
重复读取属于 File provider IO;元数据不能持有业务准入或回传权。保留现有 typed owner,只共享变化标识和最小观测,可独立检验并无持久迁移。
本 PR 交付原 File 队列和来源扫描的默认 IO 提速;安装稳定性和全部欠办回传仍由既有任务验收。
已有 _RecoveryDiscoveryReads 只覆盖一次扫描;新 helper 复用原 reader,按文件变化失效,只保存消费者需要的字段。不能通过延长轮询掩盖重复工作,也不能缓存完整授权、正文或效果决定。Lark 保留旧回复修复投影,复用同一个变化标识;Core 没有反向依赖扩展。
| 路径 | 原来 | 本次结果 |
|---|---|---|
| 未变化的终态历史 | 每次解析完整正文 | 验证变化标识后复用身份与状态 |
| 新输入、变化文件、非终态 | 原 reader | 继续原 reader 与 typed selection |
| stop/new、当前授权与原生效果 | 原准入 owner | owner 不变;精确准入继续读当前证据 |
| Windows / 不可用变化标识 | 原 reader | 保持原来的新鲜读取 |
具体改动 / Changes
审阅目标为完整 head 9ee6362360bef36b56191f6175e90ff13770e5a9,8 个文件,+412/-20;主要新增量是 246 行针对性测试。实现没有新建数据库、CLI、用户配置或重放 owner。来源控制扫描仍枚举完整目录,现有队列排序和预留容量规则继续由原 typed owner 执行。新增双语 RFC 段落说明默认 IO 路径;它不是反过来为本实现背书的验收标准。
关键代码讲解
file_change_fingerprint返回可用的本地变化标识;Windows 的创建时间不能证明内容未变,故不复用。Lark 也使用这个同一实现。FileChatDiscovery.rows先观察标识,调用原 reader,读取后再核对。缺失、变化或不完整投影不能进入可复用状态;并发返回独立元数据,删除项清理。ChatIngressStore.queued_turns仅复用 schema、Session、Turn 身份都有效的终态记录。新入队、活动状态和精确 Turn 读取仍走原路径,严格读取错误继续暴露。ChatExternalConversations.source_controls只投影原 stop/new/later-input 需要的四字段,缺字段时不缓存;pending()与read_request()继续提供完整当前记录。
独立规格依据为 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,固定在完整 revision f87d9976baab054e5baee5b0d56538ca3812b39e:变更前规格。REC-1、REC-2、REC-3 是本次映射标签,原 RFC 没有这些编号。REC-1:保留原失败与回传 owner,已实现并用完整恢复计划对照;REC-2:stop/new、新排队输入、来源与未知效果门禁保持,已通过变化后准入和负例回归;REC-3:安装与实际原受众回传由既有维护任务验收,此次合并前明确未完成该项。
验证:最终 head 的 Chat/Lark 回归 606 项通过,Ruff 通过;同一 head 的正式 standard premerge 通过:6 项 direct checks、11 项 selected checks,0 项阻塞失败;1 项既有体积 advisory 保留。真实 File 历史做三组交替对照,36 条完整计划逐字段一致;不把计时字段当语义比较。独立队列读取 oracle 在原实现读 40 份未变化终态正文并按效率断言失败,当前 head 读 0 份并通过;队列结果两边相同。另覆盖保留 mtime 的替换、瞬时空读取、严格读取异常、并发首次读取和 Windows 创建时间反例。
对主干的风险 / Risks
最大风险是错误复用旧 stop 或队列事实,导致漏掉新输入或扩大重放。实现只保存可推导元数据,依赖完整变化标识;非终态和精确准入仍重新读取,临时读取失败不会被保存为空状态。未检测到阻塞缺陷。测试使用真实 File reader 与 Core planner,模型/provider 边界为既有 fake,不能据此保证付费模型健康、生产 p95 或所有业务已完成。Windows 边界为模拟验证,未做原生 Windows 运行。回滚无需迁移 journal,正常安装 owner 可以恢复旧版本。既有 interaction_contract._admitted_interaction_next_cli_actions 体积告警在不可变 base 上同命令复现,未改预算或缩小扫描来隐藏它。
我的整体评价 / Verdict
这是对真实重复 IO 故障的 justified increment。元数据归 File provider IO,准入与副作用归既有 typed owner,边界合适;本 PR 交付默认扫描路径的可测提速,既有安装、持续响应和未闭消息任务继续承担剩余验收。没有新增用户操作轮次,不要求用户重新提交消息。视觉验收不适用:检查过现有私聊 API 和 worker 路径,渲染页面、卡片、正文与布局均未修改。未验证范围是安装后持续时延、上游可用性及每条旧消息的真实业务和收信;不能把这些标成已解决。
English verdict: APPROVE — exact head 9ee6362; no unresolved blocking finding; local validation and full-plan parity support this bounded File IO change. Author-owned approval is recorded as COMMENTED; merge follows exact-head readiness and existing maintainer authorization.
原 Bot 在检查历史欠办时,为每条恢复候选反复解析全部 File Turn 和来源正文,长会话会持续占用处理时间。本变更在现有 File IO owner 内复用可失效的终态/来源控制元数据,保留完整来源枚举、非终态新鲜读取和原 typed 准入;Lark 回复 journal 共享同一个变化标识,Windows 保持原 reader。
验证:606 项 Chat/Lark 回归通过;Ruff、双语 RFC、编译、边界扫描和 standard premerge 通过。1 项既有 interaction_contract 体积告警在不可变 base 以同命令复现,未放宽预算。真实 File 历史的 36 条完整恢复计划逐字段一致,三组成对读取约 15–16 秒降至约 2.1–2.3 秒;独立 warmed queue oracle 在 base 读取 40 份终态正文而失败,当前 head 为 0 并通过。
该对照仅证明当前 File 扫描切片;原服务安装、持续响应、上游可用性及每条原消息实际回传另行验收。没有新增消费者、重放权限、持久 schema、用户配置或额度策略。