Skip to content

fix(chat): preserve long-running turns and accepted queued queries - #7790

Merged
loopx-agent merged 1 commit into
mainfrom
codex/chat-timeout-recovery-20261101
Nov 1, 2026
Merged

loopx-agent merged 1 commit into
mainfrom
codex/chat-timeout-recovery-20261101

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

持续正常活动的交互任务会被默认硬截止中断;后续已接收消息也可能在前序工作结束前被默认一小时 TTL 丢弃。此前 CLI 还把 --hard-timeout-seconds 0 压成 0.1 秒,无法表达取消总时长截止。

普通 Codex/ACP Chat 默认取消总时长截止,并让 0 经共享启动参数 owner 传成 None。保留启动期限、无活动检测、显式正数期限和停止操作。ACP 等待循环支持无绝对期限,同时保留独立 idle deadline。排队输入默认没有隐式 TTL,显式 TTL、20 条容量、原消息幂等身份、来源和停止校验继续使用原 owner。macOS 服务配置接受并保留硬截止 0;旧显式设置保持原值,必须经正常服务管理器改变后才生效。

Author Declaration

Written by: model_agent — Codex, OpenAI GPT-6 family.
Implemented against: existing native Chat adapter, ingress and service-option contracts at base 0e78a19. Author implementation finished.

Capability/placement: existing builtin native-chat transport and service configuration; no new capability, shared state vocabulary or Python orchestration owner. Reuse the existing deadline loop, queue and shared startup option composition. The bounded managed-host segment retains its 900-second fallback. Existing operation-host callers explicitly pass their own deadline, including existing None; experiment/task/lease budgets are unchanged.

Validation

Tested revision: 289912d3fb90ee7199ad49dee7aaae106e0e00d1. Synthetic/local transport fixtures; no model or benchmark execution.

  • 146 tests passed: long activity beyond the former 30-minute cap, explicit hard and idle timeouts, ACP progress, accepted queue identity after a simulated two-day wait, explicit queue expiry, Stop/races, startup, CLI option validation, native Goal and executor profile.
  • 492 native Chat/activity tests passed, including existing subprocess transport, source-bound progress and privacy/redaction cases. The first run inherited a machine-specific provider override and failed fixture identity checks; the isolated provider-neutral run passed. No production provider or authentication was changed.
  • Real LaunchAgent-script smoke passed using synthetic HOME/manager/provider fixtures: zero hard cutoff survives install/restart while idle, source route and stored state remain intact. Initial attempts inherited workspace/registry overrides; the final run clears those overrides only for the synthetic test subprocess. No real service was restarted.
  • Ruff, whitespace, public boundary, staged bilingual RFC gate and semantic advisory passed. Full standard premerge selected 19 checks, zero blocking failures, gate passed; unchanged maintainability debt remains an inherited advisory. Merge authority is not granted by validation.

Scope And Continuation

Default behavior change is intentional for interactive Chat. Continuous work still consumes host model/tool allowance. Existing installed positive deadlines remain effective until their configuration changes. Historical timed-out Turns and their effects stay immutable; this patch does not blindly replay operations, reset receipts, add a scheduler or widen authority. Installed activation and an effect-aware continuation of original failed requests require their normal source/recipient owners.

No visible layout changed; the existing frontend/Lark progress and Stop journey remains. The bilingual user guide explains finite/disabled limits, preserved protections, service adoption and recovery boundaries. This source PR does not claim an installed long-running model result or measured solver gain.

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.1-sol | OpenAI | runtime_reported | reasoning_effort=max

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

APPROVE:未发现阻塞问题。审查完整 head 289912d3fb90ee7199ad49dee7aaae106e0e00d1;结论覆盖源码切片,实际服务采用与原业务办结继续单独验收。

动机 / Motivation

普通 Chat 用户在一个持续产生活动的任务之后继续发消息时,会遇到执行被截断、后续输入尚未开始就丢失的问题。

旧版默认任务最长 15 分钟,已配置的正数期限也会中断仍有活动的工作,队列默认一小时过期;新版普通交互任务默认无总时长截止,已接受输入保持原身份等待执行,显式期限和 Stop 继续有效。

已验证源码能跨越原截止继续完成,并在两天后从原文件队列认领同一输入;这是源码行为资格,不代表现有安装已改变。

本 PR 不自动重放历史失败,不更换 Session、账号或权限,也不取消 Goal、租约、实验预算及有界 managed-host segment 的期限。

现有安装中的显式正数设置仍需经原服务管理器变更;历史失败的效果核对、剩余工作与原受众回传由原请求和接收者继续负责。

改动思路 / Approach

截止与排队策略留在原生 Chat 的既有 owner,复用既有可空期限、文件队列和共享启动解析,没有新增调度器、恢复日志或第二消费者。

本次可独立交付的边界是普通交互任务和已接收输入的寿命规则;安装采用与效果核对后的业务恢复分别验收。

与保持现状相比,单纯把执行上限再调大只能推迟中断,也无法解决后续输入一小时过期;另造恢复队列则会多出效果核对和幂等责任。这里直接修正原 owner 的默认值和转换规则。Codex 原循环已经独立判断 idle(多久没有收到活动);ACP 的等待改为同时取绝对截止和 idle 截止的较早者。明确指定的限时与停止操作都继续生效。

下表解释源码行为变化,绑定当前 head;它不是现场执行回执。

输入或状态 原行为 本次行为
普通交互默认值 总时长 900 秒 无默认总时长截止,仍有启动与 idle 检测
显式 hard 0 转为 0.1 秒 转为 None,只取消总时长截止
正数 hard / 显式队列 TTL 到期中止 仍按原期限中止
默认排队输入 一小时未开始则过期 原身份保留至执行或停止,容量仍为 20
已安装的正数设置 保留 继续保留,普通升级不会擅自清除

具体改动 / Changes

完整差异为 14 个文件、+171/-24:生产代码 8 文件 +31/-22;测试和合成服务脚本 3 文件 +101/-2;文档 3 文件 +39。没有新增后台服务、业务重放器、持久字段或第二套恢复决策。

关键代码讲解

  1. chat_server_options 是 Chat/dashboard 和正常宿主使用的共享转换入口。它先拒绝负数、NaN、Infinity,再把 0 转成 None;1800 等正数原值传递。错误发生在服务或模型启动之前。独立测试同时检查默认、零值和正数,避免只验证 parser 接受参数却没确认实际下游含义。
  2. ACPStdioAdapter._request 只让绝对 deadline 可无限,仍使用 min(deadline, idle_deadline) 轮询真实消息;收到活动才续 idle。start_turn 分类错误前检查 hard 是否存在,因此无活动仍返回 idle_timeout,而显式 hard 到期仍返回 hard_timeout。我通过公开 start_turn 路径测试,额外覆盖了只测私有等待函数可能漏掉的错误分类。
  3. ChatIngressStore.create_queued_turn 复用原 Session 锁、client id 内容匹配和文件写入。默认把既有 expires_at 写成 null;显式 TTL 仍写日期。原 claim_next_queued_turn 已支持 null,所以不需要改历史记录或迁移器。两天后重开文件存储仍认领同一 Turn;相同 id 不同正文拒绝,21 条输入触发原容量拒绝。

规范依据是 PR 修改之前已接受的 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,spec_revision 0e78a19c277f4ca3d44313787162bc0444065172(固定版本)。本次涉及的原验收行映射如下:Acceptance 对应原身份与单次受理;Dispatch 对应排队/重启/准备失败;Correction/stop 对应精确停止;Managed 对应独立启动、idle 与期限;Authority 对应撤权拒绝及另一受众继续。上述各行在本切片均 implemented,分别由下列同输入对比、准备/停止与来源回归支撑;不据此宣称整张矩阵或安装态已经完成。修改中的 roadmap 只记录该范围,没有被用来反向定义验收标准。

对主干的风险 / Risks

最重要的反例是取消总时长截止时,连无活动检查或独立操作预算也被取消。已检查 Codex/ACP 两条路径及 unchanged operation-host 调用:前两者保留独立 idle;有界 managed-host segment 在 None 时仍回落 900 秒,operation host 继续传自己的显式期限。排队也继续经过原来源/grant 校验和精确 Stop,默认寿命变长没有赋予新权限。旧有限 expires_at 保持原到期结果,失败记录没有被重开。

验证均在当前完整 head 执行,使用合成协议与真实文件存储,未发起模型或基准任务:

  • PASS:六个相关 pytest 文件 101 项;另选原受众隔离、撤权与 Stop 路径 5 项通过。
  • PASS:独立相同 fixture(SHA256 a9132316d6590fb1e9b546b0b4ef7e61321ae28efa085eaf87bccfd175a25827)在 base 4 FAIL / 3 PASS,在 head 7 PASS。旧版失败逐项是 CLI 默认/零值、默认 native send、默认 ACP start_turn、两天后的原队列认领;显式期限、idle 和容量负例保留。两边 1131 个已加载 LoopX 模块均核对来自各自不可变源码根。时间被模拟,原决策循环实际执行,文件队列真实重开;这不是运行两天的现场模型试验。
  • PASS:实际 macos-dashboard-launchagent.sh 的完整合成 HOME/manager/provider fixture,经仓库标准 uv run --extra test python examples/macos-dashboard-launchagent-status-smoke.py 路径通过,零截止经 install/restart 保留,idle 与存储身份保留。最初系统 Python 调用在原有首个 install 步失败,内层 stderr 未捕获,原因仍未归类;原记录保留,未修改断言或产品代码来使后续通过,也不将它宣称为已修复故障。
  • PASS:标准 canary premerge --from-git-diff --git-diff-base 0e78a19c277f4ca3d44313787162bc0444065172 的 19 项选择检查无阻塞失败,另有直接差异、编译、双语 RFC、Ruff 和公开边界检查。维护性检查的既有 host_process_transport.run_host_process advisory 仍 FAIL:正确保留 tracked-set 的独立 base/head 全报告完全相同,规范化 SHA256 均为 56c0da43debe595a03434f988d0b87c5ebfd9e57b2784fe8110463666f34f82c,该文件、检查源码及阈值未变;不把 advisory 写成通过。

语义与 CI 对齐

复用已有可空截止和队列字段,明确披露默认变化,没有新 actor 协议或扩大恢复、授权、配额义务。当前策略 wait_for_ci=false,本次没有查询、轮询或等待远端 CI。本地资格与 merge-readiness 分开;CQR 当前 Goal policy disabled,未伪造 receipt。可通过显式正数恢复有限执行期限;任何安装回退仍由正常服务管理器保留原 Session、来源和历史。

我的整体评价 / Verdict

这是 justified_increment:源码对持续工作和后续输入的保留已带来可独立验证的改进,long_horizon 与 user_experience 均为 improved。用户正常发一次消息即可等待原结果,不因默认年龄限制再增加一次提交;现有 Stop 和失败读回继续可用。生产机制规模合理,兼容层仅保留已有正数配置和历史有限期限,没有需要同步的第二份状态,也没有 default-off 隔离主张。

截止与排队策略留在原生 Chat 的既有 owner,复用既有可空期限、文件队列和共享启动解析,没有新增调度器、恢复日志或第二消费者。 本次可独立交付的边界是普通交互任务和已接收输入的寿命规则;安装采用与效果核对后的业务恢复分别验收。

视觉检查不适用:完整差异没有改变渲染呈现,复用了现有 Chat/Lark 进展与停止界面。仍未验证的范围是安装态长任务、实际模型采用和后续业务结果理解。取消总时长截止仍可能增加宿主额度消耗,idle 与 Stop 不是业务成功证明。已有服务正数配置、历史效果核对和原受众最终回传需要独立完成;这些限制不掩盖为本 PR 的“自动重放已完成”。未发现阻塞问题,保留以上残余风险。

English verdict: APPROVE this source slice at 289912d. Existing explicit limits and source/Stop boundaries remain; installed adoption and effect-aware recovery are separate acceptance.

@loopx-agent
loopx-agent merged commit 403e749 into main Nov 1, 2026
13 of 33 checks passed
@loopx-agent
loopx-agent deleted the codex/chat-timeout-recovery-20261101 branch November 1, 2026 06:27
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.

1 participant