4.7 KiB
Agent Note(agent 决策记录):为待处理队列项提供编辑、移除与前移操作
Status: implemented
English | 中文
问题
Web 队列能够渲染待处理消息,但无法操作其中某一行。MessageId 不足以充当寻址标识,因为调用方可以多次将同一条不可变消息加入队列。浏览器还会根据轮次和状态事件推断队列项已退役,因此当行操作与驱动器认领发生竞态时,系统无法给出权威结果。
“立即发送”还引入了另一项语义选择:它可以表示重新排序下一个独立轮次、以 steering(中途引导)方式打断当前轮次,或取消当前工作。只有第一种解释能够保留该队列行原有的投递契约。
决策
每次获准进入 FIFO 的项都有独立标识。 AgentLoop 会铸造不透明的 InboxItemId,并发布一个 InboxItem,其中包含该 id、已有标识的 UserMessage,以及接受时确定的 queued | steering 放置方式。复用同一个 MessageId 会创建不同的 inbox 标识。注入绕过 FIFO,因此不会获得 inbox 标识。
变更边界止于驱动器认领。 Agent.updateInbox(id, action) 会同步搜索仍处于待处理状态的 queued 和 steering FIFO。编辑会替换已冻结的内容,同时保留 InboxItemId、MessageId、来源、放置方式、唤醒策略和位置。移除会发出该次入队项的终态 discard。前移会把它移至当前 FIFO 的队首;普通 queued 项还会变为可唤醒。驱动器会在提示词接纳或排空 steering 之前移除该项,因此之后的变更会返回 not-found,绝不会改写持久历史。
实时账本是权威状态。 agent/inbox/enqueue、update、dequeue 和 discard 共同维护 Host 镜像。协议发送完整的 session/queue 快照,而非增量猜测。重连会发送当前基线,每次实时变更或终态事件都会整体替换它。客户端不会进行乐观编辑,也绝不根据 turn/start、steering/message 或状态变化退役队列行。
Web 操作保持投递类型。 QueueDock 只投影 queued 入队项;待处理的 steering 入队项仍保留在权威快照中,等待 Web 提供专用交互。它只暴露编辑和删除,不提供立即发送控件。仅当所有内容块都是文本时才提供编辑功能;编辑器不能静默丢弃非文本块。编辑中的行只展示保存和取消操作,对应的键盘操作分别是 Enter 和 Escape。删除会移除对应的精确入队项。协议层仍保留前移操作,但不会把它呈现为 Web 交互;该操作绝不会把 queued 工作转换为 steering,也不会取消活动工作。
考虑过的替代方案
通过 MessageId 寻址行。 不予采纳,因为同一条不可变消息可以重复发送;按消息标识编辑或删除会无法确定应操作哪一次入队。
在浏览器中进行乐观变更。 不予采纳,因为驱动器认领或另一个客户端可能先于 Host 操作完成。等待权威快照可以显式呈现所有权边界,并让 queue-item-not-found 报告真实竞态。
把立即发送视为 steering。 不予采纳,因为这会把一个独立的排队轮次变成当前轮次的上下文,绕过普通提示词接纳,并改变单次 send 单轮次保证。前移只改变优先级,不改变投递语义。
前移前取消活动轮次。 不予采纳,因为仅影响某一行的操作不应破坏无关的进行中工作。
验证
AgentLoop 契约测试会在编辑、移除和前移对应的精确入队项时阻塞提示词接纳,随后验证所得独立轮次顺序及终态生命周期事件。Host schema 与代理测试覆盖权威快照、重连、类型化 not-found 错误和 RPC 传输。客户端运行时和 QueueDock 测试覆盖非乐观投影、Web 仅投影 queued 项、仅文本编辑、保存与取消入口、移除、退役竞态、禁用混合内容编辑,以及不提供立即发送控件。无密钥浏览器场景会通过构建后的 Web 组合和真实 HTTP/SSE 协议操作公开的编辑和删除,并使已接受的待处理 steering 在成为持久 transcript(文本记录)事件之前保持隐藏。
后果
待处理工作获得精确的行操作,但不会因此成为持久会话历史。单次入队标识是进程本地的实时寻址凭据,会在认领、取消、dispose 或重启时消失;重连只能恢复仍由活跃 Agent 持有的项。立即发送有意弱于打断,而编辑也有意排除混合内容,直至编辑器能够保留每个块。
现在,协议会在每次变更时携带完整队列快照。队列预期保持较短,因此系统优先选择确定性恢复和多客户端收敛,而非增量变更协议。