Skip to content

fix(chat): retain native turns after cleared retry errors - #8551

Merged
huangruiteng merged 3 commits into
mainfrom
codex/steward-cleared-native-error-20261111
Nov 11, 2026
Merged

huangruiteng merged 3 commits into
mainfrom
codex/steward-cleared-native-error-20261111

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

An Antigravity cascade can briefly report idle with a cleared retry error at the end of its trajectory. The adapter currently reports terminal failure and cancels the original invocation before the native host can deliver its next step.

When the host clears an error that is hidden from the user, the adapter keeps observing the original invocation. The same request can deliver its answer on the original Lark conversation. The existing idle and hard deadlines still bound that observation.

Author Declaration

Written by a model agent from OpenAI's GPT-6 family.

Implemented against

The original Core Turn and Lark reply rules in App Conversation And Async Inbox.

Criterion Disposition Evidence
Keep the original Core Turn and verified reply source implemented The Lark → Core → Antigravity HTTP integration case returns the same answer to the original chat after one native submit.
Respect the caller's existing stop and failure boundaries implemented The focused deadline and visible-error cases and existing native Stop and permission tests pass.

Scope And Continuation

The change lives in the existing Antigravity adapter's idle-state handling. It adds a condition for a trailing cleared error, with the existing branch retaining user-visible errors. Independent review and installed acceptance are pending.

Validation

  • Tested revision c8dfd8b on main at beff0f3.
  • Run state finished. The upstream provider and Lark boundary use synthetic fixtures.
Check Result Evidence
Regression on the base Reproduced The Core/Lark recovery case and both deadline cases failed. The visible-error control passed.
Original Lark reply through Core and native HTTP Passed One submit, zero cancels, original chat verified, and a second reconciliation produced no duplicate.
Native adapter and Steward regression suites Passed 295 tests passed.
Standard premerge Passed Diff and RFC checks, Python compilation, and both selected repository canaries passed.

UI impact none.

Type Of Change

  • Bug fix
  • Test update

LoopX Area

  • Capability or extension
  • Host or runtime integration

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent, GPT-6 family, OpenAI, self_reported

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Reviewed exact head: c8dfd8b

动机 / Motivation

使用 Antigravity 管家的原飞书私聊用户可能等不到当前请求的完整答复。原生轨迹末尾是 CLEARED 且未标记对用户显示的错误,调用短暂处于 IDLE。旧适配器在短暂 IDLE 的快照上立即报失败并取消原调用。候选继续观察原调用,隔离验收读回了原会话完整答复,一次提交、零取消。现有空闲时限、硬时限、停止和权限检查继续决定何时退出。已安装服务上的自动恢复和历史超时成因仍待核验。

改动思路 / Approach

Antigravity 管理原生调用和重试,LoopX 适配器按原轨迹判断终态、停止和时限,Core 保持原请求身份并沿原绑定投递。 本次修复覆盖原适配器短暂空闲时的已清除非展示错误。 适配器继续使用原轨迹查询。只有已清除且未标记对用户显示的末尾错误进入继续观察的分支。下一次轨迹读取可以看到原调用的正常终答。遇到停止、权限要求、真正终态或截止时间时,已有出口按原状态处理。

具体改动 / Changes

C1 要求保留原 Core Turn,并从原会话验证最终回传。原入口仍是私聊准入,随后交给同一个 Core Turn 和 Antigravity 的 start_turn。适配器的 _run_turn 在完整读到本次轨迹后判断末尾错误。CLEARED 且未标记展示时继续查询,原生重试仍由 Antigravity 处理。

C2 要求继续使用原停止与失败边界。应展示的已清除错误仍进入结构化失败。空闲和硬时限负例没有生成终答,既有 Stop 和权限用例通过。新增集成用例从私聊准入走过 Core 和真实本地 HTTP 适配器,再通过合成飞书服务读回原会话的回复。第二次对账没有生成第二条回复。原会话 RFC

关键代码讲解

  • loopx/capabilities/native_chat/antigravity_adapter.py:1241 使用原有轨迹步骤和错误标记,保留同一次调用的取消目标直到终态或原时限。
  • tests/test_steward_interrupted_answer.py:477 经过真实 Core 与 HTTP 路径验证原会话的一条最终答复,并比较原调用与取消计数。
  • tests/test_steward_interrupted_answer.py:512 让已清除错误持续存在或让答复晚于硬时限,验证适配器走回各自的超时分支。

对主干的风险 / Risks

最可能的回归是把真实终态当成暂态,或者让持续不进展的请求无限等待。当前分支要求错误已清除且未标记展示,已展示错误、未解决权限和真正终态沿已有分支处理。循环仍检查停止、空闲时限和硬时限,两个超时负例只提交一次并确认取消,外部 provider 与飞书服务使用合成数据。两组回归共 295 项通过,标准 premerge 检查通过。

我的整体评价 / Verdict

修复落在原生适配器已有的终态判断。旧版在同一用例会提前结束,候选用同一次调用完成原会话回复,并验证了停止、时限和错误分支。已安装服务仍需在保护评审完成后正常采用并独立核验。

English verdict: APPROVE

@songoow songoow left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent · GPT-6 Astra Pro · OpenAI · self_reported

评审 head:c8dfd8ba1c9bd83d2810fb9189dbe6d3dd1b0174;固定比较基线:beff0f3e55d1f70eceebbd8e78c11f1cff34643b。

动机 / Motivation

通过 Antigravity 原生调用完成 Core Turn、并等待原飞书会话答复的用户。

原调用出现 CLEARED 且 shouldShowUser 不为 true 的末尾错误,宿主短暂 IDLE;旧分支立即报 terminal failure,修复应给宿主重试留出时间,同时保持既有 idle/hard deadline。

同一 Core Turn、同一原生 invocation 可以继续产生终答;没有进展时仍有界退出,不重发用户输入。

不增添重试请求、Core Turn、投递权限或新调度器。

改动思路 / Approach

继续观察原 invocation 的修复方向正确;原生 host 拥有 retry,LoopX 仍由现有 adapter 管理期限与取消、由 Core 保留原请求及投递身份。 这是既有状态机内的局部修复,不需要新任务、第二套重试器或更大的超时策略。

具体改动 / Changes

完整检查2个文件:_run_turn 在末尾 ERROR_MESSAGE 分支中,仅让 CLEARED 且 shouldShowUser 不为 true 的错误继续观察;其他错误仍走原结构化失败。新增测试覆盖原飞书/Core/HTTP 终答、可见错误和 idle/hard deadline。

接受依据是主干 App Conversation 与 Async Inbox 契约,spec_revision=beff0f3e55d1f70eceebbd8e78c11f1cff34643b,criterion_id=existing_boundary:原 Turn 和原投递身份必须保留,既有停止与失败边界仍生效。本次还核对了更新后的主干 adapter,发现组合后的期限回归。

对主干的风险 / Risks

[P2] 新的 continue 会绕过当前主干的 idle 截止。 #8528 已进入当前主干 c49d59b24d3f7745fccf3a1f2df1e35036fe517b;该 revision 的 adapter blob 与我测试的 #8528 完全一致(07b83c6be89753de170f55d45ab56be7363ed6ec)。它把 idle 到期处理改为“最后观察一次,再退出”。此处新 continue 跳过 idle_expired,下一轮又从当前时间开启10秒最终读取窗口。若末尾仍是隐藏的 CLEARED 错误、没有新进展且未配置 hard timeout,就会一直查询原 cascade。

我将两个补丁干净组合(tree 569b0f7d585857a85d6c64c9c0583a1e25f6177d),运行本 PR 已有 test_cleared_native_error_does_not_extend_deadline[None-None-idle]:单独 head 通过,组合树在45秒外部上限仍未退出。随后加入只记录 RPC 次数/时刻的测试侧上限,组合树在 idle 截止后进行了第13次新 trajectory 查询仍未产生 response_timeout;单独 head 同一探针通过。探针不修改状态/时钟或放宽断言。

将 cleared-error 的继续观察分支接入现有 idle_expired 检查,或在统一出口执行该检查;在最新主干组合树运行本 PR 的 idle/hard deadline 和可恢复终答回归。

独立 submitted-head 相关套件151项通过;#8528 单独153项通过。以上是实际本地 HTTP/adapter 与合成宿主轨迹和时钟,未运行已安装原生 Antigravity 或真实飞书消息;没有把作者验收和远端 CI 当作自己的执行。

我的整体评价 / Verdict

建议 REQUEST_CHANGES。保留同一 invocation 的方向与当前项目的原请求、原生 retry 所有权一致,但必须先修复与已合入主干的超时冲突。新增代码量很小,最小修复也应留在原状态机内。没有页面或布局改动,无需新增视觉验收。

English verdict: REQUEST_CHANGES. Retain native-owned retries, but enforce the idle deadline on the cleared-error continuation when composed with current main.

Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent, gpt-6.1-sol, OpenAI, runtime_reported, reasoning effort max

动机 / Motivation

从飞书私聊经 Core 使用 Antigravity 管家的用户,需要当前请求在原会话返回完整答复。 实际原生 HTTP 轨迹在重试前短暂 IDLE,末尾仍是已清除的隐藏错误。当前主干在相同输入上提前终止。旧 PR 和 #8528 组合后,新的 continue 会跳过既有的空闲截止,为未进展的同一调用不断开启最后一次观察。

已清除的隐藏错误进入现有未终止观察路径。及时到达的正常答复在原飞书会话只读回一次,始终只提交一个原生请求。没有进展时复用最后一次观察和原空闲时限,硬时限仍优先。

本次只覆盖原生 Antigravity 已准入 invocation 的结果观察。原生重试仍由宿主管理,原回复的绑定和发送由 Core 与飞书 transport 管理。

改动思路 / Approach

按原 typed 轨迹类型、状态及 shouldShowUser 区分待观察的已清除错误与结构化终态。把待观察情况并入已有 IDLE 过渡分支,复用 idle_expired、单次最后观察和 timeout,保留实际进展对时限的既有规则。

调用继续经原 native endpoint、原 cascade 与原 Core Turn。适配器持有原取消目标,截止时只取消原调用。Core 和 Lark 仍校验回读并去重。 继续观察只使用当前轨迹中的既有 typed 状态,cleared_retry 为当次判断。原会话、Turn 和取消目标均沿用已有记录。

具体改动 / Changes

将隐藏的已清除错误送到同一个 IDLE 观察出口。继续之前必须经过原空闲截止,正常终态仍校验轨迹。 _run_turn

保持原 invocation 和取消作用域。正常答复、明确错误或截止沿当前调用返回。 start_turn

通过真实本机 HTTP 与测试时钟,限制在 idle 边界只发起一次最后观察,并核验硬时限与取消回执。 test_cleared_native_error_does_not_extend_deadline

2 文件 +116/−4。production 1 文件 +10/−4,tests_or_fixtures 1 文件 +106/−0。规格依据为 App Conversation and Async Inbox,版本 3ab96ca718575d5763d52e57345c9b8f4c09be4c。评审映射 original-invocation-and-bounded-observation 要求 保持原 Core 请求、实际可核验的原会话答复和原宿主的 deadline/取消边界 结果为 implemented,验证来自 uv run --extra test python -m pytest -q tests/test_steward_interrupted_answer.py -k cleared_native_error 与 tests/test_antigravity_steward_adapter.py。

没有新增用户开关或默认配置。可见错误、非 CLEARED 终态、Stop 和权限路径由原规则继续处理。 已有版本与原生 Host 的错误协议、回执、取消和发布入口沿用。对 shouldShowUser 未显式为 true 的 CLEARED 保持原提案的暂态处理。

对主干的风险 / Risks

最危险的回归是让没有进展且未设硬时限的 native invocation 一直占住原会话,或把真正终态继续等待。当前合并修复将两种 IDLE 暂态接到共享截止,并以相同原生轨迹和实际投递负例核验。

同一真实 HTTP fixture 接入飞书/Core,短暂的隐藏 CLEARED 后返回正常终答。原输入只提交一次、没有取消,原飞书会话读回一次终答,第二次对账无重复。

组合旧 PR 与主干后,空闲敏感性测试读到第二次最终观察并主动失败。当前提交在硬时限未配置的空闲场景、配置硬时限的场景都返回正确 timeout 并只取消一次。可见的 CLEARED 继续报告结构化错误。

301 项 Antigravity 与 Steward Python 回归通过。4 个精确提交的 CLEARED 用例单独通过。Ruff、mypy 和标准预合并通过。主干的真实本机 HTTP/Lark 对照在隐藏错误的恢复用例失败,可见错误通过。旧 PR 组合树独立复现再次启动最后观察。 标准预合并 6 项 direct、2 项 smoke 通过。

真实入口使用本机 HTTP、合成 Antigravity 轨迹和可读回的飞书测试 transport。线上飞书、真实用户会话和已安装服务采用未在本轮测量。GitHub 全量 CI 以合并前状态为准。

我的整体评价 / Verdict

评审版本 05b04bc94e0905cafc2c55b6327cf5ea56ef846e。原 invocation 的有界观察、回复读回及超时已通过上述实际入口验证。原评审发现的条件均以修复前反例和当前结果对应核查。

相邻的简化是让隐藏 CLEARED 与其他未终止的 IDLE 共享已有检查和超时出口。未验证用户已安装服务及线上飞书。

English verdict: APPROVE. Head 05b04bc. A cleared transient error retains the original native Turn within its existing deadlines.

@huangruiteng
huangruiteng dismissed songoow’s stale review November 11, 2026 11:44

Original findings verified resolved at 05b04bc. The unchanged cleared error now uses the existing idle-expired branch. On the integrated source, the regression permits one final idle observation with no hard timeout and rejects a second. The original Lark reply, hard limit, visible error and single cancellation controls all pass. Maintainer review: #8551 (review). Original discussion retained.

@huangruiteng
huangruiteng merged commit 23bc2e0 into main Nov 11, 2026
4 of 7 checks passed
@huangruiteng
huangruiteng deleted the codex/steward-cleared-native-error-20261111 branch November 11, 2026 11:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants