Messages and delivery

Черга команд

Ми серіалізуємо вхідні запуски автоматичних відповідей (усі канали) через невелику внутрішньопроцесну чергу, щоб запобігти конфліктам між кількома запусками агентів, водночас зберігаючи безпечний паралелізм між сесіями.

Навіщо

  • Запуски автоматичних відповідей можуть бути дорогими (виклики LLM) і можуть конфліктувати, коли кілька вхідних повідомлень надходять майже одночасно.
  • Серіалізація уникає конкуренції за спільні ресурси (файли сесій, журнали, stdin CLI) і зменшує ймовірність обмежень швидкості з боку upstream.

Як це працює

  • Черга FIFO з урахуванням lane обробляє кожну lane з налаштовуваним лімітом паралельності (за замовчуванням 1 для неналаштованих lane; main за замовчуванням 4, subagent — 8).
  • runEmbeddedPiAgent ставить у чергу за ключем сесії (lane session:<key>), щоб гарантувати лише один активний запуск на сесію.
  • Потім кожен запуск сесії ставиться у глобальну lane (main за замовчуванням), щоб загальний паралелізм обмежувався agents.defaults.maxConcurrent.
  • Коли ввімкнене докладне журналювання, запуски в черзі виводять коротке повідомлення, якщо вони чекали понад ~2 с перед стартом.
  • Індикатори набору все одно спрацьовують одразу під час додавання в чергу (якщо канал це підтримує), тому користувацький досвід не змінюється, поки ми чекаємо своєї черги.

Значення за замовчуванням

Коли не задано, усі поверхні вхідних каналів використовують:

  • mode: "steer"
  • debounceMs: 500
  • cap: 20
  • drop: "summarize"

steer є значенням за замовчуванням, бо він зберігає активний хід моделі чутливим без запуску другого виконання сесії. Він обробляє всі керувальні повідомлення, що надійшли до наступної межі моделі. Якщо поточний запуск не може прийняти керування, OpenClaw повертається до запису черги followup.

Режими черги

Вхідні повідомлення можуть керувати поточним запуском, чекати ходу followup або робити обидва:

  • steer: ставить керувальні повідомлення в чергу активного runtime. Pi доставляє всі очікувані керувальні повідомлення після того, як поточний хід асистента завершить виконання своїх викликів інструментів, перед наступним викликом LLM; Codex app-server отримує один пакетний turn/steer. Якщо запуск не виконує активний streaming або керування недоступне, OpenClaw повертається до запису черги followup.
  • queue (застарілий): старе почергове керування. Pi доставляє одне повідомлення керування з черги на кожній межі моделі; Codex app-server отримує окремі запити turn/steer. Надавайте перевагу steer, якщо вам не потрібна попередня серіалізована поведінка.
  • followup: ставить кожне повідомлення в чергу для пізнішого ходу агента після завершення поточного запуску.
  • collect: об’єднує повідомлення в черзі в один хід followup після тихого вікна. Якщо повідомлення спрямовані в різні канали/потоки, вони обробляються окремо, щоб зберегти маршрутизацію.
  • steer-backlog (також steer+backlog): керує зараз і зберігає те саме повідомлення для ходу followup.
  • interrupt (застарілий): перериває активний запуск для цієї сесії, а потім запускає найновіше повідомлення.

Steer-backlog означає, що ви можете отримати відповідь followup після керованого запуску, тому поверхні streaming можуть виглядати як дублікати. Надавайте перевагу collect/steer, якщо хочете одну відповідь на кожне вхідне повідомлення.

Про timing і поведінку залежностей, специфічні для runtime, див. Черга керування. Для явної команди /steer <message> див. Керування.

Налаштуйте глобально або для кожного каналу через messages.queue:

{
  messages: {
    queue: {
      mode: "steer",
      debounceMs: 500,
      cap: 20,
      drop: "summarize",
      byChannel: { discord: "collect" },
    },
  },
}

Параметри черги

Параметри застосовуються до followup, collect і steer-backlog (а також до steer або застарілого queue, коли керування повертається до followup):

  • debounceMs: тихе вікно перед обробкою followup у черзі. Голі числа — це мілісекунди; одиниці ms, s, m, h і d приймаються параметрами /queue.
  • cap: максимальна кількість повідомлень у черзі на сесію. Значення нижче 1 ігноруються.
  • drop: "summarize": за замовчуванням. За потреби відкидає найстаріші записи черги, зберігає компактні підсумки та вставляє їх як синтетичний prompt followup.
  • drop: "old": за потреби відкидає найстаріші записи черги без збереження підсумків.
  • drop: "new": відхиляє найновіше повідомлення, коли черга вже заповнена.

Значення за замовчуванням: debounceMs: 500, cap: 20, drop: summarize.

Пріоритет

Для вибору режиму OpenClaw визначає:

  1. Вбудоване або збережене посесійне перевизначення /queue.
  2. messages.queue.byChannel.<channel>.
  3. messages.queue.mode.
  4. Значення за замовчуванням steer.

Для параметрів вбудовані або збережені параметри /queue мають перевагу над конфігурацією. Потім застосовуються channel-specific debounce (messages.queue.debounceMsByChannel), значення debounce за замовчуванням Plugin, глобальні параметри messages.queue і вбудовані значення за замовчуванням. cap і drop є глобальними/сесійними параметрами, а не посесійними конфігураційними ключами.

Посесійні перевизначення

  • Надішліть /queue <mode> як окрему команду, щоб зберегти режим для поточної сесії.
  • Параметри можна комбінувати: /queue collect debounce:0.5s cap:25 drop:summarize
  • /queue default або /queue reset очищує перевизначення сесії.

Обсяг і гарантії

  • Застосовується до запусків агентів автоматичних відповідей в усіх вхідних каналах, які використовують pipeline відповідей gateway (WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, webchat тощо).
  • Lane за замовчуванням (main) є process-wide для вхідних повідомлень і основних heartbeats; задайте agents.defaults.maxConcurrent, щоб дозволити кілька сесій паралельно.
  • Можуть існувати додаткові lane (наприклад, cron, cron-nested, nested, subagent), щоб фонові завдання могли виконуватися паралельно без блокування вхідних відповідей. Ізольовані ходи cron-агента утримують slot cron, поки їхнє внутрішнє виконання агента використовує cron-nested; обидва використовують cron.maxConcurrentRuns. Спільні non-cron потоки nested зберігають власну поведінку lane. Ці відокремлені запуски відстежуються як фонові завдання.
  • Посесійні lane гарантують, що лише один запуск агента торкається конкретної сесії в певний момент часу.
  • Без зовнішніх залежностей або фонових worker-потоків; чистий TypeScript + promises.

Усунення несправностей

  • Якщо здається, що команди зависли, увімкніть докладні журнали й шукайте рядки "queued for ...ms", щоб підтвердити, що черга обробляється.
  • Якщо вам потрібна глибина черги, увімкніть докладні журнали й стежте за рядками timing черги.
  • Запуски Codex app-server, які приймають хід, а потім припиняють виводити прогрес, перериваються адаптером Codex, щоб активна lane сесії могла звільнитися замість очікування timeout зовнішнього запуску.
  • Коли діагностику ввімкнено, сесії, що залишаються в processing після diagnostics.stuckSessionWarnMs без спостереженої відповіді, інструмента, статусу, block або прогресу ACP, класифікуються за поточною активністю. Активна робота журналюється як session.long_running; активна робота без нещодавнього прогресу журналюється як session.stalled; session.stuck зарезервовано для застарілого bookkeeping сесії без активної роботи, і лише цей шлях може звільнити відповідну lane сесії, щоб робота в черзі обробилася. Повторна діагностика session.stuck застосовує backoff, поки сесія залишається незмінною.

Пов’язане