命令队列
序列化入站自动回复运行的命令队列设计
我们通过一个小型的进程内队列序列化入站自动回复运行(所有通道),以防止多个代理运行发生冲突,同时仍然允许跨会话的安全并行。
理由
- 自动回复运行可能很昂贵(LLM 调用),当多个入站消息同时到达时可能会发生冲突。
- 序列化避免了竞争共享资源(会话文件、日志、CLI stdin),并减少了上游速率限制的机会。
工作原理
- 通道感知 FIFO 队列以可配置的并发上限排出每个通道(未配置的通道默认为 1;主通道默认为 4,子代理默认为 8)。
- ''runEmbeddedPiAgent'' 按''会话键''排队(通道 ''session:<key>''),以保证每个会话只有一个活动运行。
- 每个会话运行然后排队到''全局通道''(默认 ''main''),因此总并行度受 ''agents.defaults.maxConcurrent'' 限制。
- 当启用详细日志时,排队的运行如果在开始前等待超过约 2 秒,会发出简短通知。
- 输入指示器在排队时仍会立即触发(当通道支持时),因此用户体验在我们等待轮次时保持不变。
队列模式(每个通道)
入站消息可以引导当前运行、等待后续轮次,或两者兼有:
- ''steer'':立即注入当前运行(在下一个工具边界后取消待处理的工具调用)。如果未流式传输,则回退到后续。
- ''followup'':在当前运行结束后排队等待下一个代理轮次。
- `drop`:溢出策略(`old`、`new`、`summarize`)。
- ''steer-backlog''(又名 ''steer+backlog''):现在引导''并''保留消息以供后续轮次。
- ''interrupt''(旧版):中止该会话的活动运行,然后运行最新消息。
- ''queue''(旧版别名):与 ''steer'' 相同。
Steer-backlog 意味着您可以在引导运行后获得后续响应,因此流式传输界面可能看起来像重复。如果您希望每个入站消息获得一个响应,请使用 ''collect''/''steer''。
流式传输表面可能看起来像重复。如果您希望每个入站消息获得一个响应,请使用 ''collect''/''steer''。
入站消息每个 1 次的响应。
Send ''/queue collect'' as a standalone command (per-session) or set ''messages.queue.byChannel.discord: "collect"''.
默认(设置在设置未被場合):
- All surfaces → ''collect''
通过 ''messages.queue'' 全局或按通道配置:
{
messages: {
queue: {
mode: "collect",
debounceMs: 1000,
cap: 20,
drop: "summarize",
byChannel: { discord: "collect" },
},
},
}队列选项
选项是 ''followup''、''collect''、以及 ''steer-backlog''(跟进在回退当执行机是 ''steer'' 在也適用被)在適用被:
- ''debounceMs'': wait for quiet before starting a followup turn (prevents "continue, continue").
- ''cap'': max queued messages per session.
- ''drop'': overflow policy (''old'', ''new'', ''summarize'').
Summarize会保留已丢弃消息的简短项目列表,并将其作为合成后续提示注入。默认值:''debounceMs: 1000''、''cap: 20''、''drop: summarize''。
会话每个覆盖
- Send ''/queue <mode>'' as a standalone command to store the mode for the current session.
- Options can be combined: ''/queue collect debounce:2s cap:25 drop:summarize''
- ''/queue default'' or ''/queue reset'' clears the session override.
作用域和保証
- Applies to auto-reply agent runs across all inbound channels that use the gateway reply pipeline (WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, webchat, etc.).
- Default lane (''main'') is process-wide for inbound + main heartbeats; set ''agents.defaults.maxConcurrent'' to allow multiple sessions in parallel.
- Additional lanes may exist (e.g. ''cron'', ''subagent'') so background jobs can run in parallel without blocking inbound replies.
- Per-session lanes guarantee that only one agent run touches a given session at a time.
- No external dependencies or background worker threads; pure TypeScript + promises.
故障排除
- If commands seem stuck, enable verbose logs and look for "queued for …ms" lines to confirm the queue is draining.
- If you need queue depth, enable verbose logs and watch for queue timing lines.