Repository navigation
fix(chat): allow cancelling delegation reads in place - #8102
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.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.
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
main(rebased ontoacc00f54513682dc5db95ed53ee9104fd59dafde).conversation-requests.tsx; first-read and filter cancellation oracleScope 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-searchentry 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
17b96b83dc420c4b50855102aa6a8809470a8848.finished.synthetic,public_fixture,authorized_private_read_only. Original-input diagnostics remain private and do not establish a matched timing comparison.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 keyboardtests/control_plane/test_chat_request_inventory.pyandtest_chat_request_control.py: 58 real HTTP/File/SQLite checks after rebase_admitted_interaction_next_cli_actionshas 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 changedCoverage 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
8a48e346dc3352c51a07255052d9256b38571264; after images use the same UI source blob now committed in17b96b83dc420c4b50855102aa6a8809470a8848. Final bundle/tests ran after rebase. Independent fixture instances can have different generated times. No hosted preview;npm run smoke:delegation-cancelreproduces the packaged journey.Cancelled reading, recoverable source error and expanded original at 390px
Type / Area / Boundaries