Repository navigation
fix(chat): resume proven unstarted quota failures through the original queue - #8002
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.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Reviewer: model_agent; GPT-6.1 Sol; OpenAI; self_reported (host execution observation unavailable).
动机 / Motivation
反重力额度耗尽后,已启用 Codex 备用池的管家用户会遇到原消息一直未获答复。原先原 worker 跳过反重力的结构化额度失败;现在仅在两次原生读回证明本次调用只有原输入与额度错误、没有输出和工具时,才沿原消息保留一次 Codex 续办。 这会积累未兑现的请求,并诱使用户重复发送。原 worker 的集成验收已得到一次正常 Core 执行及原消息回传,并证明重启对账不会重复派发;真实已安装服务的采用和原消息独立读回在合并升级后验收。已经执行过工具、来源变化或效果未知的旧失败继续待核实,本 PR 不宣称所有积压已补齐。不新增消息消费者、业务代办入口、授权、账号策略或无界重试,也不重放效果未知的失败。
改动思路 / Approach
保留现有 Core 准入、持久队列和原消息投递,只在提供者边界读取无效果证据,再由同一个 typed 决策 owner 判断备用容量和原来源约束;这比增加独立补办器更小,也能复用已有幂等与回传。本 PR 仅交付“最新且可证明尚未执行的反重力额度失败”沿原队列续办的完整路径。 这里的“无效果”需要核对同一次原生调用的完整范围,不是从失败提示或已读状态推断。原生读取在来源锁外进行,准入前重新核对来源、停止状态与配置,执行前再次检查容量。
| 情况 | 主干此前行为 | 本次行为 |
|---|---|---|
| 原调用只有输入和结构化额度错误,备用池已启用 | 原请求继续积压 | 原 worker 保留一次 Codex 续办,完成后原消息回传 |
| 有工具、输出、后续输入、停止或证据缺失 | 不自动重放 | 继续保留,不自动重放 |
| 已有相同续办记录 | 采用原身份 | 仍采用原身份,不生成第二次执行 |
这是根据源码制作的比较表,测试证据另见下文,不能把表当执行回执。
具体改动 / Changes
关键代码讲解
AntigravityAdapter.quota_failure_observation:两轮只读 GetTrajectory/GetSteps 必须一致;核对原输入 hash、时间、索引、model 和执行锚点,并要求稳定 idle。输入后的范围只能是一个结构化额度错误,不能出现回答、工具或后续输入;该函数不调用 Start、Send 或 Cancel。planNativeQuotaRecovery:继续由既有 typed owner 决定资格;当前来源、停止、绑定、命令、最新输入和一次性关联全部先核对,再复用nativeRecoveryCapacity。Codex 可用并不代表用户启用了备用池;原生容量和配置都必须新鲜。ChatExternalConversations.recover_failed_request:原 worker 自动发现失败请求,在锁内重读完整来源 journal,保留失败 Turn,按原 quota-1 身份预约,再沿既有 Core 和 App/Lark 投递。runtime/store 只允许绑定到这条未启动续办的切换;即便 Session 已由元数据修复切到 Codex,也创建普通执行的新原生上下文,不能继续受限 formatter 上下文。
规范依据是改动前的 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,完整 revision be2a5c3537b98053b2e6ee7f4440c83268ca84f5,而非本次新增说明自证。无编号原条款在此分别标为 original-source-fence、failed-turn-retention、no-unknown-effect-replay、single-queue-idempotence、original-reply-readback:当前实现与验证逐项覆盖原来源约束、失败保留、无未知效果重放、单队列幂等、原回复路径。EN/ZH 新段落披露支持范围,未改写授权。
12 文件 +444/-17,其中测试 +261/-1,生产代码与 metric +161/-16,文档 +22。共享原容量规则,没有添加通用重试框架。两个既有 module line ceiling 分别增加 3/2 行,用于显式 recovery 参数和必要 guard,默认预算未变;原失败保留,最终 premerge 已重新验证。
对主干的风险 / Risks
主要风险是把“额度错误”误当“没有执行”,造成重复业务效果,或复用元数据 formatter 上下文而无法正常执行。HTTP 原生边界、实际原 worker/Core/store/provider 集成、typed 负例分别覆盖两次读回不一致、工具、来源改变、后续输入、stop、容量不足、重复发现与 warm Codex 上下文。底层模型和消息提供者在这些测试中使用 fixture;没有把它们当生产付费调用或已安装服务完成证明。
精确 head 924c2bbc9ccff969afbe92d14139569dfd27aac8:522 Python、54 typed,标准 premerge 6 direct +14 selected 全部通过。不可变 base be2a5c3537b98053b2e6ee7f4440c83268ca84f5 上用实际旧 worker 运行同一个正例,预期失败于没有 context_recovery;head 原完整路径通过,避免只有新 helper 自证。另有通过真实 typed 入口的关闭/固定配置和新请求范围反例。当前 wait_for_ci=false,未查询、等待或推断远端 CI。回滚只切回发布版本,原失败和已准入身份继续保留,不能清掉历史以制造完成。
我的整体评价 / Verdict
APPROVE,属于可独立验收和回滚的 justified increment。保留现有 Core 准入、持久队列和原消息投递,只在提供者边界读取无效果证据,再由同一个 typed 决策 owner 判断备用容量和原来源约束;这比增加独立补办器更小,也能复用已有幂等与回传。本 PR 仅交付“最新且可证明尚未执行的反重力额度失败”沿原队列续办的完整路径。已检查原 App/Lark 消息投递路径;本次不改渲染、排版或交互控件,visual review 不适用。尚未把合并后的安装服务与真实原消息回复算作本次源代码测试的结果。 本地验证证明代码路径能产生正常原消息回复;用户真实消息是否收到了答案,仍须合并升级后由原 worker 自行执行,再独立读回,不能由本次 review 宣称积压已清空。Root 不代办原 Bot 业务。
English verdict: APPROVE. The exact head provides a bounded, source-fenced, no-effect native quota continuation through the existing worker and original reply path. Installed adoption and live backlog reply acceptance remain explicit delivery work; unknown-effect requests stay pending.
Quota failures from Antigravity could stay pending after a usable Codex fallback became available, because only completed-answer metadata entered the existing recovery route. This change lets the original worker reserve one continuation when two stable native readbacks prove that the latest invocation contains only the exact original input and a structured quota error, with no model output or tools.
The same source, authorization, stop, queue and native-provenance fences still own admission. Fresh capacity comes from the existing endpoint/account pool; runtime adoption rechecks it, preserves the original failed Turn, and opens a fresh native context for ordinary execution. The original App/Lark reply path returns the result. Requests with effects, later input, missing anchors, stale capacity or unknown terminal state stay pending.
Validation at
924c2bbc9ccff969afbe92d14139569dfd27aac8: 522 Python native/transport/store/model-adoption tests, 54 typed conversation/scope tests, and standard premerge (6 direct + 14 selected checks) pass. A real original-worker/provider journey on immutable basebe2a5c3537b98053b2e6ee7f4440c83268ca84f5leaves the request unrecovered; the same journey passes on the head. Coverage includes no-effect HTTP readback, stop/source/input/capacity/tool negatives, unchanged failed records, duplicate-dispatch prevention and a fresh native context when Codex already owns the Session. EN/ZH protocol text describes the boundary.The capacity rule is shared with existing metadata recovery. Two existing module line ceilings grow by three and two lines for the explicit recovery flag and guards; default budgets are unchanged. No new service, queue, permissions or automatic account policy is introduced. Installed adoption and real original-message readback are verified after merge.