Repository navigation
fix(chat): preserve answers with invalid legacy handoff metadata - #7915
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 · GPT-6 · OpenAI · self_reported
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
用户在原生聊天正常结束后收到“未生成完整答复”的错误提示。 修复前用户只能收到失败提示;修复后保留原可见正文,说明元数据未提交,所有未验证操作和委派仍被拒绝。 同一原生 Turn 只执行一次,HTTP 原会话能读回正文和 response_metadata_invalid 门禁。 本 PR 不重放业务、不代写委托、不放宽授权,也不把历史消息实际送达列为代码测试已完成。 生产历史失败请求的自动采用与原受众回传仍需安装后独立验收。
改动思路 / Approach
原生宿主的正文与可执行元数据有不同的责任。正文可见性属于已有解析边界;动作有效性仍由同一个规范化与类型校验 owner 决定。 当前实现已经对显式空 message 保留正文;本次只把同一错误分支补足到旧版输出省略、null 或空白 message 的情况。正向路径是完整信封解码、类型校验拒绝、取第一个控制标签之前的正文、重新规范化为正文和原门禁。负向路径仍拒绝没有正文的无效信封,也不把之前隐藏信封中的内容当成回答。只修复已有坏元数据降级路径对省略、null、空白 message 的正文丢失,不增加新状态或重试路径。 不增加供应商重试、恢复队列或另一个解析 owner。
具体改动 / Changes
规范依据:已读现有 App conversation RFC 在 8d314af4955c86ea389b0916eda5f1a51f30b966 的原会话、正文与授权约束;畸形旧版信封组合没有独立书面规范(no_spec),以原生回包形状和真实边界回归作为判定依据,不用 PR 自述代替规范。范围为 3 个文件,75 行新增、2 行删除,其中 70 行是测试,生产修改限于已有解析分支。
关键代码讲解
parse_agent_response 先读取最后一个完整信封,只有规范化抛出 ValueError 才走已有安全降级。新分支优先保留信封内可用 message;缺失时读取隐藏标签之前的原正文,且只保留第一个标签之前的部分。没有正文继续抛错,避免伪造答复。
normalize_agent_response 继续独立调用类型化委托校验和正文脱敏。降级时构造全新的正文加 gate 对象,不复用坏信封中的提案、委托或受保护动作。HTTP 用例通过真实服务、队列、协议进程与磁盘 Core 读回验证 completed 状态、原回答和门禁,并要求只有一次原生 turn/start。
对主干的风险 / Risks
最强反例是保正文的同时泄漏隐藏控制数据,或让无效委托间接执行。新增测试覆盖早先隐藏信封、无正文拒绝、受保护路径脱敏及全部动作字段清空;现有有效格式与显式空 message 语义保持。调用方包括 Codex 最终输出与 Antigravity 最终输出、原结果只读观察器,使用同一默认解析路径。PASS:同一 HTTP fixture 基线失败,修复后通过;178 项相关用例、语法检查、双语 RFC 与 premerge 通过。初次 premerge 因未显式选择两个本机 runtime 根而拒绝,明确指定原路由后通过;没有把入口错误删除或说成代码回归。按本 Goal 的 wait_for_ci=false 未查询、轮询或等待 CI。
语义与 CI 对齐
复用既有 response_metadata_invalid 与类型校验语义;提示内容没有新增义务。动作门禁仍是强制边界,正文保留没有执行授权。回滚仅需撤销此代码提交,历史失败 Turn 与投递回执保留。
我的整体评价 / Verdict
此修改是 justified_increment:long_horizon 与 user_experience 均 improved,减少已完成工作被格式错误隐藏并诱发重复执行的风险。178 项相关测试通过;同一 HTTP/协议 fixture 在基线失败、修复后完成并且 turn/start 次数为一。 修改使用现有 owner、没有新增持久化状态,机制成本与已复现损失相称。界面未改变布局或展示层,无需新的视觉验收;生产历史失败请求的自动采用与原受众回传仍需安装后独立验收。 该限制不等于已自动补办业务,后续采用仍沿原服务保护进行。
English verdict: APPROVE — preserve the original answer while rejecting invalid action metadata.
已完成的原生回答可能带有旧版委托元数据:如果委托 brief 不是对象,同时省略 message 字段,原解析器会把整轮标为失败并丢弃可见正文。本改动保留协议标签之前的原答复,明确提示元数据未通过校验,继续阻止全部未验证操作与委派;没有正文时仍然失败关闭。
验证:178 项相关测试通过。真实 HTTP → 原生会话队列 → 协议进程 → 读回测试在基线复现失败,修复后保留正文和元数据门禁,且只启动一次原生 Turn;另覆盖省略、null、空白 message、正文脱敏及早先隐藏信封隔离。受管 premerge 和双语 RFC 检查通过。安装后原服务是否完成历史答复回传仍需独立验收。