> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openkova.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 提示词排队

> 排队、并入当前轮、立即发送——以及为什么队列状态要用全量快照而不是增量。

提示词排队让你在 agent 还在跑的时候把后续要求写进去。

排队条上只有四个操作，没有更多。这一页讲它们各自做什么，以及背后的一个设计决定：
**队列状态用全量快照而不是增量**。它正好能说明扣瓦怎么处理「前端状态」这类问题。

## 按线程隔离

<Note>
  队列**按线程隔离**：每个 threadId 一条 FIFO，串行链也是每线程一条。
  不同线程的 turn 并行执行、互不阻塞。
</Note>

这条隔离解决的是早期最难缠的一类问题：上一轮没结束时到达的新 prompt 如果直接
打到 `agent.prompt()`，会撞上 `Agent is already processing` 守卫。现在它进入该线程的
FIFO，由该线程的串行链依次执行。

所以「排队」不是全局的一个盒子，而是**每个会话各自的一条队**——
你在会话 A 排队不会挡住会话 B。

## 四个操作

<CodeGroup>
  ```text 默认排队 / Queue theme={null}
  Enter 发送进队列，等当前轮结束按序派发。

  并入当前轮 / Steer
  不打断当前回合，但把这条消息交给正在跑的 agent。

  立即发送 / Promote
  插队，这条消息立刻派发。

  删除 / Cancel
  从队列里移除。
  ```
</CodeGroup>

编辑、暂停/恢复、失败熔断在重构中被**有意移除**，不是遗漏：

* **没有暂停**：派发中的项已从快照消失，无锁定态可言；上一轮流收尾后链节自动取队首开跑
* **没有熔断**：失败项随流终结回填成气泡，要不要重发由你决定，而不是让一个自动闸
  替你决定后面几条也一起停

## 早期的问题在哪

<Columns cols={2}>
  <Column title="症状与根源">
    队列状态没有持久化、事实源分散、前端对消息数组做多路手术。
    刷新重启后排队消息失踪变成 ghost；消息数组要摘除/回填/恢复/抑制四条路径，
    还有恢复竞态、对账重复追加、顺序错乱；任意旁路流结束把会话状态打回 ready，
    按钮闪烁。
  </Column>

  <Column title="现在的答案">
    队列重写为纯状态机 `QueueEngine`——队列、自增 id、派发收口在一个无 I/O 的类里。
    **每次变更**向会话转录追加一行全量快照，重启、切线程、树导航之后从最后一条恢复；
    同时向线程广播全量快照，前端「最后快照胜出」。
  </Column>
</Columns>

<Note>
  选全量快照而不是增量的理由很朴素：队列通常不超过 5 条，全量最简单、没有对账逻辑，
  广播频率也低。
</Note>

### 快照怎么走

* **持久化**：每次变更向 session JSONL 追加一行 `queue_state` 全量快照
* **恢复**：sidecar 重启后经 `get_queue_state` 回放恢复，**不再自动暂停**
* **广播**：每次变更经 `sendEventChunk` 向该线程发 `data-queue-state`
* **冲突**：前端「最后快照胜出」。线程无活跃请求时快照静默丢弃——空闲态的变更都由
  前端自身的 invoke 发起，前端从回复里自更新

<Note>
  「同 id 原地更新多 phase」那种增量 chunk 形态**已整体废弃**。
  入队、位置、派发全部由全量快照承载，没有 per-item 生命周期 chunk。
</Note>

## 前端三条同步规则

前端对消息数组的所有操作收敛为三条，每条幂等：

| 规则 | 触发 | 做什么 |
| - | - | - |
| R1 queued | 快照里有这条 | 消息只在排队条（从 Chat 数组摘除，防重复项） |
| R2 出队 | 快照里这条消失（轮真正开始） | 消息回填列表末尾；刷新后没有原气泡，就用快照文本重建 |
| R3 steered | 并入当前轮 | 维持「宿主轮收尾回填」——立即回填会在宿主轮写入窗口内触发重复项增长与乱序 |

被删掉的旧路径：restore 竞态补偿、cancelled 标记、对账方向分支——全部由
「快照状态 + 三条规则」替代。

## 稳定 id

条目有**持久化的自增 id**，跨重启不重复，派发与取消都以 id 寻址。

这不是细节：早期用数组下标寻址，重启后下标错位就会取消错东西。

## 附件不丢

早期快照只持久化文本，刷新后重建的气泡不带附件。后来修掉了——快照条目现在携带
图片附件（协议形状 `{ name, mimeType, data | path }`，与 prompt 帧同形），
刷新/重启恢复、接力泵出队重发与队列条缩略图都不丢图。

<Note>
  这里有个值得记的坑：sidecar 原本按一个**前端从不发送**的 `type: "image"` 字段判形状，
  实际把图片全部丢弃——所以历史 queue\_state 行无一携带附件，而且不报错。
  教训是：协议形状要对齐已经在用的那一套，而不是发明一个新字段。
</Note>

## 已知边界

「发送后、确认前」刷新：注册表在前端内存里，刷新即清空。此时那一项按快照重建
（现在含图片附件），可接受。

## 下一步

<CardGroup cols={2}>
  <Card title="模式总览" icon="sliders" href="/features/modes">
    一个应用里五个「模式」，别混。
  </Card>

  <Card title="会话工作区" icon="message" href="/features/conversation">
    排队条在对话流里的位置。
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.