Зачем
- Запуски автоответов могут быть дорогими (вызовы LLM) и могут конфликтовать, когда несколько входящих сообщений приходят почти одновременно.
- Сериализация предотвращает конкуренцию за общие ресурсы (файлы сеанса, журналы, stdin CLI) и снижает вероятность лимитов частоты на стороне вышестоящих сервисов.
Как это работает
- FIFO-очередь с учетом полосы обрабатывает каждую полосу с настраиваемым лимитом параллелизма (по умолчанию 1 для ненастроенных полос; main по умолчанию 4, subagent — 8).
runEmbeddedAgentставит в очередь по ключу сеанса (полосаsession:<key>), чтобы гарантировать только один активный запуск на сеанс.- Затем каждый запуск сеанса ставится в глобальную полосу (
mainпо умолчанию), так что общий параллелизм ограничиваетсяagents.defaults.maxConcurrent. - Когда включено подробное логирование, запуски в очереди выводят короткое уведомление, если ждали более ~2 с перед стартом.
- Индикаторы набора по-прежнему срабатывают сразу при постановке в очередь (если канал поддерживает это), поэтому пользовательский опыт не меняется, пока мы ждем своей очереди.
Значения по умолчанию
Если не задано, все входящие поверхности каналов используют:mode: "steer"debounceMs: 500cap: 20drop: "summarize"
Режимы очереди
/queue управляет тем, что делают обычные входящие сообщения, когда у сеанса уже есть
активный запуск:
steer: внедрять сообщения в активную среду выполнения. OpenClaw доставляет все ожидающие сообщения управления после того, как текущий ход ассистента завершит выполнение вызовов инструментов, перед следующим вызовом LLM; app-server Codex получает один пакетныйturn/steer. Если запуск не выполняет активную потоковую передачу или управление недоступно, OpenClaw ждет завершения активного запуска перед запуском подсказки.followup: не управлять. Ставить каждое сообщение в очередь для более позднего хода агента после завершения текущего запуска.collect: не управлять. Объединять сообщения в очереди в один последующий ход после окна тишины. Если сообщения нацелены на разные каналы/потоки, они обрабатываются по отдельности, чтобы сохранить маршрутизацию.interrupt: прервать активный запуск для этого сеанса, затем выполнить самое новое сообщение.
/steer <message>
см. в разделе Управление.
Настраивайте глобально или для каждого канала через messages.queue:
Параметры очереди
Параметры применяются к доставке из очереди.debounceMs также задает окно тишины
для управления Codex в режиме steer:
debounceMs: окно тишины перед обработкой последующих сообщений или пакетов collect из очереди; в режиме Codexsteer— окно тишины перед отправкой пакетногоturn/steer. Простые числа считаются миллисекундами; параметры/queueпринимают единицыms,s,m,hиd.cap: максимальное число сообщений в очереди на сеанс. Значения ниже1игнорируются.drop: "summarize": по умолчанию. При необходимости отбрасывать самые старые записи очереди, сохранять компактные сводки и внедрять их как синтетическую последующую подсказку.drop: "old": при необходимости отбрасывать самые старые записи очереди без сохранения сводок.drop: "new": отклонять самое новое сообщение, когда очередь уже заполнена.
debounceMs: 500, cap: 20, drop: summarize.
Управление и потоковая передача
Когда потоковая передача канала имеет значениеpartial или block, управление может выглядеть как несколько
коротких видимых ответов, пока активный запуск достигает границ среды выполнения:
partial: предварительный просмотр может завершиться рано, затем после принятия управления начинается новый предварительный просмотр.block: блоки размером с черновик могут создавать такой же последовательный вид.- Без потоковой передачи управление возвращается к последующему сообщению после активного запуска, когда среда выполнения не может принять управление в том же ходе.
steer не прерывает уже выполняющиеся инструменты. Используйте /queue interrupt, когда самое новое
сообщение должно прервать текущий запуск.
Приоритет
Для выбора режима OpenClaw разрешает:- Встроенное или сохраненное переопределение
/queueдля сеанса. messages.queue.byChannel.<channel>.messages.queue.mode.- Значение по умолчанию
steer.
/queue имеют приоритет над конфигурацией. Затем
применяются специфичный для канала debounce (messages.queue.debounceMsByChannel), значения debounce по умолчанию Plugin,
глобальные параметры messages.queue и встроенные значения по умолчанию. cap и drop — это глобальные/сеансовые параметры, а не конфигурационные
ключи для отдельных каналов.
Переопределения для сеанса
- Отправьте
/queue <steer|followup|collect|interrupt>как отдельную команду, чтобы сохранить режим очереди для текущего сеанса. - Параметры можно комбинировать:
/queue collect debounce:0.5s cap:25 drop:summarize /queue defaultили/queue resetочищает переопределение сеанса.
Область действия и гарантии
- Применяется к запускам агента автоответов во всех входящих каналах, которые используют конвейер ответов Gateway (WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, webchat и т. д.).
- Полоса по умолчанию (
main) действует в рамках процесса для входящих сообщений и основных Heartbeat; задайтеagents.defaults.maxConcurrent, чтобы разрешить параллельную работу нескольких сеансов. - Могут существовать дополнительные полосы (например,
cron,cron-nested,nested,subagent), чтобы фоновые задания могли выполняться параллельно, не блокируя входящие ответы. Изолированные ходы cron-агента удерживают слотcron, пока их внутреннее выполнение агента используетcron-nested; оба используютcron.maxConcurrentRuns. Общие не-cron-потокиnestedсохраняют собственное поведение полосы. Эти отсоединенные запуски отслеживаются как фоновые задачи. - Полосы для сеанса гарантируют, что только один запуск агента одновременно обращается к данному сеансу.
- Никаких внешних зависимостей или фоновых рабочих потоков; только TypeScript + promises.
Устранение неполадок
- Если команды кажутся зависшими, включите подробные журналы и ищите строки “queued for …ms”, чтобы подтвердить, что очередь обрабатывается.
- Если нужна глубина очереди, включите подробные журналы и следите за строками тайминга очереди.
- Запуски app-server Codex, которые принимают ход, а затем перестают выводить прогресс, прерываются адаптером Codex, чтобы активная полоса сеанса могла освободиться, не дожидаясь тайм-аута внешнего запуска.
- Когда диагностика включена, сеансы, которые остаются в
processingдольшеdiagnostics.stuckSessionWarnMsбез наблюдаемого ответа, инструмента, статуса, блока или прогресса ACP, классифицируются по текущей активности. Активная работа логируется какsession.long_running; принадлежащие владельцу тихие вызовы модели также остаютсяsession.long_runningдоdiagnostics.stuckSessionAbortMs, чтобы медленные или непотоковые провайдеры не считались зависшими слишком рано. Активная работа без недавнего прогресса логируется какsession.stalled; принадлежащие владельцу вызовы модели переключаются наsession.stalledна пороге прерывания или после него, а устаревшая активность модели/инструмента без владельца не скрывается как длительная.session.stuckзарезервирован для восстанавливаемого устаревшего учета сеансов, включая простаивающие сеансы в очереди с устаревшей активностью модели/инструмента без владельца, и только этот путь может освободить затронутую полосу сеанса, чтобы работа из очереди продолжила обрабатываться. Повторные диагностикиsession.stuckприменяют backoff, пока сеанс остается неизменным.