Skip to content

fix(chat): allow cancelling delegation reads in place - #8102

Merged
huangruiteng merged 1 commit into
mainfrom
codex/delegation-recovery-20261105-075011
Nov 5, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/delegation-recovery-20261105-075011

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

A slow delegation read currently requires closing the reader to stop waiting. The toolbar now offers Cancel read in place. Cancelling keeps the last published same-source records and open original conversation, restores refresh and keyboard focus, and fences the cancelled response. Clicking the requested filter again retries it.

This completes the local reader cancellation/retry slice. It does not cancel a delegation or certify backend latency improvements.

Author Declaration

  • Written by: model_agent — OpenAI Codex (GPT-6 family).
  • Implemented against: the existing original-delegation reader contract, plus the reproduced inability to cancel a pending read in place.
  • Intended base: main (rebased onto acc00f54513682dc5db95ed53ee9104fd59dafde).
Criterion Disposition Owning path / evidence
Stop waiting without closing the reader; retry the same filter implemented conversation-requests.tsx; first-read and filter cancellation oracle
Preserve published rows, paging extent, expanded original and source/search fences implemented 61-request real File/SQLite/HTTP journey; delayed response completes after the new page
Source failure stays unknown and recoverable; no request authority or receipt mutation implemented Real source refusal/recovery, original-body and no-write checks

Scope And Continuation

The production change stays in the TypeScript reader and reuses its AbortController, generation fence and refresh revision. The existing Python fixture only adds a bounded, releasable HTTP wait for the packaged regression. CLI/Lark and shared request semantics are unchanged. The existing CI smoke:delegation-search entry runs the new TypeScript scenario directly.

Native foreground latency/root-cause work, installed App/MacWebView qualification and historical provenance recovery remain with the existing workstream. Cancellation stops client waiting; the server can still finish the read. This boundary is independently reversible and requires no additional configuration or confirmation. No merge or installation is included.

Validation

  • Tested revision: 17b96b83dc420c4b50855102aa6a8809470a8848.
  • Run state: finished.
  • Input classes: synthetic, public_fixture, authorized_private_read_only. Original-input diagnostics remain private and do not establish a matched timing comparison.
Check kind Result Evidence / limitation
static passed Chat build, strict noEmit for the new TS smoke, fixture Ruff, explicit four-file public scan and diff/RFC hygiene
real_entrypoint / real_backend passed npm run smoke:delegation-search: packaged Chat with real File and SQLite 3.53.4 in disposable isolated runtimes; 61 mixed long requests per arm, initial/filter/search/More/multi-window cancellation, late completion, retry, source loss/recovery, English/Chinese, 390px and keyboard
regression_parity passed Same cancellation assertion fails on the baseline UI because the control is absent; candidate passes. Full 15,620-character original and existing history/search/return recovery remain readable; reader adds no POST or receipt/journal change
integration passed tests/control_plane/test_chat_request_inventory.py and test_chat_request_control.py: 58 real HTTP/File/SQLite checks after rebase
manual passed Ego inspected populated loading/cancelled/error/expanded states at 1200×888 and 390×844; Enter cancels with 12 rows and refresh focus preserved, same-filter retry works, long original fits without horizontal overflow
static failed Existing maintainability ratchet: _admitted_interaction_next_cli_actions has 62 decision points against 60. Independent clean base/head runs match complete failing identities/details, tracked workload and environment. Failure is retained as an optional inherited advisory; no threshold changed
static passed Exact-scope CQR is valid with that advisory; quick premerge passes five direct checks and three catalog checks, retaining one inherited advisory. This grants no merge authority

Coverage is the packaged browser and owning backend. Backend performance, real-model adoption, native WebView and installed behavior remain unqualified. The public synthetic regression supplements the original-input investigation; it is not a published private fixture or a benchmark result.

Frontend / Visual Evidence

  • UI impact: changed. Source data in every image: public synthetic fixtures through the real SQLite/HTTP owners.
  • Before uses 8a48e346dc3352c51a07255052d9256b38571264; after images use the same UI source blob now committed in 17b96b83dc420c4b50855102aa6a8809470a8848. Final bundle/tests ran after rebase. Independent fixture instances can have different generated times. No hosted preview; npm run smoke:delegation-cancel reproduces the packaged journey.
  • Attention/craft review: one toolbar control changes from disabled refresh to the available cancellation action. Recipient grouping and counts remain prominent, with full source detail behind existing expansion. The cancelled status explains the retained observation; actual failure clears rows and leaves retry/count-unknown visible. Narrow views wrap controls without shrinking body text. The 61-row case remains scannable; its long expanded original remains a scrollable document. A small/first-load case is covered by the same cancellation scenario. No new card, slogan, authority field or colour token.
View Before After while reading
Desktop 1200×888 before-desktop after-loading-desktop
Narrow 390×844 before-narrow after-loading-narrow
Cancelled reading, recoverable source error and expanded original at 390px after-cancelled-narrow after-error-narrow after-original-narrow

Type / Area / Boundaries

  • Bug fix and regression test; presentation surface.
  • DCO sign-off; one focused commit; no English/Chinese RFC pair changed.
  • No private source, raw diagnostic/profile, credentials, internal links or local paths in the diff, body or images. Generated captures stay ignored.
  • No benchmark duplication, shared-authority promotion, merge, install or release. Shared-authority RFC fixture impact: N/A.

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)

没有发现阻塞性问题。以下结论只覆盖精确 head 的“取消读取”任务,不把界面操作视为委派执行、完成验收或合并授权。

动机 / Motivation

在管家对话中回看委派的用户,需要在慢读取期间停止等待,并继续当前筛选、分页与原文阅读。
此前读取期间刷新被禁用,用户只能关闭再打开弹窗并重新找回上下文;新代码允许在原处取消读取,再沿当前条件重试。
取消后弹窗、已读记录和已展开原文保留,迟到响应不能覆盖新读取;失败时显示未知并可恢复。
不取消或执行被委派的工作,不改变来源授权、任务完成判断或持久化状态,也不新增配置步骤。

独立基线页面已复现刷新禁用且没有原地取消入口。保持现状或关闭重开会重复筛选与找回原文;复用当前按钮退休读取更小、更符合已知意图。用户不需要重新输入来源信息、申请委派取消或多一轮确认。取消后重试是恢复操作,不是新的业务授权。

改动思路 / Approach

取消与重试属于当前读取视图,沿用 generation、AbortController 和既有授权 reader,比新增后端取消状态或配置更直接。
当前 PR 的完整边界是原地退休读取、保留阅读上下文并可重试;不扩展委派执行、授权或完成判断。

cancelRead 在 abort 之前推进 generation,让旧 callback 即便随后返回也不能发布。取消只清 busy 并记录本地意图,pages 和展开原文继续保留;再次点击同一个筛选条件会推进 revision。关闭弹窗或更换来源仍沿原 reset 和授权路径。将 generation fence、视图取消和请求生命周期放在各自 owner,避免“停止等待读取”被解释成“取消工作”。

具体改动 / Changes

审查 head:17b96b83dc420c4b50855102aa6a8809470a8848;实际 merge base:acc00f54513682dc5db95ed53ee9104fd59dafde。完整 diff 为 4 个文件,224 additions / 12 deletions;生产变更集中在现有组件,172 行是专用 smoke,其余为 fixture 的实际 HTTP gate 与脚本接入。实际 target main 独立固定为 3c7e0935fd6697291c5c432e5267816b4a667cfa 用于 diff/premerge/CQR,没有把目标分支观察值当作 merge base。

规格为 docs/development/frontend-delivery.md,固定 revision acc00f54513682dc5db95ed53ee9104fd59dafde,在 diff 之前读取。原文条款没有独立编号,以下标签只用于定位:delegation-read-only:读取仍沿现有来源授权,不确认、取消或执行请求,58 个真实 HTTP File/SQLite 用例在 base/head 均通过,浏览器 POST 计数和 source/chat 字节不变。same-query-retry:取消后同条件可重试;已实际验证全部记录重试,以及搜索 A 取消、B 读到记录 60、A 迟到后 B 保持。complete-original:既有完整历史 reader 与发现上限不变,15619 字符原文及结束标记在取消61条多窗口刷新后仍在。task-continuity:打包页面从发现按钮、授权读取、反馈到失败重试均走真实 backend,非组件 mock。

关键入口 ConversationRequests(230)维持 source/session、filter 与分页快照;cancelRead(353)只退休读取;OriginalRequest(161)继续按原 session/turn 读取完整历史。独立流程包含首次键盘 Enter 取消并保留未知数量、12条翻页取消后保留12条再重试至24条、读到61条并展开长原文,以及实际 inventory503后的清空旧结果与 Retry 恢复。fixture 的 continue 只放行新读,release 再放开旧读,确实挑战了迟到响应,不是只检查 AbortSignal 字段。

对主干的风险 / Risks

主要风险是旧响应覆盖新查询、取消刷新丢失累计页或把未知误报为空。generation 在 abort 前推进,旧读取 finally 同样受 fence 约束;实测迟到 A 未覆盖 B,取消多窗口刷新保留61条和展开原文。错误路径清空旧 rows、显示未知数量与重试,恢复后重新读取12条;既有任务状态与回执未被改写。默认关闭状态没有新增后台扫描,也没有引入 opt-in 配置或共享必填字段。

PASS:base/head 各58个 inventory/control pytest,两个精确版本 packaged build,head dashboard tsc --noEmit、新 TS smoke 的 Node syntax、fixture Ruff、配置内17-source mypy、native premerge/public-boundary 检查。浏览器使用 Ego 操作实际打包页面与 SQLite owner;未额外启动仓库 smoke 的 Playwright driver,不声称它执行通过。FAILED advisory:ratchet 在独立 target-main/head 同命令均 exit1,完整 stdout/stderr 相同,均为未改动的 _admitted_interaction_next_cli_actions;这是保留的无关失败,不是本 PR 新缺陷。CQR 精确 scope 为 pass。未查询或等待 CI,也未合并。

我的整体评价 / Verdict

已查看 1200×888 和 390×844 的真实打包页面:默认列表保留接收方、目的、状态和时间层级,取消/刷新与页脚可找到;展开的长原文使用正文区滚动,窄屏搜索换行且错误与重试同屏。
未验证范围:宿主已安装版本、原生 Windows 和真实业务数据;本次为精确 head 打包资源接真实隔离 SQLite 后端,不据此宣称全局新鲜度或排序。

常见慢读取的恢复不再要求关闭并重建阅读上下文;业务授权、完整原文和失败反馈仍由原 owner 提供。默认与展开视图均查看了合成的重复长内容和混合待回复/待结论/待送达状态;原文正文可滚动,错误与 Retry 可见。此项范围可独立回退且已完成真实入口验证,批准结论成立。实际 Host 安装、真实数据排序和更广义长期收益仍不由这些 fixture 证明,合并须另行满足维护者授权与 readiness。

English verdict: APPROVE — in-place read cancellation preserves context, rejects late responses, and recovers through the existing authorized reader.

@huangruiteng
huangruiteng merged commit edc7418 into main Nov 5, 2026
31 of 42 checks passed
@huangruiteng
huangruiteng deleted the codex/delegation-recovery-20261105-075011 branch November 5, 2026 12:48
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.

2 participants