Repository navigation
fix(chat): recover untouched requests after transport loss - #8024
Conversation
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; model=GPT-6 (Codex); provider=OpenAI; declaration_source=self_reported
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
评审对象为 5810dcc2dc84fa218ecc7afe294a53c851215e34。未发现阻塞问题,生产送达保留为安装后的独立验收。
动机 / Motivation
使用原管家或个人助手、等待断线前已收到的消息得到答复的人会遇到这个问题。连接关闭后,原请求只留下用户输入,却同时被保存为失联会话和原生中断;旧恢复入口因此永远跳过它,新入口在证明尚未执行后通过原队列接续。真实stdio、Core队列和provider回传回归证明同一会话完成一次接续,重复核验不再次派发,原失败保持不变。本次不恢复含工具、答案、思考、未知项或修正的原生中断,也不增加消息消费者、队列、授权或用户操作。全部生产积压是否已补执行并实际送达,仍需安装后逐条独立验收。
改动思路 / Approach
原生适配器只提供完整读取推导的事实,Core继续独占准入;复用现有routing退避、三次上限和确定性身份可避免新增同步状态。本PR交付断线后最新user-only请求的自动恢复,不处理效果未知的中断。连接关闭会让两个现有状态同时改变:Core记录失联,原生端记录中断。修复必须在原生事实与Core准入两端衔接。原生读取确认最新Turn已终止、没有native error、完整库存仅有原用户输入,并再次读取库存与终止状态;Core重新核验来源、绑定、停止、失败类别和预算后,沿原队列创建确定性接续。发现提示、无delta或模型可用不能代替这些事实。单独把会话改成ready仍缺少未执行证明,新增消费者也不能解决原owner的判定缺口。
具体改动 / Changes
关键代码讲解
failed_request_readback复用完整分页读取;最新无native error的interrupted只进入user-only库存核验,任何工具、答案、思考、压缩、修正、未知项和变化都拒绝。返回的interrupted_before_execution是派生事实,不能单独授权执行。实机读取得到这一严格证明,使用既有两类只读RPC,没有启动模型或恢复请求。planRoutingRecovery仅让精确stale/transport_disconnected且原Core传输失败的闲置Session进入核验。新中断证明还要求stop_observed=false和唯一原始用户项;来源/授权、原失败身份、退避、最多三次及既有入队相关性保持。原worker回归用真实stdio关闭、真实Core与provider fixture完整走过原接收、失败保留、同Session接续、送达核验和去重;停止、来源编辑、撤销、未知native项、其他失联原因均不产生额外业务Turn。对这处具体组合的有界规范检索未发现独立已接受RFC,本次没有虚构规范条目;验收依据为原请求队列、未执行证明及既有来源/停止边界。
生产新增19行、删除3行,测试新增123行。新增观察沿现有receipt保存,没有独立同步状态、服务、入口或数据迁移。
对主干的风险 / Risks
主要风险是把中断误判成未执行,随后重复工具效果。严格的完整user-only库存和当前来源核验限制了这一边界;只有原请求仍有效且无停止时才有新接续。未知项、原生答案、后续Turn、变更库存和其他失联原因保持拒绝。不可变已安装基线 478bfacec994849a1a0250b6f07c001dfc733924 上,同一最终fixture得到2项预期正例断言失败、18项负例通过;当前head恢复正例并保持这些负例。
PASS:当前head的551项native/routing回归、15项原Core/transport不变量通过;相同最终TS源码的49项typed owner回归通过。标准源码premerge包含6项direct和10项selected检查,0失败,保留既有维护性advisory;Goal的CQR策略disabled,CI按策略未查询。最初fixture缺少home和来源payload键的失败已保留并修正,实机也暴露了额外RPC兼容问题;最终使用原有完整Turn/items接口,实机严格证明与当前完整回归共同支持结论。旧PR的DCO遗漏在本地确认,新分支保留签署并在本head重新验证,原历史未改。
语义与 CI 对齐
沿用既有 stale、interrupted、传输错误与routing词汇;新增布尔字段属于内部原生观察,Core继续拥有准入和效果。没有新公共actor、状态枚举、配置或用户确认。原生产caller仍为既有私聊worker。回滚两处生产改动时保留已入队身份、原失败和待办,效果未知状态继续由原owner处理。测试的model/provider IO隔离,不能证明全部生产消息已处理。
我的整体评价 / Verdict
这是 justified_increment:交付了真实断线组合下的恢复不变量,后续生产验收明确。long_horizon=improved,消除默认worker永不发现已承诺请求的盲点并保留有限预算;user_experience=improved,沿既有意图与授权自动接续,无额外重发或确认轮次。loopx/capabilities/native_chat/codex_adapter.py和loopx/control_plane/collaboration/conversation_binding.ts只改变恢复观察及准入,没有渲染、布局、文案或展示密度改动。无视觉变更;生产原会话实际送达待安装验收。原生适配器只提供完整读取推导的事实,Core继续独占准入;复用现有routing退避、三次上限和确定性身份可避免新增同步状态。本PR交付断线后最新user-only请求的自动恢复,不处理效果未知的中断。规模与故障成本相称,不需要新增队列或消费者;全部生产积压继续保留为原Bot执行和独立读回义务。
English verdict: APPROVE. Exact head 5810dcc; native/Core recovery and source premerge checks passed, with real message delivery retained as post-install acceptance.
断线后的原请求可能一直得不到答复:Core 已将 Turn 记为
host_gate失败并将 Session 标为stale/transport_disconnected,原生端则将关闭中的 Turn 保存为interrupted。恢复发现只接受 ready Session 和 failed 原生 Turn,因而跳过了尚未执行的请求。本补丁复用原恢复 owner:对最新、稳定、终止的原生 Turn 读取完整分页,严格要求只有一条原始用户输入,并再次比对输入;Core 只在原失败属于传输故障、Session 没有活跃 Turn、来源和授权未变、没有停止或修正时,按已有退避与最多三次的确定性身份接续。原失败与失败通知保留,工具、答案、思考、未知项、后续 Turn 或状态变化均不能生成这项未执行证明。
没有增加队列、消费者、模型调用入口、权限或手工重放。原 Bot 继续负责执行与原受众回传。生产积压和实际送达仍需安装后独立验收。
验证:当前 head 的 551 项 native/routing 回归、15 项原 Core/transport 不变量通过;相同最终 TS 源码的 49 项 typed-owner 回归通过。源码 premerge 的 6 项 direct 和 10 项 selected 检查通过,0 失败,既有维护性 advisory 保留;Goal 策略不查询 CI。不可变基线同一最终 fixture 复现 2 项正例断言失败、18 项负例通过,当前修复正例并保持拒绝边界。已独立读取本机真实 native 记录,确认原只读接口能提供严格未执行证明;生产执行与原消息实际送达在安装后单独验收。