Skip to content

feat(chat): edit and cancel pending queue messages - #8096

Merged
huangruiteng merged 1 commit into
mainfrom
codex/chat-queue-edit-cancel-20261105-041910
Nov 5, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/chat-queue-edit-cancel-20261105-041910

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

待处理消息此前只能查看或插入本轮,发现输入有误后无法在启动前修正或取消。现在可在该条消息的“更多”菜单中编辑或取消排队;取消保留历史标记,编辑保留附件。确认丢失时可核对原操作,避免重复执行。

  • Outcome basis / source: 已接受的队列 steering 与编辑/取消需求;Command+Enter 插入当前回合,Enter 排队、Shift+Enter 换行的主输入框约定保持不变。
  • Observable result: More → Edit → Save,或 Cancel queued message;旧修订、已启动回合和原来源权限变化拒绝修改并保留编辑草稿。
  • Intended base: main,已核对 4b7afef2215067dd1171f308b93c9336e1c6e5d9。不关闭更大范围的工作区交付任务。

Author Declaration

  • Written by: model_agent — OpenAI Codex。
  • Specification and revision: 本 PR 记录的维护者已接受请求;docs/integrations/session-runtime-control-plane-adapter.md 的 queued-input 契约,修订见本 PR。
Criterion Disposition Owning path Evidence
精确修改/取消尚未启动的原队列输入 implemented loopx/control_plane/turn_driver/chat_queue_steering.ts HTTP/store 竞争与 source/session 拒绝用例
保留附件、历史及原 admission 的重试身份 implemented loopx/chat_ingress.py 实际编辑后 native dispatch 与原 admission replay
丢失确认后沿原操作恢复,不重复执行 implemented 同一 TS owner + queue journal partial write/reopen 测试与浏览器 reload/check
队列 UI、Command+Enter、取消 readback implemented conversation-queue.tsx / channel-timeline.tsx 打包浏览器流程、composer smoke
  • Self-check: 阅读最终 18 文件范围和仓库约束;复用原 owner、锁、可见历史分页与 source admission;Python 仅执行 HTTP/journal IO。没有新增配置、执行权限或平行决策 owner。

Scope And Continuation

本 PR 完成 pending web input 的编辑、取消、恢复与历史 readback。部分写入先持久化 reservation,自动出队和 steering 使用同一 Session/Turn fence;只有原 operation 和 intent 可完成或重放。外部、绑定、协作及 LoopX execution 输入沿原入口处理。

同域整理将路由放回现有 queue API mixin,并移除一用即弃的 runtime wrapper 与多余的 raw-input reader;完整输入复用原有 audience-projected paged history。没有提高模块预算。

更大范围的原生前景/后台与安装版验证仍沿现有工作区交付流程推进。安装、发布与合并不在本次操作范围内;本提案可独立审阅、测试和回退。

Validation

  • Tested revision: 浏览器、native/store 和主回归在 4647ffc40c4dece167e42f95cc02b2c099db8c41;最终 head 7774095cf61287ff891ba6daa52080736ba20f13 仅重放到最新已核对 main,18 文件 patch 比对完全一致。最终 head 重新严格构建、质量资格和 quick premerge。
  • Run state: finished。
  • Input classes: synthetic + public_fixture。
Check kind Result Evidence / limitation
integration / real_backend passed tests/presentation/test_chat_turn_queue.py 25 项;真实 HTTP、文件 Chat journal、TS effect owner,两种 claim 顺序、丢失提交恢复、权限与 Session 拒绝、附件实际派发。隔离 File/SQLite canonical Goal 上下文均通过;不表示 Chat journal 改为 SQLite。
regression_parity passed 85 项原生 Chat/steering/project 既有回归;未启用新操作的 admission 路径不变。
unit passed 全量 TS 控制面 6120 passed / 77 conditional skipped / 0 failed;新队列 owner 与 history reducer 的 stale/role/Turn/Session/live-answer 用例通过。
static passed control-plane strict TS、dashboard strict TS/build、仓库配置 mypy 17 files、changed-path Ruff、semantic vocabulary advisory、diff/public boundary。
real_entrypoint / manual passed 编译后的交付 assets + 实际 Chat HTTP/store;编辑、取消历史标记、lost ACK 后刷新核对、存储故障先于提交、附件保留、390px 无横向溢出、Command+Enter steering → FIFO 下一条 → Stop 命中新的当前 Turn。native 边界使用脚本化 stdio host。
real_entrypoint passed packaged composer smoke:Enter / Shift+Enter / Command+Enter。
static passed exact-scope change-quality receipt valid,quick premerge 的双语、模块 ceiling、边界/风险/接口 budget 与 public-boundary 检查通过。独立 PR review / CI / merge-readiness 另行判断。
manual not_run 真实付费模型、安装版桌面 App、真实 macOS 中文 IME、Lark/CS-Notes 端到端未在此隔离流程资格化;不据此声称整体工作区交付完成。

Frontend / Visual Evidence

  • UI impact: changed。
  • Primary question: 我能否在启动前修正或取消这一条待处理消息?默认保留紧凑队列;编辑、完整输入和附件按需展开。保存失败与不确定状态保留草稿和原 operation,主输入框不被覆盖。
  • Source data: public_fixture(已入库真实 EdgeBench Grid R7 history)+ synthetic(隔离会话与操作输入)。R7 两组均为 runner_invalid,不计分、不推断 benchmark 增益;没有运行新 benchmark 或上传原始轨迹。
  • Build boundary: compiled packaged assets / real owning HTTP+store / scripted stdio executor;不是安装版或真实模型验收。Before 03d6ab2864a54e86ab4f97854854d0e4acd7dd48,After 4647ffc;最终 rebase 不改这 18 文件 patch。
  • Preview: 本地隔离验证已结束,不提供会过期的本地地址。截图为实际界面,未改图。
  • Attention/craft review: 原队列只多一个 More 入口,保持本轮操作、取消 readback 与主输入在同一视口;长真实内容、混合状态、附件及错误均实际检查。沿用现有排版、图标和间距,无新增大卡片或文案口号;原有长答复展示不在本 PR 范围。
State Desktop Narrow (390px)
Before:查看/插入,不能编辑或取消 Before desktop Before narrow
After:取消标记与 pre-submit 存储失败;右侧为 lost ACK 的原操作核对 After cancel and storage failure After unconfirmed edit

附件编辑后保留并可展开,主草稿保留:

Edited input retains attachment

Type of Change

  • New feature
  • Bug fix
  • Documentation update
  • Test update

LoopX Area

  • Control plane (runtime queue owner)
  • Public docs or presentation surface (dashboard)
  • Host or runtime integration

Technical Direction

现有 roadmap S5 的原会话/回合、重连、重复操作与 stale 拒绝边界;这里仅交付原队列输入操作,不声明整个阶段完成。

Shared-authority RFC fixture impact

N/A:未声明 TypeScript migration 或 shared Goal Authority RFC 的阶段进度;未改变 canonical Goal provider、promotion、routing 或 legacy compatibility。

Boundary Checklist

  • Diff、正文和附件不包含密钥、私有状态、本机路径、内部链接、raw trace 或 verifier output。
  • 未重复维护者拥有的 benchmark 工作;仅复用现有公开 display fixture。
  • 变更限定在上述队列输入任务。
  • 无既有成对 RFC 变更;双语 premerge check 通过。
  • 首屏与窄屏、真实数据/执行边界及失败状态已直接展示。
  • 唯一提交保留 DCO Signed-off-by。

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; model=gpt-6.1-sol; provider=OpenAI; reasoning_effort=max; declaration_source=runtime_reported

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

动机 / Motivation

浏览器中等待当前回合完成、又需要纠正下一条输入的用户会遇到这个问题:在当前回合执行期间,用户发现待处理输入有错,只能查看或插入当前回合,无法在启动前修改或取消。错误输入可能继续执行,或需要等待、追加说明。同一条带附件的待处理消息,现在可以 More → 编辑 → 保存,或取消排队;修改确认丢失后刷新,仍能核对同一操作。实际 HTTP 与打包页面验证了文本修改、附件保留、取消历史标记,以及旧修订拒绝后草稿保留。

这是一条完整的 pending-input 修正路径,不需要重新选择附件、覆盖主输入草稿,或增加一次权限确认。More 隐藏低频操作,保存提交明确的新文本;取消直接作用于原待处理项。未知确认才需要“核对修改”。不声明整个工作区交付、安装态、真实模型收益或自动接续显示问题已完成。

改动思路 / Approach

修改复用原队列的 Session→Turn 锁;Session 是原对话,Turn 是其中一轮工作。TS owner 判断来源、是否仍排队、输入修订和操作身份,Python 按计划修改原用户记录。先持久化待完成操作,再写文本、历史、事件和最终修订;部分写入会使该项暂停自动出队及 steering。只有同一个操作和同一份意图能完成恢复,不能用新操作替换未知写入。

现有 TS queue owner 决定资格、修订与重放;Python 只执行有锁的 journal IO,React 只保留用户草稿和原操作,没有第二个执行或权限 owner。沿用现有 queue API mixin、完整分页且经过 audience 投影的历史读取和历史 reducer,避免新增 raw-input 读取通道。保留原文本用于 admission 重试身份比较,不把修正后的文本当作另一次发送。

触发 验证后的结果
尚未启动、原 web 输入、修订匹配 编辑原文本或取消原项,附件及历史保留
旧修订、已经启动、来源失效或不同 Session 拒绝修改,保留编辑草稿
部分写入、确认丢失 保留原操作恢复,不重新发送消息
未执行新操作 原队列、busy 拒绝、重复 admission 与原输入保持

本次完成尚未启动的 web 输入编辑、取消和原操作恢复;既有自动接续显示缺口、安装版、真实模型与 macOS IME 不在通过结论内。

具体改动 / Changes

评审对象为 7774095,固定基线为 4b7afef。先读基线的 docs/integrations/session-runtime-control-plane-adapter.md 队列与快捷键契约,再读完整 18 文件 diff。新增 22 行文档是本提案的操作说明,未拿它反向认证实现。以下 CHAT 标记只是给既有未编号条款加的评审索引:

  • CHAT-IDENTITY:原 Session、client_turn_id、附件与“接受不等于执行”。编辑后原 admission 重试仍返回同一个 Turn;独立 HTTP 验证了取消后原 admission 重试也不会重发。
  • CHAT-FIFO:复用原队列消费边界。编辑/取消与 claim 的两种串行顺序均验证,当前回合不被打断,不跨 Session 修改。
  • CHAT-RECOVERY:未知结果保留原身份。实际服务端提交后人为丢弃浏览器确认,刷新后核对同一操作;存储故障发生在提交前,实际修改请求数为零。
  • CHAT-KEYS:普通 Enter 排队、Shift+Enter 换行、Command+Enter 插入语义保留;编辑区 Command+Enter 保存自己的草稿。已跑键盘单测及实际 Enter/Command+Enter;真实 macOS 中文 IME 没有资格化。

关键执行位置:

  • planQueuedChatMutation:拒绝来源、状态、修订或操作意图冲突;完成操作可按原身份重放。
  • mutate_queued_input:在消费锁内执行 reservation→原用户行及历史→事件→Session cache 时间→Turn 提交,部分写入可恢复。
  • QueuedMessage:提交前保存恢复身份;确认校验 session、Turn、action、operation、revision;旧状态拒绝时保留草稿。
  • reconcileConversationReturns:只接受同一用户行的更新修订,不让旧读取、其他角色/Turn/Session 覆盖取消或实时答案。

18 文件 +612/-33 包含 3 个测试文件 +224/-1、文档 +22,其余是相互依赖的决策、journal、UI 与 readback。没有新增模块、配置、provider 或平行 Python 决策实现。新状态有具体生产者:用户选择产生不可推断的操作意图;有锁执行产生 pending/completed receipt 和历史;列表只是投影。旧记录缺省修订为 0,不能因前后端共同部署而删除持久历史兼容性。

对主干的风险 / Risks

主要风险是混合写入后错误出队、重复发送、旧修订覆盖,以及界面丢草稿。独立验证覆盖了实际 HTTP、真实文件 Chat journal、TS effect owner、并发锁和进程重开,脚本化 stdio host 替代模型。本轮结果如下;没有查询或等待远程 CI。

验证 结果与边界
队列、ordinary project、preparation、steering 回归 head 153 passed;基线 145 passed,共同用例全部通过,新增 8 项;File/SQLite 是 canonical Goal 上下文,Chat journal 仍是 File
TS queue / history reducer / keyboard queue 5 passed,history reducer 与 composer 键盘单测通过
无新操作的固定基线对照 完整 queue、Turn、原用户行、重复 admission、busy/GET 拒绝、无 native IO 的观察向量一致;只规范化生成身份、时间、临时 fixture 根及已核对的两个新增缺省字段,未删错误/权限/文本语义
独立新操作敏感性 基线 POST input 返回 404 且不改原输入;head 编辑、同操作重试、stale 拒绝、取消、旧 edit 重放及取消后 admission 重试均符合预期,无 native 重发
打包 UI + 实际 owning backend 编辑/取消、附件、lost ACK→刷新→核对、存储故障零请求、旧修订拒绝保留双草稿,desktop/390px 展开检查通过
严格 TS、dashboard build、Ruff、diff/双语/公开边界 通过;build chunk-size 提示保留
标准 premerge FAIL:todo-readmodel-boundary-smoke.py line 101 访问不存在的 loopx.status.open_todo_items;固定基线与 head 的完整 traceback 相同,仅替换 checkout 根。另有相同基线 maintainability advisory;不写成全绿或合并就绪

另一个既有缺口也必须保留:对刷新恢复的对话,在原回合完成、下一条已由后端开始时,界面可能仍显示旧轮结束并缺少 Stop。基线与 head 的实际打包页面均复现;再刷新后,Stop 都准确命中新一轮 durable-turn-2。这不是本 PR 引入的回归,也不能支持正文中“自动接续到新回合控制已全面验证”的更强结论。它属于原接续/显示路径的后续修复,不能用本次编辑/取消通过来关闭。

我的整体评价 / Verdict

APPROVE,未发现本次 diff 新增的阻塞性问题;author-owned 账号通过 COMMENTED 承载批准结论。独立证据支持有用且可回退的 pending-input 编辑/取消交付,不能推导到合并、安装、完整工作区或长期成本验收。标准 premerge 失败和既有接续显示缺口仍然保留。

实际打包页面中,待处理列表、More、附件、取消标记和主输入同屏可辨;长输入按需展开。展开编辑区需要内部滚动,错误可在该区域下方读到;未把无横向溢出等同于视觉验收。检查使用长重复中文输入、两条待处理项、附件、活动回合和混合错误状态;390px 展开输入和附件可读。作者测试版与本 head 的 18 个文件 blob 全部一致,且独立构建和浏览器检查在本 head 完成;复用截图没有扩大版本边界。

安装版桌面、真实 macOS 中文 IME、Lark/CS-Notes 未验证。刷新恢复后自动接续时,基线与 head 均可显示旧轮结束而缺少 Stop,需再刷新;这是既有缺口,未视为本 PR 已修复。相应的当前回合控制还需要原显示 owner 修复;本提案没有提高权限或改变该 owner。完整净收益和真实模型采用也没有测量。

English verdict: APPROVE — the explicit pending-input edit/cancel path is verified. The unchanged local validation failure and pre-existing follow-up display gap remain; this is not merge or installation authorization.

@huangruiteng
huangruiteng merged commit 76cc8d0 into main Nov 5, 2026
36 of 47 checks passed
@huangruiteng
huangruiteng deleted the codex/chat-queue-edit-cancel-20261105-041910 branch November 5, 2026 08: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