Repository navigation
fix(chat): recover original steward replies after a Codex service restart - #8196
Conversation
…inal queue 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 · Codex GPT-6 · OpenAI · self_reported(host 身份观测 unavailable,未虚构精确构建)
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
服务重启前已经收到部分输出、但仍没拿到答案的 Codex 管家用户。旧路径只给项目助手做结果复核,管家即使原生记录已稳定也一直停在失败提示;新路径可由原队列自动核对现有结果并补回复。在已配置的灵活额度路由可用时,无须重新输入问题或确认,原受众能得到现有证据支持的答复。这次只恢复结果回复,不重放效果未知的业务、不追加委派,也不关闭尚未完成的原业务。真实安装采用与积压消息实际回传仍待独立验收;已有最终答案的其他失败类别、缺失原生证据及不符合原额度路由的情况没有被冒称覆盖。
改动思路 / Approach
复用 typed Core 的 planResultReview 和既有单次 review-1 队列;provider 只解释并冻结原生 DTO,原授权管家读取及受限 sandbox 继续由已有 owner 提供。本 PR 覆盖配置灵活额度路由的 Codex 管家重启中断且无最终答案的结果复核,保留原项目助手路径和全部未知效果保护。最强反对理由是这次复核可能只给部分答案,并额外使用一次模型额度;但只修提示不能解决欠答,直接重做又可能重复此前副作用。这里选择一次受限结果复核,仍先验证原生记录和当前额度,不增加用户确认,也不引入第二消费者、手工状态或重试预算。
具体改动 / Changes
审查依据为 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,spec_revision 8eb707d47a4d5529e316bcc30e042840cca3ad80;先读既有 Managed/result、原来源和重启去重条款,再判断本次新增小节。本文用 managed-restart-result、original-source-queue、unknown-effect-and-history 标识这些未编号要求:均 implemented,由原回复路径、稳定原生读取、原队列以及 sandbox 验证覆盖;不是用新增规范反向定义正确性。
关键代码讲解
conversation_binding.ts:1227的planResultReview复用原项目结果复核,扩展到当前 Codex 管家;额外要求原 client/message/origin、原生摘要和已配置额度。planContextRecovery先识别重启复核,再判断额度耗尽家族,避免已经入队的重启复核被错误家族截住。只有一个 review-1,失败后不能变业务重试。codex_adapter.py:380的interrupted_result_readback将真实 dynamicToolCall 纳入终态效果清单;未知、活动条目或最终答案仍拒绝。摘要只绑定精确原 Turn 与完整 items,独立复查全库存稳定性,同时允许不相关的后续已完成输入增长,不因此丢掉原答案。external_conversations.py:357的recover_failed_request对 Codex 答案使用 Codex 读取与现有额度 owner,不误调 Antigravity。:775的_checked_answer_review在执行前重新读回同一摘要;原来源、停止及 grant 检查继续有效。已有新受限 thread 只允许原管家读取,禁用网络、apps、patch 及业务动作;原失败不改写。manager_failure_reply只修正未来的重启提示,说明可核验后由原队列恢复结果回复,仍保留未知效果等待;不会把旧失败通知改成伪造成功。
9文件 +261/-14,产品代码 +39/-12,其余为既有测试和两份 RFC。PASS:716项较广历史/会话回归;最后原摘要及断言调整由23项关键路径重验覆盖。58项 TS 通过;相同最终文件在基准有2个 Python 正例及1个 TS 正例失败,未知/活动负例保持拒绝,head 全部通过;其余57项 TS 基准/head 都通过。真实原生中断记录也通过只读 provider 资格核验,没有启动模型或业务。
对主干的风险 / Risks
未发现阻塞问题。最大风险是把“原工具已执行”误判成可再次执行业务,本实现只允许读取原结果后答复;没有重新打开旧业务 Turn。正反例覆盖停止、来源变化、原生记录缺失/变化、额度不足、错误身份、复核冒出业务动作和入队后回执丢失;实际核对原 sender、会话及正文、原产物和失败字节不变、一条新受限 thread、无 thread/resume,以及网络/apps/patch 禁用和只保留 manager read。缺额度在预约前保持等待,不以一次准备失败耗尽复核机会。
这是已有灵活 Argon/Codex 路由内的恢复,不保证每一种失败或所有配置都可恢复。纯 Codex 其他路由、缺原生证据以及已经有最终答案的不同恢复类别仍按原 owner 处理。回滚会停止新增重启复核,保留原失败和已入队回执,不能以回滚触发业务重放。合成 native/IM 后端验证真实 Core/worker,但不能证明真人收到或模型答复内容质量;安装态另验。
语义与 CI 对齐
复用现有 answer_review/read_only_review/review-1 和原生摘要,没有新 actor、枚举、CLI 或第二 authority。标准预合并 PASS:6项直接检查、11项选择检查;Ruff、编译、双语差分、语义注册和9文件公开扫描通过。初次测试暴露的家族顺序及容量 fixture 问题已保留并修正,未放宽生产门禁或预算。按 Goal 配置不查询或等待 CI。提示由笼统不重放改为条件恢复,仍不宣称业务成功,符合本次明确的用户方向。
我的整体评价 / Verdict
这是 justified_increment:原先被漏掉的管家重启欠答可以沿原来源转成有预算的自动结果回复,长程接续和用户体验改善,零额外输入或确认。检查现有 Lark/Chat 消息路径,只有失败提示正文变化,没有布局、页面或新控件;以原受众消息正文和 sender 的集成读回验证,视觉截图不适用。真实安装后原欠答的送达单独验收,合成provider不冒充真人收到。机制按 typed Core、原生 provider 和受限效果 owner 分工,体量与实际漏答相称;兼容保留已有项目复核与持久失败/预留,不另造 replay 服务。当前 head f6766dde828b0d27312a302a2ad361b1ab6eca5b 无已有评论或未解决发现;用户已明确授权相关修复自评审自合并,临合并仍需准确 head 的 readiness。
English verdict: APPROVE — head f6766dd; no blocking finding, source-bound read-only recovery passes regression and local premerge. Installed message delivery remains separate acceptance.
A steward running on the configured Codex fallback could deliver a restart failure notice and then never answer the original question, even after its native tool activity had ended. Reuse the existing single
review-1original-source queue reservation for one restricted answer review, rather than replaying interrupted business work.The typed owner requires the exact original request, source/grant/stop checks, a stable interrupted native inventory with no final or live item, and fresh configured Codex capacity. The provider recognizes terminal native dynamic-tool calls and pins the original inventory digest; dispatch rechecks it. The review uses the existing read-only manager sandbox: no writes, network effects, new handoffs or business continuation. Failure history and reservation identity survive restarts and uncertain enqueue replies. Existing project reviews remain unchanged. The future failure notice and both RFC mirrors explain the qualified recovery.
Validation: 23 focused Python provider/worker cases and 58 TypeScript conversation-binding tests pass. Identical frozen final tests fail on the base (two Python positives and one TypeScript owner case), while the unknown/live negative remains held; head passes all four selected checks. The real native interrupted inventory also qualifies through the read-only provider without any model or business dispatch. Broader history/conversation regression passed 716 cases; the final edited critical paths were separately revalidated in the 23-case run. Standard premerge passes six direct and eleven selected checks; Ruff, compilation, semantic registry, bilingual diff and public boundary scan are clean.
Presentation: the existing Chat/Lark reply journey is reused, with a corrected failure notice. No page layout, control, settings or extra message consumer is added. Synthetic tests verify original-source sender/body, unchanged failure history, one restricted thread, disabled network/apps/patch tools, stop/source/native-change holds and crash adoption. Actual installation and original message readback remain acceptance work; this does not promise replay of unknown effects or support for every terminal category.