Repository navigation
fix(chat): amortize historical recovery discovery reads - #7989
Conversation
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: actor_kind=model_agent; model=gpt-6.1-sol; provider=OpenAI; reasoning_effort=max; declaration_source=runtime_reported
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
精确审查 #7989@9ac5fad30829541d7956c80788acbb54b4b5093a,对照 immutable merge-base 1dc98eb8739777a65102e18553658dc70e0f0044,核验 target main 44337e3cb5cbe3e1621550e1fe741853ba5b5a45。同一 Session 的多个失败投递逐条重复读取 queue/history/control 与 runtime code identity。
受影响调用方:Lark private delivery recovery scanner over multiple failed requests in one Session.
同一轮两个失败请求保持候选结果不变,queue/control/runtime identity 从各2次降为各1次;准备失败的 user history 同样2→1,下一轮重新读取。
非目标:不改变恢复准入、不持久化快照、不安装或证明真实模型效果、生产 p95 或长期效用。
剩余缺口:真实模型、生产负载与安装态长程效用尚未验证;全量 premerge 的既有 registry smoke 失败仍保留,合并就绪另判。
改动思路 / Approach
保留现有 TypeScript 决策 owner;Python helper 仅在既有 provider/transport IO 边界复用事实,不创建第二套恢复策略或共享状态协议。
本 PR 只交付发现阶段按轮次复用读取;发现提示不能授权恢复。
复用了现有 caller、typed owner 和错误/重试边界;没有新增持久状态、scope/config owner 或迁移。局部重构已包含于同一边界;跨进程缓存、实时状态修复和独立 UI 都不属于本次交付。
具体改动 / Changes
_RecoveryDiscoveryReads; context_recovery_observer; pending_delivery_paths。
没有独立书面 discovery IO 验收规范;先读 immutable base 的既有 correlation/admission owner 和 TypeScript 准备恢复优先级,未编造 roadmap 验收。
独立验证:当前 exact head 三模块391通过;当前 immutable base 两模块383通过。 独立真实 ChatSessionStore/Core/Lark 扫描探针 base/head 各2通过。普通上下文失败保留两个候选,准备失败因后续等价用户输入只保留最新候选;每轮各类读取2→1,第二轮累计4→2。malformed JSON/null 与非用户无效时间不改变结果,源记录、provider capture 不变,新增 provider 调用0。
负例:新增8项模块覆盖单轮/跨轮/跨 Session、临时 IO 错误不缓存为空、queued input、revoked binding、owner unavailable 的实时拒绝与禁止把 discovery object 用作实际恢复;这些8项已包含在当前完整回归中,不相加。
对主干的风险 / Risks
本地 standard premerge FAIL:registry smoke 在 base/head 同样于第62行失败,期待24个 builtin,实际包含第25个 anti-entropy-governance;完整规范化 traceback 相同,smoke/catalog/registry/entry 源 blob 相同。它在 scanner 前即失败,因此独立归因为 unchanged pre-existing,未改写为通过。其余7项 risk smoke、直接 diff/RFC/compile 和 semantic 检查通过。
当前完整 CI Ruff 范围通过;两个 F811 抑制只标注既有 pytest fixture 参数,未删测试正文。
两边 raw maintainability ratchet 也都 FAIL,完整输出与 formatter blob 相同:render_canonical_todo_sections oversized、magnitude_regressions=0;native gate 将其列为 inherited advisory,未将单项 smoke 标成通过。没有把一次成功、作者计时或测试数量当成生产性能、安装态 adoption 或真实模型效果。
CI 未查询、轮询或等待,状态未知。未知 CI 不单独阻塞有独立证据的 approve;当前回归、必要覆盖、合并就绪与权限仍分开判断。
我的整体评价 / Verdict
当前 exact head 没有验证出的 blocking finding,交付边界完整且可回滚,结论 APPROVE。本条是 author-owned 的 COMMENTED approval conclusion;合并需另取该 head 的 readiness,且本次没有合并授权或执行。
English verdict: APPROVE — the bounded caller fix is independently validated; unchanged baseline failures and merge-readiness holds remain explicit.
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
9ac5fad to
ea1154b
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · GPT-5 · OpenAI · self_reported
Approval conclusion
动机 / Motivation
Lark 后台扫描与维护恢复的 Agent。
同一 Session 的多个历史失败请求,每次发现检查都会重新读取相同 queue、用户历史和 source-control 记录;历史越长,单次 pending_delivery_paths() 越慢,并可能拖住后续队列发现。
本 head 在一次扫描内惰性复用这些只读事实,下一次扫描重新读取。候选结果、请求/Turn/binding 的逐项读取、实际恢复的实时准入和副作用保持不变。
不新增持久缓存、重试协议、恢复权限或配置;不宣称已安装 App、真实 provider、生产 p95 或长期收益已达标。
改动思路 / Approach
入口仍是 LarkPrivateConversations.pending_delivery_paths();权威事实仍是 File ChatSessionStore 中的 Session、Turn、消息和 private source journal。新的 _RecoveryDiscoveryReads 只是一次扫描内的局部读取器:按 Session 缓存 queued_turns 与 user messages,并缓存一次 source controls。context_recovery_observer() 把同一个局部读取器交给该轮每个请求,下一轮重新创建。本 PR 的边界是修正 discovery IO 复用并覆盖真实权限负例,不增加持久缓存或第二套恢复决策。
发现与准入继续分离。_context_recovery_plan(discovery_only=True) 可使用该读取器;非 discovery 调用若收到它直接报错。实际 recover_failed_request() 仍逐条回读 binding、原请求/Turn、当前 queue、source authority 和 native observation,因此 cache 不能成为恢复许可。pending_delivery_paths() 复用既有 effect-runtime request scope,让一轮扫描固定同一 runtime code identity;没有新增通用 cache 或 decision owner。该判断应保留局部读取器这一最小边界。
具体改动 / Changes
相对 34cc6883fb7c9ca374e652dc900d5caf4fc924e2,本 PR 修改 4 个文件(+218/-7):两个现有发现/读取 owner、一个新增的 discovery regression 模块,以及一个当前 main 的 builtin registry smoke 清单修正。没有新增公共协议、持久字段或 CLI。
本 PR 没有独立书面 discovery IO 规范;不可变 base 中的 external_conversations.py 已定义 discovery/admission 分离,private_conversations.py 已定义 private delivery 队列。实现和测试按这两个既有 owner 的真实边界验收。
关键代码讲解
external_conversations.py:41的_RecoveryDiscoveryReads只保存一次扫描内的 queue/history/control hints;读取失败不会写入缓存,下一轮是全新实例。external_conversations.py:80的_context_recovery_plan接受可选的 scan-local reads,但拒绝在discovery_only=False时使用它,从代码边界上阻止 discovery hint 成为恢复授权。external_conversations.py:207的context_recovery_observer为一次扫描创建读取器,并把同一个 observer 传给后续请求;实际 request、Turn 和 binding 仍逐个读取。external_conversations.py:212的context_recovery_candidate继续返回“可能是候选”的布尔提示,不执行正常恢复或写入 provider。private_conversations.py:1294的pending_delivery_paths在同一 request scope 内使用该 observer;下一轮扫描重新建 observer,并保留既有 60 秒 probe 间隔。
对主干的风险 / Risks
最强风险是把发现阶段的缓存误解为保证候选可恢复。当前实现把风险限制在提示层:同一扫描中若 queue 新变化,真实 recover_failed_request 仍读当前状态并拒绝;binding 撤销或 owner authority 丢失也在恢复前重新检查。新测试分别覆盖 queued input、revoked binding、owner unavailable,且都断言 capture、Turn 和原始 state bytes 未改变。
另一个风险是失败读取被缓存成“无输入”。_RecoveryDiscoveryReads 只有在读取成功返回后才赋值缓存;测试让 queued_turns 第一次抛错、第二次成功,证明 reader 会重试而不是保留空结果。跨 Session 测试也确认 key 按 session_id 隔离,不会复用另一会话的输入。
当前验证结果:
pytest tests/test_context_recovery_discovery.py -q: 8 PASS。pytest tests/test_context_recovery_discovery.py tests/test_native_steward_private.py tests/test_lark_private_conversations.py -q: 405 PASS。- 当前 base 的同命令 registry smoke 因 main 新增
anti-entropy-governance而失败;本 head 将其加入 builtin inventory 后 smoke:PASS,对应 registry tests 22 PASS。 ruff、Python compile、diff check、semantic-vocabulary smoke、bilingual RFC check:PASS。- 标准 premerge:6 direct、2 catalog(一个继承 maintainability advisory)、8 extension-runtime smokes、1 public-boundary scan,PASS;manual holds 0。
没有查询、轮询或等待 GitHub CI,因为 managed packet 的 wait_for_ci=false。未运行已安装 App、原生 WebView、手机或真实 provider;这些仍是独立的采用/端到端证据缺口,不能用合成 fixture 替代。
语义与 CI 对齐
复用既有 context_recovery_candidate、recover_failed_request、pending_delivery_paths 和 effect-runtime request scope,没有新增共享词汇。本轮改动只改变读取次数,不改变候选判定、准入、发送、存储或权限;registry smoke 的改动只是补齐当前 main 的 builtin inventory。
我的整体评价 / Verdict
APPROVE。 当前精确 head 没有发现阻塞项。长期任务维度改善:历史失败较多时,同一个扫描不再重复读取 Session 级事实,队列发现成本不再随失败请求数线性叠加同一份历史 IO。用户体验维度改善:后台恢复扫描更快,且错误、撤销和权限丢失仍产生安全拒绝;没有新增人工确认或配置。
视觉评审不适用:变更只涉及 Python 后台发现、内存局部读取器和测试清单;没有渲染界面或首屏变化。代码体量以真实回归覆盖为主,生产逻辑集中在两个现有 owner;没有需要在本 PR 新增的第二套缓存/恢复框架。先前的约 5.8× 墙钟数据属于旧候选的合成测量;当前 exact head 只声明读取次数和回归覆盖,仍需独立安装态观测才能声称生产延迟收益。
English verdict: APPROVE — head ea1154b7729da1eeec934cddd849705388d64e20 reuses Session-level discovery reads only within one scanner pass, preserves recovery authority and current main registry behavior, and passes 405 related tests, semantic checks and standard premerge. No blocking finding remains.
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
ea1154b to
410d292
Compare
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
410d292 to
8ed84e7
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · GPT-5 · OpenAI · self_reported
Approval conclusion
动机 / Motivation
Lark 后台扫描与维护恢复的 Agent。
同一 Session 的多个历史失败请求,每次发现检查都会重新读取相同 queue、用户历史和 source-control 记录;历史越长,单次 pending_delivery_paths() 越慢,并可能拖住后续队列发现。
本 head 在一次扫描内惰性复用这些只读事实,下一次扫描重新读取。候选结果、请求/Turn/binding 的逐项读取、实际恢复的实时准入和副作用保持不变。
不新增持久缓存、重试协议、恢复权限或配置;不宣称已安装 App、真实 provider、生产 p95 或长期收益已达标。
改动思路 / Approach
入口仍是 LarkPrivateConversations.pending_delivery_paths();权威事实仍是 File ChatSessionStore 中的 Session、Turn、消息和 private source journal。新的 _RecoveryDiscoveryReads 只是一次扫描内的局部读取器:按 Session 缓存 queued_turns 与 user messages,并缓存一次 source controls。context_recovery_observer() 把同一个局部读取器交给该轮每个请求,下一轮重新创建。本 PR 的边界是修正 discovery IO 复用并覆盖真实权限负例,不增加持久缓存或第二套恢复决策。
发现与准入继续分离。_context_recovery_plan(discovery_only=True) 可使用该读取器;非 discovery 调用若收到它直接报错。实际 recover_failed_request() 仍逐条回读 binding、原请求/Turn、当前 queue、source authority 和 native observation,因此 cache 不能成为恢复许可。pending_delivery_paths() 复用既有 effect-runtime request scope,让一轮扫描固定同一 runtime code identity;没有新增通用 cache 或 decision owner。该判断应保留局部读取器这一最小边界。
具体改动 / Changes
相对当前 base 0c4f6075c6a8f3edcea08b9a21d705dc4e01f8d0,本 PR 修改 4 个文件(+218/-7):两个现有发现/读取 owner、一个新增的 discovery regression 模块,以及一个当前 main 的 builtin registry smoke 清单修正。没有新增公共协议、持久字段或 CLI。
本 PR 没有独立书面 discovery IO 规范;当前 base 中的 external_conversations.py 已定义 discovery/admission 分离,private_conversations.py 已定义 private delivery 队列。实现和测试按这两个既有 owner 的真实边界验收。rebase 保留了新 main 的 metadata_capacity、executor configuration、native-session 与 metadata-review ownership,只把原来的 Session history 读取替换为 scan-local reader。
关键代码讲解
external_conversations.py:41的_RecoveryDiscoveryReads只保存一次扫描内的 queue/history/control hints;读取失败不会写入缓存,下一轮是全新实例。external_conversations.py:80的_context_recovery_plan接受可选的 scan-local reads,但拒绝在discovery_only=False时使用它,从代码边界上阻止 discovery hint 成为恢复授权。external_conversations.py:207的context_recovery_observer为一次扫描创建读取器,并把同一个 observer 传给后续请求;实际 request、Turn 和 binding 仍逐个读取。external_conversations.py:212的context_recovery_candidate继续返回“可能是候选”的布尔提示,不执行正常恢复或写入 provider。private_conversations.py:1294的pending_delivery_paths在同一 request scope 内使用该 observer;下一轮扫描重新建 observer,并保留既有 60 秒 probe 间隔。
对主干的风险 / Risks
最强风险是把发现阶段的缓存误解为保证候选可恢复。当前实现把风险限制在提示层:同一扫描中若 queue 新变化,真实 recover_failed_request 仍读当前状态并拒绝;binding 撤销或 owner authority 丢失也在恢复前重新检查。新测试分别覆盖 queued input、revoked binding、owner unavailable,且都断言 capture、Turn 和原始 state bytes 未改变。
另一个风险是失败读取被缓存成“无输入”。_RecoveryDiscoveryReads 只有在读取成功返回后才赋值缓存;测试让 queued_turns 第一次抛错、第二次成功,证明 reader 会重试而不是保留空结果。跨 Session 测试也确认 key 按 session_id 隔离,不会复用另一会话的输入。
当前验证结果:
pytest tests/test_context_recovery_discovery.py -q: 8 PASS。pytest tests/test_context_recovery_discovery.py tests/test_native_steward_private.py tests/test_lark_private_conversations.py -q: 在前一 rebasef818165f5f上 412 PASS。随后 main 前进到0c4f6075c6的 diff 只涉及 benchmark 文件,与本 PR 路径无交集;最终 head 另行重跑了下面 8 项 discovery、registry 与 premerge。- 当前 base 的同命令 registry smoke 因 main 新增
anti-entropy-governance而失败;本 head 将其加入 builtin inventory 后 smoke:PASS,对应 registry tests 22 PASS。 ruff、Python compile、diff check、semantic-vocabulary smoke、bilingual RFC check:PASS。- 最终 head 标准 premerge:6 direct、2 catalog、8 extension-runtime smokes、1 public-boundary scan,PASS;zero failures、manual holds 0。
没有查询、轮询或等待 GitHub CI,因为 managed packet 的 wait_for_ci=false。未运行已安装 App、原生 WebView、手机或真实 provider;这些仍是独立的采用/端到端证据缺口,不能用合成 fixture 替代。
语义与 CI 对齐
复用既有 context_recovery_candidate、recover_failed_request、pending_delivery_paths 和 effect-runtime request scope,没有新增共享词汇。本轮改动只改变读取次数,不改变候选判定、准入、发送、存储或权限;registry smoke 的改动只是补齐当前 main 的 builtin inventory。
我的整体评价 / Verdict
APPROVE。 当前精确 head 没有发现阻塞项。长期任务维度改善:历史失败较多时,同一个扫描不再重复读取 Session 级事实,队列发现成本不再随失败请求数线性叠加同一份历史 IO。用户体验维度改善:后台恢复扫描更快,且错误、撤销和权限丢失仍产生安全拒绝;没有新增人工确认或配置。
视觉评审不适用:变更只涉及 Python 后台发现、内存局部读取器和测试清单;没有渲染界面或首屏变化。代码体量以真实回归覆盖为主,生产逻辑集中在两个现有 owner;没有需要在本 PR 新增的第二套缓存/恢复框架。先前的约 5.8× 墙钟数据属于旧候选的合成测量;当前 exact head 只声明读取次数和回归覆盖,仍需独立安装态观测才能声称生产延迟收益。
English verdict: APPROVE at 8ed84e740bed68d9148435125c054bb9ddf6c28a. The rebased head reuses Session-level discovery reads only within one scanner pass, preserves current-main recovery and registry semantics, and passes 8 exact-head discovery tests, 22 registry tests, the registry smoke, static checks and all 11 local premerge checks. No blocking finding remains.
Goal And Delivered Outcome
Lark 的后台投递扫描会检查历史请求能否恢复。同一 Session 的多个历史失败,每次检查都重新解析整个 Turn 目录、读取会话历史和扫描来源控制记录。历史增长后,这些重复 IO 会拖慢队列发现。
本 PR 在一次
pending_delivery_paths()扫描内创建一个惰性本地读取器,复用同一 Session 的队列、用户历史及来源控制记录;下一次扫描重新读取。请求、Turn 和 binding 仍逐项读取,实际恢复仍执行原有的完整、实时准入检查。可观察结果是一次扫描中的 Session 级只读事实从“每个候选各读一次”降为该扫描每类一次;候选与副作用不变。该结论不冒充生产 App、真实 WebView、手机或长期延迟收益。
Current repair · 2026-11-04
Head:
8ed84e740bed68d9148435125c054bb9ddf6c28a. Base:main0c4f6075c6a8f3edcea08b9a21d705dc4e01f8d0.main.external_conversations._context_recovery_planconflict by preserving bothmain's metadata-capacity/executor-configuration path and this PR's
discovery_reads._original_native_sessionand metadata-review/executor ownership;the scan-local reader changes only the three repeated Session-level reads.
anti-entropy-governance; the second commitupdates that exact builtin inventory and the registry tests/smoke pass.
Changes
_RecoveryDiscoveryReadslazily caches one scanner pass's queued-turn state, user messages,and source controls. Failed reads are not cached as empty results.
context_recovery_observer()supplies one local reader to every request in the scan;pending_delivery_paths()creates a fresh reader for the next scan and pins oneeffect-runtime request scope.
_context_recovery_plan(..., discovery_reads=...)is explicitly discovery-only. Normalrecovery/admission rejects a discovery reader, re-reads current authority and remains the
owner of submission and provider effects.
queued input, revoked binding, lost owner authority, forbidden discovery authorization,
and the real scanner's one-pass/per-request authority behavior.
Validation
pytest tests/test_context_recovery_discovery.py tests/test_native_steward_private.py tests/test_lark_private_conversations.py -q --tb=short: 412 passed on the rebase againstf818165f5f. The later base advance to0c4f6075c6changed only benchmark files, none intersecting this PR's paths; the exact final head then reran the 8 discovery tests, registry tests/smoke and premerge below.pytest tests/test_context_recovery_discovery.py -q --tb=shorton final head: 8 passed.pytest tests/capabilities/test_capability_extension_registry.py -q: 22 passed.python examples/capability-extension-registry-smoke.py: passed.git diff --check: passed.Remaining gaps
No installed App, native WebView, mobile or live provider acceptance was run. The PR establishes
read-count amortization and regression parity, not installed-state latency or long-term benefit.
No persistent cache, retry protocol, scoring, permission or storage-format change is introduced.