You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
摘要
用户在工作中排队消息(prompt mode
queue→agent.followup)后点击"中止",队列内容的命运取决于时机:若中止落在队列项被 claim 之前,cancel({ keepInbox: true })保留 inbox 且wakeRequested会重新唤醒驱动,行为正常;但一旦队列项在步骤边界被Inbox.claim()消费进当前轮(该删除是持久化的 pure-deletion splice),随后中止当前轮时,没有任何逻辑把这些已 claim、未得到回复的消息回填 inbox——它们变成会话历史里"没有回应的 user 消息",既不排队也不触发新轮次,必须手动重发一条消息才能继续。若中止恰好落在 claim 之后、user/message 落盘之前的窗口,消息则彻底丢失(inbox 已删、历史未记)。这解释了 #212:「中止工作中内容后,无法直接处理队列中内容,需要在对话窗重新输入」——答案是bug,不是"没玩明白"。根因(源码定位,rc.6)
dsh-agent/lib/types/inbox.jsclaim()(L50-58):步骤边界把 next-step 全部 +next-turn 一条持久化删除(
mutate(..., false),splice 事件直接落 session 日志),并发布 claimed 通知;删除不可逆、无回填 API 语义。
dsh-agent-loop/lib/index.jspreStep()(L496):每步边界调用this.inbox.claim(target, position.turn),把队列项并入本步装配。turn()(L554):claim 的消息要等到 preStep 完成后才session.append("user/message", ...)落盘——claim 与落盘之间存在中止窗口(L532/L547 的
signal.throwIfAborted())。cancel()(L405-411):用户中止走agent.cancel({ kind: "user" }, { keepInbox: true })(host-apiproxy L2959),inbox 不清空——但已 claim 的消息已不在 inbox,
keepInbox救不了它们。kick()finally(L488):中止后只有当wakeRequested && this.inbox.hasPending才重新唤醒;已 claim 的消息使
hasPending为 false → 不再唤醒。三个时间窗:① 中止在 claim 前 → 正常续跑(设计行为);
② 中止在 claim 后 → 队列项成历史中无回应的 user 消息,不再触发任何轮次(主缺陷);
③ 中止在 claim 与 user/message 落盘之间 → 消息永久丢失(inbox 已删、历史未记)。
复现步骤
建议修复
方案 A(推荐)· 中止时回填已 claim 消息:
turn()记录本论从 inbox claim 的user 消息(已 append 但未得到 assistant 回应的),当该轮以
aborted结束(turn/end reason = aborted)时,把这些消息按原顺序重新
inbox.prepend("next-turn")并唤醒驱动。语义与用户预期完全一致:"停止"= 终止当前步骤,排队内容下一个轮次继续。
方案 B · 缩小丢失窗口:把 claim 的持久化删除延后到 user/message 落盘之后的
同一原子段(或先落盘 user/message 再删 inbox),消除第③窗口;但②(历史里无回应
消息不自动处理)仍需方案 A 解决。
方案 C(UI 缓解):中止后若历史末尾存在无回应的 user 消息,UI 提供"继续处理
队列"的显式按钮(等价手动重发,但不需要重新输入内容)。
影响
静默失效或丢失,用户必须重输——内容越长损失越大
环境
验证材料
turn 延迟落盘 → cancel keepInbox 救不回 → kick 不唤醒)
First analysis of discussion #212. Happy to open a PR with fix option A.
All reactions