Messages and delivery
Черга команд
OpenClaw серіалізує вхідні запуски автовідповідей (з усіх каналів) через невелику внутрішньопроцесну чергу, щоб запобігти конфліктам між кількома запусками агента, водночас забезпечуючи безпечний паралелізм між сеансами.
Навіщо це потрібно
- Запуски автовідповідей можуть бути ресурсомісткими (виклики LLM) і конфліктувати, коли кілька вхідних повідомлень надходять майже одночасно.
- Серіалізація запобігає конкуренції за спільні ресурси (файли сеансів, журнали, стандартний ввід CLI) і знижує ймовірність спрацювання обмежень частоти запитів у зовнішніх системах.
Як це працює
- FIFO-черга з урахуванням смуг обробляє кожну смугу з налаштовуваним обмеженням паралельності (типово 1 для неналаштованих смуг; типове значення для
main— 4, дляsubagent— 8). runEmbeddedAgentставить запуск у чергу за ключем сеансу (смугаsession:<key>), гарантуючи лише один активний запуск на сеанс.- Потім кожен запуск сеансу ставиться в глобальну смугу (типово
main), щоб загальний паралелізм обмежувався значеннямagents.defaults.maxConcurrent. - Коли ввімкнено докладне журналювання, запуски в черзі виводять коротке сповіщення, якщо перед початком вони чекали понад ~2 с.
- Індикатори набору тексту однаково спрацьовують одразу після додавання до черги (якщо канал це підтримує), тому взаємодія з користувачем не змінюється, поки запуск очікує своєї черги.
Типові значення
Якщо параметри не задано, для всіх поверхонь вхідних каналів використовуються:
mode: "steer"debounceMs: 500cap: 20drop: "summarize"
Керування в межах того самого ходу використовується типово. Запит, що надходить під час запуску, вставляється в активне середовище виконання, якщо запуск може прийняти керування, тому другий запуск сеансу не починається. Якщо активний запуск не може прийняти керування, OpenClaw очікує його завершення, перш ніж запустити запит.
Режими черги
/queue визначає, що відбувається зі звичайними вхідними повідомленнями, коли сеанс уже має активний запуск:
steer: вставляє повідомлення в активне середовище виконання. OpenClaw передає всі повідомлення керування, що очікують, після того, як поточний хід асистента завершить виконання своїх викликів інструментів, але перед наступним викликом LLM; сервер застосунку Codex отримує один пакетнийturn/steer. Якщо запуск не здійснює активне потокове передавання або керування недоступне, OpenClaw очікує завершення активного запуску, перш ніж запустити запит.followup: не виконує керування. Ставить кожне повідомлення в чергу для наступного ходу агента після завершення поточного запуску.collect: не виконує керування. Об’єднує повідомлення в черзі в один наступний хід після завершення вікна тиші. Якщо повідомлення призначені для різних каналів або гілок, вони обробляються окремо, щоб зберегти маршрутизацію.interrupt: перериває активний запуск для цього сеансу, а потім запускає найновіше повідомлення.
Докладніше про часові характеристики та поведінку залежностей для конкретного середовища виконання див. у розділі Черга керування. Відомості про явну команду /steer <message> див. у розділі Керування.
Налаштуйте глобально або для окремого каналу через messages.queue:
{ messages: { queue: { mode: "steer", debounceMs: 500, cap: 20, drop: "summarize", byChannel: { discord: "collect" }, }, },}Параметри черги
Параметри застосовуються до доставки з черги. debounceMs також задає вікно тиші керування Codex у режимі steer:
debounceMs: вікно тиші перед обробкою наступних повідомлень із черги або пакетівcollect; у режиміsteerCodex — вікно тиші перед надсиланням пакетного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 мають перевагу над конфігурацією. Далі в зазначеному порядку застосовуються затримка для конкретного каналу (messages.queue.debounceMsByChannel), типові затримки Plugin, глобальні параметри messages.queue та вбудовані типові значення. cap і drop — це глобальні параметри або параметри сеансу, а не ключі конфігурації окремого каналу.
Перевизначення для окремого сеансу
- Надішліть
/queue <steer|followup|collect|interrupt>як окрему команду, щоб зберегти режим черги для поточного сеансу. - Параметри можна поєднувати:
/queue collect debounce:0.5s cap:25 drop:summarize /queue defaultабо/queue resetочищає перевизначення сеансу.
Скасування ходу в черзі
Поки запит перебуває в черзі followup/collect (наприклад, коли chat.send із TUI або вебчату надходить під час активного іншого ходу), Gateway зберігає належний Gateway ідентифікатор скасування для клієнтського runId, доки вміст із черги не буде запущено або видалено. Ідентифікатор слідує за вмістом, включеним до зведення про переповнення.
chat.abortіз конкретнимrunIdскасовує цей хід, поки він ще перебуває в черзі, якщо запитувач авторизований (за тими самими правилами володіння, що й для активних запусків).chat.abortдля сеансу безrunIdспочатку скасовує авторизовані ходи в черзі, а потім перериває авторизовані активні запуски. Такий порядок не дає обробці черги перевести роботу в частково зупинений сеанс.- Очищення всієї черги сеансу без перевірки кожного запитувача не є способом зупинки для сеансів із кількома власниками.
- Очікування в черзі не відображаються як активні запуски агента в
sessions.listі не мають семантики часу очікування активного запуску; вона застосовується лише до активної фази.
Клієнти (зокрема TUI) пересилають запити, що надходять під час запуску, і дають Gateway застосувати режим черги. Esc//stop використовує переривання в межах сеансу, щоб втрата локальних дескрипторів не призвела до виконання запиту, який усе ще перебуває в черзі.
Область дії та гарантії
- Застосовується до запусків агента автовідповідей у всіх вхідних каналах, які використовують конвеєр відповідей Gateway (вебверсія WhatsApp, Telegram, Slack, Discord, Signal, iMessage, вебчат тощо).
- Типова смуга (
main) діє в межах усього процесу для вхідних повідомлень і основних Heartbeat; задайтеagents.defaults.maxConcurrent, щоб дозволити паралельну роботу кількох сеансів. - Можуть існувати додаткові смуги (наприклад,
cron,cron-nested,nested,subagent), щоб фонові завдання могли виконуватися паралельно, не блокуючи вхідні відповіді. Ізольовані ходи агента Cron утримують слотcron, поки їхнє внутрішнє виконання агента використовуєcron-nested; обидві смуги використовуютьcron.maxConcurrentRuns. Спільні потокиnested, не пов’язані з Cron, зберігають власну поведінку смуги. Ці від’єднані запуски відстежуються як фонові завдання. - Смуги для окремих сеансів гарантують, що в будь-який момент часу лише один запуск агента працює з певним сеансом.
- Жодних зовнішніх залежностей або фонових робочих потоків; лише TypeScript і проміси.
Усунення несправностей
- Якщо здається, що команди зависли, увімкніть докладні журнали та знайдіть рядки «queued for ...ms», щоб переконатися, що черга обробляється.
- Запуски сервера застосунку Codex, які приймають хід, а потім припиняють повідомляти про поступ, перериваються адаптером Codex, щоб активна смуга сеансу могла звільнитися, а не очікувала завершення зовнішнього часу очікування запуску.
- Коли діагностику ввімкнено, сеанси, які залишаються в стані
processingдовше заdiagnostics.stuckSessionWarnMsбез зафіксованого поступу відповіді, інструмента, стану, блока або ACP, класифікуються за поточною активністю:- Активна робота з нещодавнім поступом журналюється як
session.long_running. Беззвучні виклики моделі з визначеним власником також залишаютьсяsession.long_runningдоdiagnostics.stuckSessionAbortMs, щоб повільні постачальники або постачальники без потокового передавання не позначалися як завислі надто рано. - Активна робота без нещодавнього поступу журналюється як
session.stalled; виклики моделі з визначеним власником, заблоковані виклики інструментів і завислі вбудовані запуски переходять у станsession.stalledпісля досягнення порога переривання. Застаріла активність моделі або інструмента без власника не приховується як довготривала. session.stuckзарезервовано для відновлюваних застарілих облікових даних сеансу, зокрема неактивних сеансів у черзі із застарілою активністю моделі або інструмента без власника.session.stuckзавжди запускає відновлення, яке може звільнити відповідну смугу сеансу. Класифікаціяsession.stalledпісля перевищенняdiagnostics.stuckSessionAbortMs(заблокований виклик інструмента, завислий виклик моделі або завислий вбудований запуск) також може запустити відновлення з активним перериванням, тому обидві класифікації можуть розблокувати чергу, а не лишеsession.stuck.- Для повторюваних рядків журналу попереджень
session.stuckіsession.long_runningінтервал збільшується експоненційно, доки сеанс залишається незмінним; спроби відновлення однаково виконуються під час кожного такту Heartbeat незалежно від цього збільшення інтервалу.
- Активна робота з нещодавнім поступом журналюється як