diff --git a/docs/uk/channels/telegram.md b/docs/uk/channels/telegram.md index cde611227..524454eef 100644 --- a/docs/uk/channels/telegram.md +++ b/docs/uk/channels/telegram.md @@ -4,25 +4,25 @@ read_when: summary: Стан підтримки бота Telegram, можливості та конфігурація title: Telegram x-i18n: - generated_at: "2026-04-29T12:15:20Z" + generated_at: "2026-04-29T14:47:18Z" model: gpt-5.5 provider: openai - source_hash: 500f1282c7d6f7350b781a2413737b0e34b00ea8b042703341fd9ddb700ecfb4 + source_hash: 1ffc0c1a6bb94fbab81ede0f08b0e3a165f06c599d4d06d4b9e70c8ba41121f7 source_path: channels/telegram.md workflow: 16 --- -Готово до production для DM ботів і груп через grammY. Довге опитування є режимом за замовчуванням; режим Webhook необов’язковий. +Готове до production-використання для DM ботів і груп через grammY. Long polling є режимом за замовчуванням; режим webhook необов’язковий. - Типова політика DM для Telegram — сполучення. + Політика DM за замовчуванням для Telegram — сполучення. - - Міжканальна діагностика та плейбуки відновлення. + + Міжканальна діагностика та сценарії відновлення. - Повні шаблони й приклади конфігурації каналу. + Повні шаблони та приклади конфігурації каналів. @@ -30,9 +30,9 @@ x-i18n: - Відкрийте Telegram і поспілкуйтеся з **@BotFather** (переконайтеся, що ім’я користувача точно `@BotFather`). + Відкрийте Telegram і поспілкуйтеся з **@BotFather** (переконайтеся, що handle точно `@BotFather`). - Виконайте `/newbot`, дотримуйтесь підказок і збережіть токен. + Запустіть `/newbot`, дотримуйтесь підказок і збережіть токен. @@ -52,7 +52,7 @@ x-i18n: ``` Резервний варіант env: `TELEGRAM_BOT_TOKEN=...` (лише обліковий запис за замовчуванням). - Telegram **не** використовує `openclaw channels login telegram`; налаштуйте токен у config/env, а потім запустіть gateway. + Telegram **не** використовує `openclaw channels login telegram`; налаштуйте токен у config/env, потім запустіть gateway. @@ -69,33 +69,33 @@ openclaw pairing approve telegram - Додайте бота до своєї групи, а потім налаштуйте `channels.telegram.groups` і `groupPolicy` відповідно до вашої моделі доступу. + Додайте бота до своєї групи, потім налаштуйте `channels.telegram.groups` і `groupPolicy` відповідно до вашої моделі доступу. -Порядок визначення токена враховує обліковий запис. На практиці значення config мають пріоритет над резервним env, а `TELEGRAM_BOT_TOKEN` застосовується лише до облікового запису за замовчуванням. +Порядок визначення токена враховує облікові записи. На практиці значення config мають пріоритет над резервним env, а `TELEGRAM_BOT_TOKEN` застосовується лише до облікового запису за замовчуванням. -## Налаштування на боці Telegram +## Налаштування з боку Telegram Боти Telegram за замовчуванням використовують **Privacy Mode**, який обмежує, які групові повідомлення вони отримують. - Якщо бот має бачити всі групові повідомлення, або: + Якщо бот має бачити всі групові повідомлення, зробіть одне з такого: - вимкніть режим приватності через `/setprivacy`, або - зробіть бота адміністратором групи. - Після перемикання режиму приватності видаліть і повторно додайте бота в кожній групі, щоб Telegram застосував зміну. + Після перемикання режиму приватності видаліть і знову додайте бота в кожну групу, щоб Telegram застосував зміну. Статус адміністратора керується в налаштуваннях групи Telegram. - Боти-адміністратори отримують усі групові повідомлення, що корисно для постійно активної поведінки в групі. + Боти-адміністратори отримують усі групові повідомлення, що корисно для постійної поведінки в групах. @@ -114,32 +114,32 @@ openclaw pairing approve telegram `channels.telegram.dmPolicy` керує доступом через прямі повідомлення: - `pairing` (за замовчуванням) - - `allowlist` (потребує принаймні один ID відправника в `allowFrom`) + - `allowlist` (потребує принаймні одного ID відправника в `allowFrom`) - `open` (потребує, щоб `allowFrom` містив `"*"`) - `disabled` - `dmPolicy: "open"` з `allowFrom: ["*"]` дає змогу будь-якому обліковому запису Telegram, який знайде або вгадає ім’я користувача бота, керувати ботом. Використовуйте це лише для навмисно публічних ботів із суворо обмеженими інструментами; боти з одним власником мають використовувати `allowlist` із числовими ID користувачів. + `dmPolicy: "open"` з `allowFrom: ["*"]` дозволяє будь-якому обліковому запису Telegram, який знайде або вгадає ім’я користувача бота, керувати ботом. Використовуйте це лише для навмисно публічних ботів із жорстко обмеженими інструментами; боти з одним власником мають використовувати `allowlist` із числовими ID користувачів. - `channels.telegram.allowFrom` приймає числові ID користувачів Telegram. Префікси `telegram:` / `tg:` приймаються й нормалізуються. - У конфігураціях із кількома обліковими записами обмежувальний `channels.telegram.allowFrom` верхнього рівня вважається межею безпеки: записи `allowFrom: ["*"]` на рівні облікового запису не роблять цей обліковий запис публічним, якщо ефективний allowlist облікового запису після злиття все ще не містить явного wildcard. + `channels.telegram.allowFrom` приймає числові ID користувачів Telegram. Префікси `telegram:` / `tg:` приймаються та нормалізуються. + У конфігураціях із кількома обліковими записами обмежувальний верхньорівневий `channels.telegram.allowFrom` вважається межею безпеки: записи `allowFrom: ["*"]` на рівні облікового запису не роблять цей обліковий запис публічним, якщо ефективний список дозволених для облікового запису після об’єднання не містить явний wildcard. `dmPolicy: "allowlist"` з порожнім `allowFrom` блокує всі DM і відхиляється перевіркою конфігурації. Налаштування запитує лише числові ID користувачів. - Якщо ви оновилися й ваша конфігурація містить записи allowlist `@username`, виконайте `openclaw doctor --fix`, щоб розв’язати їх (best-effort; потребує токен бота Telegram). - Якщо ви раніше покладалися на файли allowlist зі сховища сполучень, `openclaw doctor --fix` може відновити записи в `channels.telegram.allowFrom` у потоках allowlist (наприклад, коли `dmPolicy: "allowlist"` ще не має явних ID). + Якщо ви оновилися і ваша конфігурація містить записи списку дозволених `@username`, запустіть `openclaw doctor --fix`, щоб їх розв’язати (best-effort; потрібен токен бота Telegram). + Якщо раніше ви покладалися на файли списку дозволених зі сховища сполучень, `openclaw doctor --fix` може відновити записи в `channels.telegram.allowFrom` у потоках allowlist (наприклад, коли `dmPolicy: "allowlist"` ще не має явних ID). - Для ботів з одним власником надавайте перевагу `dmPolicy: "allowlist"` з явними числовими ID `allowFrom`, щоб політика доступу була стійкою в config (замість залежності від попередніх схвалень сполучення). + Для ботів з одним власником надавайте перевагу `dmPolicy: "allowlist"` з явними числовими ID `allowFrom`, щоб політика доступу була сталою в конфігурації (замість залежності від попередніх схвалень сполучення). - Типова плутанина: схвалення сполучення DM не означає «цей відправник авторизований скрізь». + Поширене непорозуміння: схвалення сполучення DM не означає «цей відправник авторизований усюди». Сполучення надає доступ до DM. Якщо власника команд ще немає, перше схвалене сполучення також встановлює `commands.ownerAllowFrom`, щоб команди лише для власника та схвалення exec мали явний обліковий запис оператора. - Авторизація відправника в групі все одно походить з явних allowlist у конфігурації. - Якщо ви хочете «мене авторизовано один раз, і працюють і DM, і групові команди», додайте свій числовий ID користувача Telegram до `channels.telegram.allowFrom`; для команд лише для власника переконайтеся, що `commands.ownerAllowFrom` містить `telegram:`. + Авторизація відправників у групах усе ще походить із явних списків дозволених у конфігурації. + Якщо ви хочете «я авторизований один раз, і працюють як DM, так і групові команди», додайте свій числовий ID користувача Telegram у `channels.telegram.allowFrom`; для команд лише для власника переконайтеся, що `commands.ownerAllowFrom` містить `telegram:`. - ### Як знайти свій ID користувача Telegram + ### Пошук вашого ID користувача Telegram Безпечніше (без стороннього бота): - 1. Напишіть DM своєму боту. - 2. Виконайте `openclaw logs --follow`. + 1. Надішліть DM своєму боту. + 2. Запустіть `openclaw logs --follow`. 3. Прочитайте `from.id`. Офіційний метод Bot API: @@ -152,29 +152,29 @@ curl "https://api.telegram.org/bot/getUpdates" - + Два елементи керування застосовуються разом: 1. **Які групи дозволені** (`channels.telegram.groups`) - - немає config `groups`: + - немає конфігурації `groups`: - з `groupPolicy: "open"`: будь-яка група може пройти перевірки ID групи - з `groupPolicy: "allowlist"` (за замовчуванням): групи заблоковані, доки ви не додасте записи `groups` (або `"*"`) - - `groups` налаштовано: діє як allowlist (явні ID або `"*"`) + - `groups` налаштовано: діє як список дозволених (явні ID або `"*"`) 2. **Які відправники дозволені в групах** (`channels.telegram.groupPolicy`) - `open` - `allowlist` (за замовчуванням) - `disabled` - `groupAllowFrom` використовується для фільтрації відправників у групах. Якщо не встановлено, Telegram повертається до `allowFrom`. + `groupAllowFrom` використовується для фільтрації відправників у групах. Якщо не задано, Telegram повертається до `allowFrom`. Записи `groupAllowFrom` мають бути числовими ID користувачів Telegram (префікси `telegram:` / `tg:` нормалізуються). - Не додавайте ID чатів груп або супергруп Telegram у `groupAllowFrom`. Від’ємні ID чатів належать до `channels.telegram.groups`. + Не додавайте ID чатів груп або супергруп Telegram у `groupAllowFrom`. Від’ємні ID чатів мають бути в `channels.telegram.groups`. Нечислові записи ігноруються для авторизації відправника. - Межа безпеки (`2026.2.25+`): авторизація відправника в групі **не** успадковує схвалення зі сховища сполучень DM. - Сполучення залишається лише для DM. Для груп встановіть `groupAllowFrom` або `allowFrom` для окремої групи/теми. - Якщо `groupAllowFrom` не встановлено, Telegram повертається до config `allowFrom`, а не до сховища сполучень. - Практичний шаблон для ботів з одним власником: встановіть свій ID користувача в `channels.telegram.allowFrom`, залиште `groupAllowFrom` невстановленим і дозвольте цільові групи в `channels.telegram.groups`. - Примітка щодо runtime: якщо `channels.telegram` повністю відсутній, runtime за замовчуванням fail-closed з `groupPolicy="allowlist"`, якщо `channels.defaults.groupPolicy` не встановлено явно. + Межа безпеки (`2026.2.25+`): auth відправників у групах **не** успадковує схвалення зі сховища сполучень DM. + Сполучення лишається тільки для DM. Для груп задайте `groupAllowFrom` або `allowFrom` для окремої групи/теми. + Якщо `groupAllowFrom` не задано, Telegram повертається до конфігураційного `allowFrom`, а не до сховища сполучень. + Практичний шаблон для ботів з одним власником: задайте свій ID користувача в `channels.telegram.allowFrom`, лишіть `groupAllowFrom` незаданим і дозвольте цільові групи в `channels.telegram.groups`. + Примітка щодо runtime: якщо `channels.telegram` повністю відсутній, runtime за замовчуванням переходить у fail-closed `groupPolicy="allowlist"`, якщо `channels.defaults.groupPolicy` не задано явно. Приклад: дозволити будь-якого учасника в одній конкретній групі: @@ -211,18 +211,18 @@ curl "https://api.telegram.org/bot/getUpdates" ``` - Типова помилка: `groupAllowFrom` не є allowlist груп Telegram. + Поширена помилка: `groupAllowFrom` не є списком дозволених груп Telegram. - Додавайте від’ємні ID чатів груп або супергруп Telegram, як-от `-1001234567890`, у `channels.telegram.groups`. - Додавайте ID користувачів Telegram, як-от `8734062810`, у `groupAllowFrom`, коли хочете обмежити, які люди всередині дозволеної групи можуть запускати бота. - - Використовуйте `groupAllowFrom: ["*"]` лише тоді, коли хочете, щоб будь-який учасник дозволеної групи міг говорити з ботом. + - Використовуйте `groupAllowFrom: ["*"]` лише тоді, коли хочете, щоб будь-який учасник дозволеної групи міг спілкуватися з ботом. - - Групові відповіді за замовчуванням потребують згадки. + + Відповіді в групах за замовчуванням потребують згадки. Згадка може надходити з: @@ -236,9 +236,9 @@ curl "https://api.telegram.org/bot/getUpdates" - `/activation always` - `/activation mention` - Вони оновлюють лише стан сесії. Використовуйте config для постійності. + Вони оновлюють лише стан сесії. Використовуйте конфігурацію для збереження. - Приклад постійної конфігурації: + Приклад сталої конфігурації: ```json5 { @@ -252,11 +252,11 @@ curl "https://api.telegram.org/bot/getUpdates" } ``` - Як отримати ID групового чату: + Отримання ID групового чату: - - переслати групове повідомлення до `@userinfobot` / `@getidsbot` - - або прочитати `chat.id` з `openclaw logs --follow` - - або перевірити Bot API `getUpdates` + - перешліть групове повідомлення до `@userinfobot` / `@getidsbot` + - або прочитайте `chat.id` з `openclaw logs --follow` + - або перегляньте Bot API `getUpdates` @@ -264,14 +264,14 @@ curl "https://api.telegram.org/bot/getUpdates" ## Поведінка runtime - Telegram належить процесу gateway. -- Маршрутизація детермінована: вхідні повідомлення Telegram отримують відповідь у Telegram (модель не вибирає канали). -- Вхідні повідомлення нормалізуються в спільний конверт каналу з метаданими відповіді та placeholder для медіа. -- Групові сесії ізольовані за ID групи. Теми форуму додають `:topic:`, щоб зберегти ізоляцію тем. -- DM-повідомлення можуть містити `message_thread_id`; OpenClaw маршрутизує їх із ключами сесії, що враховують тред, і зберігає ID треду для відповідей. -- Довге опитування використовує grammY runner із послідовністю на рівні чату/треду. Загальна конкуренція runner sink використовує `agents.defaults.maxConcurrent`. -- Довге опитування захищене всередині кожного процесу gateway, тож лише один активний poller може використовувати токен бота одночасно. Якщо ви все ще бачите конфлікти `getUpdates` 409, імовірно, інший gateway OpenClaw, скрипт або зовнішній poller використовує той самий токен. -- Перезапуски watchdog для long-polling запускаються після 120 секунд без завершеної liveness `getUpdates` за замовчуванням. Збільшуйте `channels.telegram.pollingStallThresholdMs` лише якщо ваше розгортання все ще бачить хибні перезапуски через polling-stall під час тривалої роботи. Значення в мілісекундах і дозволене від `30000` до `600000`; підтримуються перевизначення для окремих облікових записів. -- Telegram Bot API не підтримує підтвердження прочитання (`sendReadReceipts` не застосовується). +- Маршрутизація детермінована: вхідні повідомлення Telegram отримують відповіді назад у Telegram (модель не вибирає канали). +- Вхідні повідомлення нормалізуються у спільний channel envelope з метаданими відповіді та placeholders для медіа. +- Групові сесії ізольовані за ID групи. Теми форуму додають `:topic:`, щоб теми лишалися ізольованими. +- Повідомлення DM можуть містити `message_thread_id`; OpenClaw маршрутизує їх із thread-aware ключами сесії та зберігає ID thread для відповідей. +- Long polling використовує grammY runner із послідовністю per-chat/per-thread. Загальна конкуренція runner sink використовує `agents.defaults.maxConcurrent`. +- Long polling захищений усередині кожного процесу gateway, тому лише один активний poller може використовувати токен бота одночасно. Якщо ви все ще бачите конфлікти `getUpdates` 409, імовірно, той самий токен використовує інший gateway OpenClaw, скрипт або зовнішній poller. +- Перезапуски watchdog для long-polling запускаються після 120 секунд без завершеної liveness `getUpdates` за замовчуванням. Збільшуйте `channels.telegram.pollingStallThresholdMs` лише якщо ваше розгортання все ще бачить хибні перезапуски через polling stall під час тривалої роботи. Значення вказується в мілісекундах і дозволене від `30000` до `600000`; підтримуються перевизначення для окремих облікових записів. +- Telegram Bot API не підтримує read receipts (`sendReadReceipts` не застосовується). ## Довідник функцій @@ -286,10 +286,10 @@ curl "https://api.telegram.org/bot/getUpdates" - `channels.telegram.streaming` має значення `off | partial | block | progress` (за замовчуванням: `partial`) - `progress` зіставляється з `partial` у Telegram (сумісність із міжканальним іменуванням) - - `streaming.preview.toolProgress` керує тим, чи оновлення інструментів/прогресу повторно використовують те саме редаговане повідомлення попереднього перегляду (за замовчуванням: `true`, коли streaming попереднього перегляду активний) - - застарілі `channels.telegram.streamMode` і булеві значення `streaming` виявляються; виконайте `openclaw doctor --fix`, щоб мігрувати їх до `channels.telegram.streaming.mode` + - `streaming.preview.toolProgress` керує тим, чи оновлення інструментів/прогресу повторно використовують те саме редаговане повідомлення попереднього перегляду (за замовчуванням: `true`, коли активний preview streaming) + - застарілі `channels.telegram.streamMode` і булеві значення `streaming` виявляються; запустіть `openclaw doctor --fix`, щоб мігрувати їх до `channels.telegram.streaming.mode` - Оновлення попереднього перегляду прогресу інструментів — це короткі рядки «Працюю...», які показуються під час роботи інструментів, наприклад виконання команд, читання файлів, оновлення планування або підсумки patch. Telegram залишає їх увімкненими за замовчуванням, щоб відповідати випущеній поведінці OpenClaw з `v2026.4.22` і пізніше. Щоб залишити редагований попередній перегляд для тексту відповіді, але приховати рядки прогресу інструментів, встановіть: + Оновлення попереднього перегляду tool-progress — це короткі рядки «Working...», які показуються під час роботи інструментів, наприклад виконання команд, читання файлів, оновлень планування або підсумків patch. Telegram лишає їх увімкненими за замовчуванням, щоб відповідати випущеній поведінці OpenClaw від `v2026.4.22` і пізніше. Щоб зберегти редагований попередній перегляд для тексту відповіді, але приховати рядки tool-progress, задайте: ```json { @@ -306,18 +306,18 @@ curl "https://api.telegram.org/bot/getUpdates" } ``` - Використовуйте `streaming.mode: "off"` лише тоді, коли хочете доставку тільки фінальної відповіді: редагування попереднього перегляду Telegram вимикаються, а загальний шум інструментів/прогресу пригнічується замість надсилання як окремі повідомлення «Працюю...». Запити схвалення, медіа payload і помилки все одно маршрутизуються через звичайну фінальну доставку. Використовуйте `streaming.preview.toolProgress: false`, коли хочете лише зберегти редагування попереднього перегляду відповіді, приховавши рядки статусу прогресу інструментів. + Використовуйте `streaming.mode: "off"` лише тоді, коли хочете доставку тільки фінальної відповіді: редагування попереднього перегляду Telegram вимикаються, а загальний службовий текст інструментів/прогресу приглушується замість надсилання як окремих повідомлень «Working...». Запити схвалення, медіа payloads і помилки все ще маршрутизуються через звичайну фінальну доставку. Використовуйте `streaming.preview.toolProgress: false`, коли хочете лише зберегти редагування попереднього перегляду відповіді, приховавши рядки статусу tool-progress. Для відповідей лише з текстом: - - короткі попередні перегляди DM/груп/тем: OpenClaw зберігає те саме повідомлення попереднього перегляду та виконує фінальне редагування на місці - - попередні перегляди, старші приблизно за одну хвилину: OpenClaw надсилає завершену відповідь як нове фінальне повідомлення, а потім прибирає попередній перегляд, щоб видима позначка часу Telegram відображала час завершення, а не час створення попереднього перегляду + - короткі попередні перегляди DM/групи/теми: OpenClaw зберігає те саме повідомлення попереднього перегляду та виконує фінальне редагування на місці + - попередні перегляди, старші приблизно за одну хвилину: OpenClaw надсилає завершену відповідь як нове фінальне повідомлення, а потім очищає попередній перегляд, тож видима часова позначка Telegram відображає час завершення, а не час створення попереднього перегляду - Для складних відповідей (наприклад, медіанавантажень) OpenClaw повертається до звичайної фінальної доставки, а потім прибирає повідомлення попереднього перегляду. + Для складних відповідей (наприклад, медіа-навантажень) OpenClaw повертається до звичайної фінальної доставки, а потім очищає повідомлення попереднього перегляду. - Потокове передавання попереднього перегляду відокремлене від потокового передавання блоків. Коли потокове передавання блоків явно ввімкнено для Telegram, OpenClaw пропускає потік попереднього перегляду, щоб уникнути подвійного потокового передавання. + Потокове передавання попереднього перегляду відокремлене від потокового передавання блоків. Коли потокове передавання блоків явно ввімкнене для Telegram, OpenClaw пропускає потік попереднього перегляду, щоб уникнути подвійного потокового передавання. - Якщо нативний транспорт чернеток недоступний/відхилений, OpenClaw автоматично повертається до `sendMessage` + `editMessageText`. + Якщо нативний транспорт чернеток недоступний або відхилений, OpenClaw автоматично повертається до `sendMessage` + `editMessageText`. Потік міркувань лише для Telegram: @@ -329,16 +329,16 @@ curl "https://api.telegram.org/bot/getUpdates" Вихідний текст використовує Telegram `parse_mode: "HTML"`. - - Текст у стилі Markdown рендериться у безпечний для Telegram HTML. - - Сирий HTML моделі екранується, щоб зменшити помилки парсингу Telegram. + - Markdown-подібний текст відтворюється як безпечний для Telegram HTML. + - Сирий HTML моделі екранується, щоб зменшити збої парсингу Telegram. - Якщо Telegram відхиляє розібраний HTML, OpenClaw повторює спробу як звичайний текст. - Попередні перегляди посилань увімкнено за замовчуванням, їх можна вимкнути за допомогою `channels.telegram.linkPreview: false`. + Попередні перегляди посилань увімкнені за замовчуванням і можуть бути вимкнені через `channels.telegram.linkPreview: false`. - Реєстрація меню команд Telegram виконується під час запуску за допомогою `setMyCommands`. + Реєстрація меню команд Telegram виконується під час запуску через `setMyCommands`. Типові значення нативних команд: @@ -361,7 +361,7 @@ curl "https://api.telegram.org/bot/getUpdates" Правила: - - імена нормалізуються (видаляється початковий `/`, переводяться в нижній регістр) + - назви нормалізуються (прибирається початковий `/`, переводяться в нижній регістр) - допустимий шаблон: `a-z`, `0-9`, `_`, довжина `1..32` - користувацькі команди не можуть перевизначати нативні команди - конфлікти/дублікати пропускаються та записуються в журнал @@ -369,39 +369,39 @@ curl "https://api.telegram.org/bot/getUpdates" Примітки: - користувацькі команди є лише записами меню; вони не реалізують поведінку автоматично - - команди Plugin/Skills усе ще можуть працювати під час введення, навіть якщо їх не показано в меню Telegram + - команди Plugin/навичок можуть і далі працювати під час введення, навіть якщо їх не показано в меню Telegram - Якщо нативні команди вимкнено, вбудовані команди видаляються. Користувацькі команди/команди Plugin усе ще можуть реєструватися, якщо це налаштовано. + Якщо нативні команди вимкнені, вбудовані команди видаляються. Користувацькі команди/команди Plugin можуть усе ще реєструватися, якщо це налаштовано. - Поширені помилки налаштування: + Поширені збої налаштування: - - `setMyCommands failed` із `BOT_COMMANDS_TOO_MUCH` означає, що меню Telegram усе ще переповнене після обрізання; зменште кількість команд Plugin/Skills/користувацьких команд або вимкніть `channels.telegram.commands.native`. - - Помилка `deleteWebhook`, `deleteMyCommands` або `setMyCommands` із `404: Not Found`, коли прямі команди Bot API через curl працюють, може означати, що `channels.telegram.apiRoot` було задано як повну кінцеву точку `/bot`. `apiRoot` має бути лише коренем Bot API, а `openclaw doctor --fix` видаляє випадковий кінцевий `/bot`. + - `setMyCommands failed` з `BOT_COMMANDS_TOO_MUCH` означає, що меню Telegram усе ще переповнене після обрізання; зменште кількість команд Plugin/навичок/користувацьких команд або вимкніть `channels.telegram.commands.native`. + - Збій `deleteWebhook`, `deleteMyCommands` або `setMyCommands` із `404: Not Found`, тоді як прямі curl-команди Bot API працюють, може означати, що `channels.telegram.apiRoot` було встановлено на повний кінцевий пункт `/bot`. `apiRoot` має бути лише коренем Bot API, а `openclaw doctor --fix` видаляє випадковий кінцевий `/bot`. - `getMe returned 401` означає, що Telegram відхилив налаштований токен бота. Оновіть `botToken`, `tokenFile` або `TELEGRAM_BOT_TOKEN` поточним токеном BotFather; OpenClaw зупиняється перед опитуванням, тому це не повідомляється як збій очищення Webhook. - - `setMyCommands failed` із помилками мережі/fetch зазвичай означає, що вихідний DNS/HTTPS до `api.telegram.org` заблоковано. + - `setMyCommands failed` із помилками мережі/fetch зазвичай означає, що вихідні DNS/HTTPS-з’єднання до `api.telegram.org` заблоковані. ### Команди сполучення пристрою (Plugin `device-pair`) - Коли встановлено Plugin `device-pair`: + Коли Plugin `device-pair` встановлено: 1. `/pair` генерує код налаштування 2. вставте код у застосунок iOS - 3. `/pair pending` показує очікувані запити (включно з роллю/областями) + 3. `/pair pending` перелічує запити в очікуванні (зокрема роль/області дії) 4. схваліть запит: - `/pair approve ` для явного схвалення - - `/pair approve`, коли є лише один очікуваний запит + - `/pair approve`, коли є лише один запит в очікуванні - `/pair approve latest` для найновішого - Код налаштування містить короткочасний bootstrap-токен. Вбудована передача bootstrap зберігає токен основного вузла на `scopes: []`; будь-який переданий токен оператора залишається обмеженим `operator.approvals`, `operator.read`, `operator.talk.secrets` і `operator.write`. Перевірки областей bootstrap мають префікс ролі, тож цей allowlist оператора задовольняє лише запити оператора; неоператорські ролі все ще потребують областей під власним префіксом ролі. + Код налаштування переносить короткочасний bootstrap-токен. Вбудована передача bootstrap зберігає токен основного вузла на `scopes: []`; будь-який переданий токен оператора залишається обмеженим до `operator.approvals`, `operator.read`, `operator.talk.secrets` і `operator.write`. Перевірки bootstrap-областей дії мають префікс ролі, тому цей список дозволів оператора задовольняє лише запити оператора; неоператорським ролям усе ще потрібні області дії під власним префіксом ролі. - Якщо пристрій повторює спробу зі зміненими даними автентифікації (наприклад, роль/області/публічний ключ), попередній очікуваний запит замінюється, а новий запит використовує інший `requestId`. Повторно виконайте `/pair pending` перед схваленням. + Якщо пристрій повторює спробу зі зміненими деталями авторизації (наприклад, роль/області дії/публічний ключ), попередній запит в очікуванні замінюється, а новий запит використовує інший `requestId`. Повторно виконайте `/pair pending` перед схваленням. Докладніше: [Сполучення](/uk/channels/pairing#pair-via-telegram-recommended-for-ios). - Налаштуйте область вбудованої клавіатури: + Налаштуйте область дії вбудованої клавіатури: ```json5 { @@ -433,7 +433,7 @@ curl "https://api.telegram.org/bot/getUpdates" } ``` - Області: + Області дії: - `off` - `dm` @@ -477,24 +477,24 @@ curl "https://api.telegram.org/bot/getUpdates" Дії повідомлень каналу надають зручні псевдоніми (`send`, `react`, `delete`, `edit`, `sticker`, `sticker-search`, `topic-create`). - Елементи керування доступом: + Керування обмеженнями: - `channels.telegram.actions.sendMessage` - `channels.telegram.actions.deleteMessage` - `channels.telegram.actions.reactions` - `channels.telegram.actions.sticker` (за замовчуванням: вимкнено) - Примітка: `edit` і `topic-create` наразі ввімкнено за замовчуванням, і вони не мають окремих перемикачів `channels.telegram.actions.*`. - Надсилання під час виконання використовують активний знімок конфігурації/секретів (запуск/перезавантаження), тому шляхи дій не виконують ситуативне повторне розв’язання SecretRef для кожного надсилання. + Примітка: `edit` і `topic-create` наразі ввімкнені за замовчуванням і не мають окремих перемикачів `channels.telegram.actions.*`. + Надсилання під час виконання використовує активний знімок конфігурації/секретів (запуск/перезавантаження), тому шляхи дій не виконують ad-hoc повторне розв’язання SecretRef для кожного надсилання. - Семантика видалення реакції: [/tools/reactions](/uk/tools/reactions) + Семантика видалення реакцій: [/tools/reactions](/uk/tools/reactions) - - Telegram підтримує явні теги гілкування відповідей у згенерованому виводі: + + Telegram підтримує явні теги гілок відповідей у згенерованому виводі: - - `[[reply_to_current]]` відповідає на повідомлення, що ініціювало дію + - `[[reply_to_current]]` відповідає на повідомлення, яке спричинило запуск - `[[reply_to:]]` відповідає на конкретний ідентифікатор повідомлення Telegram `channels.telegram.replyToMode` керує обробкою: @@ -503,29 +503,29 @@ curl "https://api.telegram.org/bot/getUpdates" - `first` - `all` - Коли гілкування відповідей увімкнено й оригінальний текст або підпис Telegram доступний, OpenClaw автоматично включає нативний уривок цитати Telegram. Telegram обмежує нативний текст цитати 1024 кодовими одиницями UTF-16, тому довші повідомлення цитуються від початку й повертаються до звичайної відповіді, якщо Telegram відхиляє цитату. + Коли гілкування відповідей увімкнене й доступний оригінальний текст або підпис Telegram, OpenClaw автоматично включає нативний фрагмент цитати Telegram. Telegram обмежує нативний текст цитати 1024 кодовими одиницями UTF-16, тому довші повідомлення цитуються від початку й повертаються до звичайної відповіді, якщо Telegram відхиляє цитату. - Примітка: `off` вимикає неявне гілкування відповідей. Явні теги `[[reply_to_*]]` усе одно враховуються. + Примітка: `off` вимикає неявне гілкування відповідей. Явні теги `[[reply_to_*]]` усе ще враховуються. Форумні супергрупи: - - ключі сеансів теми додають `:topic:` - - відповіді та індикатор набору спрямовуються в гілку теми + - ключі сесій теми додають `:topic:` + - відповіді та індикатор набору спрямовуються до гілки теми - шлях конфігурації теми: `channels.telegram.groups..topics.` - Особливий випадок загальної теми (`threadId=1`): + Спеціальний випадок загальної теми (`threadId=1`): - - надсилання повідомлень пропускають `message_thread_id` (Telegram відхиляє `sendMessage(...thread_id=1)`) - - дії набору все ще включають `message_thread_id` + - надсилання повідомлень пропускає `message_thread_id` (Telegram відхиляє `sendMessage(...thread_id=1)`) + - дії набору тексту все ще включають `message_thread_id` - Успадкування тем: записи тем успадковують налаштування групи, якщо їх не перевизначено (`requireMention`, `allowFrom`, `skills`, `systemPrompt`, `enabled`, `groupPolicy`). - `agentId` діє лише для теми й не успадковується з типових значень групи. + Успадкування теми: записи тем успадковують налаштування групи, якщо їх не перевизначено (`requireMention`, `allowFrom`, `skills`, `systemPrompt`, `enabled`, `groupPolicy`). + `agentId` застосовується лише до теми й не успадковується з типових значень групи. - **Маршрутизація агента для окремої теми**: кожна тема може маршрутизуватися до іншого агента через встановлення `agentId` у конфігурації теми. Це дає кожній темі власний ізольований робочий простір, пам’ять і сеанс. Приклад: + **Маршрутизація агента для окремої теми**: кожна тема може маршрутизуватися до іншого агента через налаштування `agentId` у конфігурації теми. Це надає кожній темі власний ізольований робочий простір, пам’ять і сесію. Приклад: ```json5 { @@ -545,13 +545,13 @@ curl "https://api.telegram.org/bot/getUpdates" } ``` - Кожна тема тоді має власний ключ сеансу: `agent:zu:telegram:group:-1001234567890:topic:3` + Кожна тема потім має власний ключ сесії: `agent:zu:telegram:group:-1001234567890:topic:3` - **Постійне прив’язування теми ACP**: теми форуму можуть закріплювати сеанси harness ACP через типізовані прив’язування ACP верхнього рівня (`bindings[]` з `type: "acp"` і `match.channel: "telegram"`, `peer.kind: "group"` та ідентифікатором із кваліфікатором теми на кшталт `-1001234567890:topic:42`). Наразі обмежено темами форуму в групах/супергрупах. Див. [Агенти ACP](/uk/tools/acp-agents). + **Постійне прив’язування тем ACP**: теми форуму можуть закріплювати сесії ACP harness через типізовані ACP-прив’язки верхнього рівня (`bindings[]` з `type: "acp"` і `match.channel: "telegram"`, `peer.kind: "group"` та ідентифікатором із кваліфікатором теми на кшталт `-1001234567890:topic:42`). Наразі обмежено темами форуму в групах/супергрупах. Див. [Агенти ACP](/uk/tools/acp-agents). - **Прив’язаний до гілки spawn ACP із чату**: `/acp spawn --thread here|auto` прив’язує поточну тему до нового сеансу ACP; подальші повідомлення маршрутизуються туди напряму. OpenClaw закріплює підтвердження spawn у темі. Потребує `channels.telegram.threadBindings.spawnAcpSessions=true`. + **Запуск ACP, прив’язаний до гілки, з чату**: `/acp spawn --thread here|auto` прив’язує поточну тему до нової сесії ACP; подальші повідомлення маршрутизуються туди напряму. OpenClaw закріплює підтвердження запуску в темі. Потребує `channels.telegram.threadBindings.spawnAcpSessions=true`. - Контекст шаблону надає `MessageThreadId` і `IsForum`. DM-чати з `message_thread_id` зберігають маршрутизацію DM, але використовують ключі сеансів із підтримкою гілок. + Контекст шаблону надає `MessageThreadId` та `IsForum`. Чати DM з `message_thread_id` зберігають маршрутизацію DM, але використовують ключі сесій з урахуванням гілок. @@ -564,7 +564,7 @@ curl "https://api.telegram.org/bot/getUpdates" - тег `[[audio_as_voice]]` у відповіді агента примусово надсилає голосову нотатку - транскрипти вхідних голосових нотаток оформлюються як машинно згенерований, ненадійний текст у контексті агента; виявлення згадок усе ще використовує сирий - транскрипт, тож голосові повідомлення з вимогою згадки продовжують працювати. + транскрипт, тому голосові повідомлення, обмежені згадками, продовжують працювати. Приклад дії повідомлення: @@ -616,7 +616,7 @@ curl "https://api.telegram.org/bot/getUpdates" - `~/.openclaw/telegram/sticker-cache.json` - Стікери описуються один раз (коли можливо) і кешуються, щоб зменшити повторні vision-виклики. + Стікери описуються один раз (коли можливо) і кешуються, щоб зменшити повторні виклики vision. Увімкніть дії зі стікерами: @@ -670,30 +670,30 @@ curl "https://api.telegram.org/bot/getUpdates" Примітки: - - `own` означає реакції користувачів лише на повідомлення, надіслані ботом (за можливості через кеш надісланих повідомлень). - - Події реакцій усе одно враховують засоби контролю доступу Telegram (`dmPolicy`, `allowFrom`, `groupPolicy`, `groupAllowFrom`); неавторизованих відправників відкидають. - - Telegram не надає ідентифікатори гілок у оновленнях реакцій. - - групи нефорумного типу спрямовуються до сеансу групового чату - - форумні групи спрямовуються до сеансу загальної теми групи (`:topic:1`), а не до точної початкової теми + - `own` означає лише реакції користувача на повідомлення, надіслані ботом (найкраща можлива спроба через кеш надісланих повідомлень). + - Події реакцій усе ще дотримуються контролів доступу Telegram (`dmPolicy`, `allowFrom`, `groupPolicy`, `groupAllowFrom`); неавторизовані відправники відкидаються. + - Telegram не надає ідентифікатори гілок в оновленнях реакцій. + - групи без форуму спрямовуються до сесії групового чату + - форумні групи спрямовуються до сесії загальної теми групи (`:topic:1`), а не до точної початкової теми `allowed_updates` для polling/webhook автоматично включає `message_reaction`. - - `ackReaction` надсилає emoji підтвердження, поки OpenClaw обробляє вхідне повідомлення. + + `ackReaction` надсилає емодзі підтвердження, поки OpenClaw обробляє вхідне повідомлення. - Порядок розв’язання: + Порядок визначення: - `channels.telegram.accounts..ackReaction` - `channels.telegram.ackReaction` - `messages.ackReaction` - - резервний emoji ідентичності агента (`agents.list[].identity.emoji`, інакше "👀") + - резервний емодзі ідентичності агента (`agents.list[].identity.emoji`, інакше "👀") Примітки: - - Telegram очікує Unicode emoji (наприклад "👀"). - - Використовуйте `""`, щоб вимкнути реакцію для каналу або облікового запису. + - Telegram очікує unicode-емодзі (наприклад, "👀"). + - Використайте `""`, щоб вимкнути реакцію для каналу або облікового запису. @@ -720,30 +720,30 @@ curl "https://api.telegram.org/bot/getUpdates" - Типово використовується long polling. Для режиму webhook задайте `channels.telegram.webhookUrl` і `channels.telegram.webhookSecret`; необов’язково `webhookPath`, `webhookHost`, `webhookPort` (типові значення `/telegram-webhook`, `127.0.0.1`, `8787`). + Типово використовується long polling. Для режиму webhook задайте `channels.telegram.webhookUrl` і `channels.telegram.webhookSecret`; необов’язкові `webhookPath`, `webhookHost`, `webhookPort` (типово `/telegram-webhook`, `127.0.0.1`, `8787`). - Локальний слухач прив’язується до `127.0.0.1:8787`. Для публічного входу або поставте reverse proxy перед локальним портом, або свідомо задайте `webhookHost: "0.0.0.0"`. + Локальний слухач прив’язується до `127.0.0.1:8787`. Для публічного входу або поставте reverse proxy перед локальним портом, або навмисно задайте `webhookHost: "0.0.0.0"`. - Режим webhook перевіряє захисти запиту, секретний токен Telegram і JSON-тіло перед поверненням `200` до Telegram. - Потім OpenClaw обробляє оновлення асинхронно через ті самі смуги бота для кожного чату/теми, що й long polling, тому повільні ходи агента не затримують ACK доставки Telegram. + Режим Webhook перевіряє захисти запиту, секретний токен Telegram і JSON-тіло перед поверненням `200` до Telegram. + Потім OpenClaw обробляє оновлення асинхронно через ті самі bot lanes для кожного чату/теми, що використовуються long polling, тому повільні ходи агента не утримують ACK доставки Telegram. - + - Типове значення `channels.telegram.textChunkLimit` — 4000. - - `channels.telegram.chunkMode="newline"` надає перевагу межам абзаців (порожнім рядкам) перед розбиттям за довжиною. + - `channels.telegram.chunkMode="newline"` надає перевагу межам абзаців (порожнім рядкам) перед розділенням за довжиною. - `channels.telegram.mediaMaxMb` (типово 100) обмежує розмір вхідних і вихідних медіа Telegram. - - `channels.telegram.timeoutSeconds` перевизначає таймаут клієнта Telegram API (якщо не задано, застосовується типове значення grammY). - - Типове значення `channels.telegram.pollingStallThresholdMs` — `120000`; налаштовуйте в межах від `30000` до `600000` лише для хибнопозитивних перезапусків через зависання polling. + - `channels.telegram.timeoutSeconds` перевизначає timeout клієнта Telegram API (якщо не задано, застосовується типове значення grammY). + - `channels.telegram.pollingStallThresholdMs` типово дорівнює `120000`; налаштовуйте в межах від `30000` до `600000` лише для хибнопозитивних перезапусків через зупинку polling. - Історія контексту групи використовує `channels.telegram.historyLimit` або `messages.groupChat.historyLimit` (типово 50); `0` вимикає. - - Додатковий контекст відповіді/цитати/пересилання наразі передається як отримано. - - Allowlist Telegram насамперед обмежують, хто може запускати агента, а не є повною межею редагування додаткового контексту. + - Додатковий контекст відповіді/цитати/пересилання наразі передається як отриманий. + - Списки дозволених Telegram передусім обмежують, хто може запускати агента, а не є повною межею редагування додаткового контексту. - Елементи керування історією DM: - `channels.telegram.dmHistoryLimit` - `channels.telegram.dms[""].historyLimit` - - Конфігурація `channels.telegram.retry` застосовується до допоміжних засобів надсилання Telegram (CLI/інструменти/дії) для відновлюваних вихідних помилок API. Доставка фінальної відповіді для вхідних повідомлень також використовує обмежену безпечну повторну спробу надсилання для збоїв Telegram до підключення, але не повторює неоднозначні мережеві оболонки після надсилання, які можуть дублювати видимі повідомлення. + - Конфігурація `channels.telegram.retry` застосовується до helper-ів надсилання Telegram (CLI/tools/actions) для відновлюваних вихідних помилок API. Доставка фінальної відповіді для вхідних повідомлень також використовує обмежену безпечну повторну спробу надсилання для збоїв Telegram до підключення, але не повторює неоднозначні мережеві конверти після надсилання, які можуть дублювати видимі повідомлення. - Ціль надсилання CLI може бути числовим ID чату або іменем користувача: + Ціль надсилання CLI може бути числовим ідентифікатором чату або іменем користувача: ```bash openclaw message send --channel telegram --target 123456789 --message "hi" @@ -765,13 +765,13 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \ - `--poll-duration-seconds` (5-600) - `--poll-anonymous` - `--poll-public` - - `--thread-id` для форумних тем (або використовуйте ціль `:topic:`) + - `--thread-id` для форумних тем (або використайте ціль `:topic:`) Надсилання Telegram також підтримує: - - `--presentation` з блоками `buttons` для inline keyboards, коли це дозволяє `channels.telegram.capabilities.inlineButtons` - - `--pin` або `--delivery '{"pin":true}'` для запиту закріпленої доставки, коли бот може закріплювати в цьому чаті - - `--force-document` для надсилання вихідних зображень і GIF як документів замість стиснених завантажень фото або анімованих медіа + - `--presentation` з блоками `buttons` для inline-клавіатур, коли `channels.telegram.capabilities.inlineButtons` це дозволяє + - `--pin` або `--delivery '{"pin":true}'`, щоб запросити закріплену доставку, коли бот може закріплювати в цьому чаті + - `--force-document`, щоб надсилати вихідні зображення та GIF як документи замість стиснених фото або завантажень анімованих медіа Обмеження дій: @@ -781,20 +781,20 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \ - Telegram підтримує підтвердження exec у DM затверджувачів і може необов’язково публікувати запити в початковому чаті або темі. Затверджувачі мають бути числовими ID користувачів Telegram. + Telegram підтримує підтвердження exec у DM затверджувачів і може необов’язково публікувати запити в початковому чаті або темі. Затверджувачі мають бути числовими ідентифікаторами користувачів Telegram. Шлях конфігурації: - - `channels.telegram.execApprovals.enabled` (автоматично вмикається, коли можна розв’язати принаймні одного затверджувача) - - `channels.telegram.execApprovals.approvers` (повертається до числових ID власників із `commands.ownerAllowFrom`) + - `channels.telegram.execApprovals.enabled` (автоматично вмикається, коли можна визначити принаймні одного затверджувача) + - `channels.telegram.execApprovals.approvers` (повертається до числових ідентифікаторів власників із `commands.ownerAllowFrom`) - `channels.telegram.execApprovals.target`: `dm` (типово) | `channel` | `both` - `agentFilter`, `sessionFilter` - `channels.telegram.allowFrom`, `groupAllowFrom` і `defaultTo` контролюють, хто може говорити з ботом і куди він надсилає звичайні відповіді. Вони не роблять когось затверджувачем exec. Перше схвалене сполучення DM ініціалізує `commands.ownerAllowFrom`, коли власника команд ще немає, тому налаштування з одним власником усе одно працює без дублювання ID у `execApprovals.approvers`. + `channels.telegram.allowFrom`, `groupAllowFrom` і `defaultTo` керують тим, хто може спілкуватися з ботом і куди він надсилає звичайні відповіді. Вони не роблять когось затверджувачем exec. Перше затверджене спарення DM ініціалізує `commands.ownerAllowFrom`, коли власника команд ще немає, тож налаштування з одним власником усе ще працює без дублювання ідентифікаторів у `execApprovals.approvers`. - Доставка в канал показує текст команди в чаті; вмикайте `channel` або `both` лише в довірених групах/темах. Коли запит потрапляє у форумну тему, OpenClaw зберігає тему для запиту підтвердження та подальшого повідомлення. Підтвердження exec типово спливають через 30 хвилин. + Доставка в канал показує текст команди в чаті; вмикайте `channel` або `both` лише в довірених групах/темах. Коли запит потрапляє у форумну тему, OpenClaw зберігає тему для запиту підтвердження та подальшої відповіді. Підтвердження exec типово завершуються через 30 хвилин. - Inline-кнопки підтвердження також потребують, щоб `channels.telegram.capabilities.inlineButtons` дозволяв цільову поверхню (`dm`, `group` або `all`). ID підтверджень із префіксом `plugin:` розв’язуються через підтвердження plugin; інші спочатку розв’язуються через підтвердження exec. + Inline-кнопки підтвердження також потребують, щоб `channels.telegram.capabilities.inlineButtons` дозволяв цільову поверхню (`dm`, `group` або `all`). Ідентифікатори підтвердження з префіксом `plugin:` визначаються через підтвердження plugin; інші спершу визначаються через підтвердження exec. Див. [Підтвердження exec](/uk/tools/exec-approvals). @@ -805,12 +805,12 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \ Коли агент стикається з помилкою доставки або провайдера, Telegram може або відповісти текстом помилки, або придушити її. Цю поведінку контролюють два ключі конфігурації: -| Ключ | Значення | Типово | Опис | -| ----------------------------------- | ----------------- | ------- | ---------------------------------------------------------------------------------------------- | -| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` надсилає дружнє повідомлення про помилку в чат. `silent` повністю придушує відповіді про помилки. | -| `channels.telegram.errorCooldownMs` | number (ms) | `60000` | Мінімальний час між відповідями про помилки до того самого чату. Запобігає спаму помилками під час збоїв. | +| Ключ | Значення | Типово | Опис | +| ----------------------------------- | ----------------- | ------- | ------------------------------------------------------------------------------------------------ | +| `channels.telegram.errorPolicy` | `reply`, `silent` | `reply` | `reply` надсилає дружнє повідомлення про помилку до чату. `silent` повністю придушує відповіді про помилки. | +| `channels.telegram.errorCooldownMs` | число (мс) | `60000` | Мінімальний час між відповідями про помилки до того самого чату. Запобігає спаму помилок під час збоїв. | -Підтримуються перевизначення для кожного облікового запису, групи й теми (таке саме наслідування, як для інших ключів конфігурації Telegram). +Підтримуються перевизначення для кожного облікового запису, групи та теми (те саме успадкування, що й для інших ключів конфігурації Telegram). ```json5 { @@ -835,50 +835,50 @@ openclaw message poll --channel telegram --target -1001234567890:topic:42 \ - Якщо `requireMention=false`, режим приватності Telegram має дозволяти повну видимість. - BotFather: `/setprivacy` -> Disable - - потім видаліть і повторно додайте бота до групи + - потім видаліть і знову додайте бота до групи - `openclaw channels status` попереджає, коли конфігурація очікує групові повідомлення без згадки. - - `openclaw channels status --probe` може перевірити явні числові ID груп; wildcard `"*"` не можна перевірити на членство. - - швидкий тест сеансу: `/activation always`. + - `openclaw channels status --probe` може перевіряти явні числові ідентифікатори груп; wildcard `"*"` не можна перевірити на членство. + - швидкий тест сесії: `/activation always`. - + - коли існує `channels.telegram.groups`, група має бути в списку (або включати `"*"`) - перевірте членство бота в групі - - перегляньте журнали: `openclaw logs --follow` для причин пропуску + - перегляньте логи: `openclaw logs --follow` для причин пропуску - - авторизуйте ідентичність свого відправника (сполучення та/або числовий `allowFrom`) - - авторизація команд усе одно застосовується, навіть коли політика групи — `open` - - `setMyCommands failed` з `BOT_COMMANDS_TOO_MUCH` означає, що нативне меню має забагато записів; зменште кількість команд plugin/skill/користувацьких команд або вимкніть нативні меню - - Виклики запуску `deleteMyCommands` / `setMyCommands` обмежені й повторюються один раз через транспортний fallback Telegram у разі таймауту запиту. Постійні мережеві/fetch-помилки зазвичай вказують на проблеми досяжності DNS/HTTPS до `api.telegram.org` + - авторизуйте свою ідентичність відправника (спарення та/або числовий `allowFrom`) + - авторизація команд усе ще застосовується, навіть коли політика групи — `open` + - `setMyCommands failed` з `BOT_COMMANDS_TOO_MUCH` означає, що в нативному меню забагато записів; зменште кількість команд plugin/skill/custom або вимкніть нативні меню + - стартові виклики `deleteMyCommands` / `setMyCommands` обмежені та повторюються один раз через транспортний fallback Telegram у разі timeout запиту. Постійні помилки мережі/fetch зазвичай вказують на проблеми доступності DNS/HTTPS до `api.telegram.org` - `getMe returned 401` — це збій автентифікації Telegram для налаштованого токена бота. - - Повторно скопіюйте або згенеруйте токен бота в BotFather, потім оновіть `channels.telegram.botToken`, `channels.telegram.tokenFile`, `channels.telegram.accounts..botToken` або `TELEGRAM_BOT_TOKEN` для типового облікового запису. - - `deleteWebhook 401 Unauthorized` під час запуску також є збоєм автентифікації; трактування цього як "webhook не існує" лише відклало б той самий збій поганого токена до пізніших викликів API. - - Якщо `deleteWebhook` завершується помилкою через тимчасову мережеву помилку під час запуску polling, OpenClaw перевіряє `getWebhookInfo`; коли Telegram повідомляє про порожній URL webhook, polling продовжується, бо очищення вже виконано. + - Скопіюйте повторно або згенеруйте заново токен бота в BotFather, а потім оновіть `channels.telegram.botToken`, `channels.telegram.tokenFile`, `channels.telegram.accounts..botToken` або `TELEGRAM_BOT_TOKEN` для типового облікового запису. + - `deleteWebhook 401 Unauthorized` під час запуску також є збоєм автентифікації; трактування цього як "webhook не існує" лише відклало б той самий збій через поганий токен до пізніших викликів API. + - Якщо `deleteWebhook` завершується з тимчасовою мережевою помилкою під час запуску polling, OpenClaw перевіряє `getWebhookInfo`; коли Telegram повідомляє порожній URL webhook, polling продовжується, бо cleanup уже задоволений. - - Node 22+ + користувацький fetch/proxy може спричиняти негайне переривання, якщо типи AbortSignal не збігаються. - - Деякі хости спочатку розв’язують `api.telegram.org` в IPv6; несправний вихідний IPv6-трафік може спричиняти періодичні збої Telegram API. - - Якщо журнали містять `TypeError: fetch failed` або `Network request for 'getUpdates' failed!`, OpenClaw тепер повторює ці запити як відновлювані мережеві помилки. - - Якщо журнали містять `Polling stall detected`, OpenClaw перезапускає опитування та перебудовує Telegram transport після 120 секунд без завершеної перевірки життєздатності long-poll за замовчуванням. - - `openclaw channels status --probe` і `openclaw doctor` попереджають, коли запущений обліковий запис з опитуванням не завершив `getUpdates` після пільгового періоду запуску або коли його остання успішна активність polling transport застаріла. - - Збільшуйте `channels.telegram.pollingStallThresholdMs` лише тоді, коли довготривалі виклики `getUpdates` справні, але ваш хост усе ще повідомляє про хибні перезапуски через зависання опитування. Постійні зависання зазвичай вказують на проблеми proxy, DNS, IPv6 або вихідного TLS-трафіку між хостом і `api.telegram.org`. - - Telegram також враховує env proxy процесу для Bot API transport, зокрема `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY` та їхні варіанти в нижньому регістрі. `NO_PROXY` / `no_proxy` усе ще можуть обходити `api.telegram.org`. - - Якщо керований proxy OpenClaw налаштовано через `OPENCLAW_PROXY_URL` для сервісного середовища і стандартні env proxy відсутні, Telegram також використовує цей URL для Bot API transport. - - На VPS-хостах із нестабільним прямим вихідним трафіком/TLS спрямовуйте виклики Telegram API через `channels.telegram.proxy`: + - Node 22+ + власний fetch/проксі можуть спричинити негайне переривання, якщо типи AbortSignal не збігаються. + - Деякі хости спершу резолвлять `api.telegram.org` в IPv6; зламаний вихідний IPv6-трафік може спричиняти періодичні збої Telegram API. + - Якщо журнали містять `TypeError: fetch failed` або `Network request for 'getUpdates' failed!`, OpenClaw тепер повторює ці операції як відновлювані мережеві помилки. + - Якщо журнали містять `Polling stall detected`, OpenClaw перезапускає polling і перебудовує транспорт Telegram після 120 секунд без завершеної перевірки життєздатності long-poll за замовчуванням. + - `openclaw channels status --probe` і `openclaw doctor` попереджають, коли запущений polling-акаунт не завершив `getUpdates` після пільгового періоду запуску, коли запущений webhook-акаунт не завершив `setWebhook` після пільгового періоду запуску, або коли остання успішна активність polling-транспорту застаріла. + - Збільшуйте `channels.telegram.pollingStallThresholdMs` лише тоді, коли довготривалі виклики `getUpdates` справні, але ваш хост усе ще повідомляє про хибні перезапуски через зупинку polling. Постійні зупинки зазвичай вказують на проблеми з проксі, DNS, IPv6 або вихідним TLS між хостом і `api.telegram.org`. + - Telegram також враховує process proxy env для транспорту Bot API, зокрема `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY` та їхні варіанти в нижньому регістрі. `NO_PROXY` / `no_proxy` усе ще можуть обходити `api.telegram.org`. + - Якщо керований проксі OpenClaw налаштовано через `OPENCLAW_PROXY_URL` для сервісного середовища й стандартний proxy env відсутній, Telegram також використовує цю URL-адресу для транспорту Bot API. + - На VPS-хостах із нестабільним прямим вихідним трафіком/TLS маршрутизуйте виклики Telegram API через `channels.telegram.proxy`: ```yaml channels: @@ -886,8 +886,8 @@ channels: proxy: socks5://:@proxy-host:1080 ``` - - Node 22+ за замовчуванням використовує `autoSelectFamily=true` (крім WSL2) і `dnsResultOrder=ipv4first`. - - Якщо ваш хост є WSL2 або явно краще працює з поведінкою лише IPv4, примусово задайте вибір сімейства: + - Node 22+ за замовчуванням використовує `autoSelectFamily=true` (окрім WSL2) і `dnsResultOrder=ipv4first`. + - Якщо ваш хост — WSL2 або явно краще працює лише з IPv4, примусово задайте вибір сімейства: ```yaml channels: @@ -896,10 +896,10 @@ channels: autoSelectFamily: false ``` - - Відповіді benchmark-діапазону RFC 2544 (`198.18.0.0/15`) уже дозволені + - Відповіді з benchmark-діапазону RFC 2544 (`198.18.0.0/15`) уже дозволені для завантажень медіа Telegram за замовчуванням. Якщо довірений fake-IP або - transparent proxy переписує `api.telegram.org` на якусь іншу - приватну/внутрішню/спеціальну адресу під час завантаження медіа, ви можете + прозорий проксі переписує `api.telegram.org` на якусь іншу + приватну/внутрішню/спеціального призначення адресу під час завантажень медіа, ви можете увімкнути обхід лише для Telegram: ```yaml @@ -909,25 +909,25 @@ channels: dangerouslyAllowPrivateNetwork: true ``` - - Така сама опція доступна для кожного облікового запису в + - Така сама можливість увімкнення доступна для кожного акаунта за адресою `channels.telegram.accounts..network.dangerouslyAllowPrivateNetwork`. - - Якщо ваш proxy розв’язує хости медіа Telegram у `198.18.x.x`, спочатку залиште + - Якщо ваш проксі резолвить медіахости Telegram у `198.18.x.x`, спершу залиште небезпечний прапорець вимкненим. Медіа Telegram уже дозволяє benchmark-діапазон RFC 2544 за замовчуванням. - `channels.telegram.network.dangerouslyAllowPrivateNetwork` послаблює захист Telegram - media SSRF. Використовуйте це лише для довірених, контрольованих оператором proxy + `channels.telegram.network.dangerouslyAllowPrivateNetwork` послаблює захист медіа Telegram + від SSRF. Використовуйте його лише для довірених, контрольованих оператором проксі- середовищ, як-от маршрутизація fake-IP у Clash, Mihomo або Surge, коли вони - синтезують приватні або спеціальні відповіді поза benchmark-діапазоном - RFC 2544. Залишайте це вимкненим для звичайного доступу Telegram через публічний інтернет. + синтезують приватні або спеціального призначення відповіді поза benchmark- + діапазоном RFC 2544. Залишайте його вимкненим для звичайного доступу Telegram через публічний інтернет. - Перевизначення середовища (тимчасові): - `OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1` - `OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1` - `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first` - - Перевірте відповіді DNS: + - Перевірте DNS-відповіді: ```bash dig +short api.telegram.org A @@ -937,23 +937,23 @@ dig +short api.telegram.org AAAA -Додаткова допомога: [Усунення несправностей каналів](/uk/channels/troubleshooting). +Додаткова допомога: [усунення несправностей каналів](/uk/channels/troubleshooting). ## Довідник конфігурації -Основний довідник: [Довідник конфігурації - Telegram](/uk/gateway/config-channels#telegram). +Основний довідник: [довідник конфігурації - Telegram](/uk/gateway/config-channels#telegram). -- запуск/auth: `enabled`, `botToken`, `tokenFile`, `accounts.*` (`tokenFile` має вказувати на звичайний файл; symlinks відхиляються) -- керування доступом: `dmPolicy`, `allowFrom`, `groupPolicy`, `groupAllowFrom`, `groups`, `groups.*.topics.*`, top-level `bindings[]` (`type: "acp"`) -- схвалення exec: `execApprovals`, `accounts.*.execApprovals` +- запуск/автентифікація: `enabled`, `botToken`, `tokenFile`, `accounts.*` (`tokenFile` має вказувати на звичайний файл; символічні посилання відхиляються) +- контроль доступу: `dmPolicy`, `allowFrom`, `groupPolicy`, `groupAllowFrom`, `groups`, `groups.*.topics.*`, верхньорівневий `bindings[]` (`type: "acp"`) +- схвалення виконання: `execApprovals`, `accounts.*.execApprovals` - команда/меню: `commands.native`, `commands.nativeSkills`, `customCommands` -- потоки/відповіді: `replyToMode` -- streaming: `streaming` (preview), `streaming.preview.toolProgress`, `blockStreaming` +- ланцюжки/відповіді: `replyToMode` +- streaming: `streaming` (попередній перегляд), `streaming.preview.toolProgress`, `blockStreaming` - форматування/доставка: `textChunkLimit`, `chunkMode`, `linkPreview`, `responsePrefix` - медіа/мережа: `mediaMaxMb`, `timeoutSeconds`, `pollingStallThresholdMs`, `retry`, `network.autoSelectFamily`, `network.dangerouslyAllowPrivateNetwork`, `proxy` -- користувацький корінь API: `apiRoot` (лише корінь Bot API; не включайте `/bot`) +- власний корінь API: `apiRoot` (лише корінь Bot API; не включайте `/bot`) - webhook: `webhookUrl`, `webhookSecret`, `webhookPath`, `webhookHost` - дії/можливості: `capabilities.inlineButtons`, `actions.sendMessage|editMessage|deleteMessage|reactions|sticker` - реакції: `reactionNotifications`, `reactionLevel` @@ -963,14 +963,14 @@ dig +short api.telegram.org AAAA -Пріоритетність кількох облікових записів: коли налаштовано два або більше ID облікових записів, задайте `channels.telegram.defaultAccount` (або включіть `channels.telegram.accounts.default`), щоб зробити маршрутизацію за замовчуванням явною. Інакше OpenClaw повертається до першого нормалізованого ID облікового запису, а `openclaw doctor` попереджає. Іменовані облікові записи успадковують `channels.telegram.allowFrom` / `groupAllowFrom`, але не значення `accounts.default.*`. +Пріоритет кількох акаунтів: коли налаштовано два або більше ID акаунтів, задайте `channels.telegram.defaultAccount` (або включіть `channels.telegram.accounts.default`), щоб зробити маршрутизацію за замовчуванням явною. Інакше OpenClaw повертається до першого нормалізованого ID акаунта, а `openclaw doctor` попереджає. Іменовані акаунти успадковують `channels.telegram.allowFrom` / `groupAllowFrom`, але не значення `accounts.default.*`. ## Пов’язане - Зв’яжіть користувача Telegram із gateway. + Спаруйте користувача Telegram із Gateway. Поведінка allowlist для груп і тем. @@ -985,6 +985,6 @@ dig +short api.telegram.org AAAA Зіставляйте групи й теми з агентами. - Діагностика між каналами. + Міжканальна діагностика. diff --git a/docs/uk/ci.md b/docs/uk/ci.md index 601cde400..b4cf89f3a 100644 --- a/docs/uk/ci.md +++ b/docs/uk/ci.md @@ -1,102 +1,104 @@ --- read_when: - - Вам потрібно зрозуміти, чому завдання CI запустилося або не запустилося - - Ви налагоджуєте перевірки GitHub Actions, що завершуються помилкою -summary: Граф завдань CI, гейти області охоплення та локальні еквіваленти команд + - Потрібно зрозуміти, чому завдання CI запустилося або не запустилося + - Ви налагоджуєте перевірки GitHub Actions, які не проходять +summary: Граф завдань CI, гейти області змін і локальні еквіваленти команд title: CI-конвеєр x-i18n: - generated_at: "2026-04-29T13:37:09Z" + generated_at: "2026-04-29T14:47:31Z" model: gpt-5.5 provider: openai - source_hash: 706dfe3a1b92a4e561ec76d8a6f192ad5d821f4c21ab546d28a9a1f6d4b962cb + source_hash: b3c51dff5db84e2d11f98b363a55d0d21309eeb9fce00fe90a8a9013c9c80385 source_path: ci.md workflow: 16 --- -CI запускається для кожного push до `main` і кожного pull request. Він використовує розумне обмеження області, щоб пропускати витратні завдання, коли змінено лише непов’язані ділянки. Ручні запуски `workflow_dispatch` навмисно обходять розумне обмеження області й розгортають повний звичайний граф CI для release candidates або широкої валідації, а Android-напрями вмикаються окремо через `include_android` для автономних ручних запусків. Напрями prerelease для Plugin, призначені лише для релізів, містяться в окремому workflow `Plugin Prerelease` і запускаються тільки з `Full Release Validation` або явного ручного dispatch. +CI запускається для кожного push до `main` і кожного pull request. Вона використовує розумне обмеження області, щоб пропускати дорогі завдання, коли змінилися лише непов’язані ділянки. Ручні запуски `workflow_dispatch` навмисно обходять розумне обмеження області та розгортають повний звичайний граф CI для кандидатів на реліз або широкої валідації, а Android-лінії вмикаються через `include_android` для окремих ручних запусків. Релізні лінії попереднього релізу plugin розміщені в окремому workflow `Plugin Prerelease` і запускаються лише з `Full Release Validation` або явного ручного dispatch. -Шард `check-dependencies` запускає `pnpm deadcode:dependencies`, production-прохід Knip лише для залежностей, закріплений на останній версії Knip, яку використовує цей скрипт, із вимкненим мінімальним віком релізу pnpm для встановлення `dlx`. Він також запускає `pnpm deadcode:unused-files`, який порівнює production-знахідки Knip щодо невикористаних файлів із `scripts/deadcode-unused-files.allowlist.mjs`. Цей запобіжник падає, коли PR додає новий неперевірений невикористаний файл або залишає застарілий запис allowlist після очищення, водночас зберігаючи навмисні поверхні динамічних plugin, згенеровані, build, live-test і package bridge, які Knip не може статично розв’язати. +Шард `check-dependencies` запускає `pnpm deadcode:dependencies`, виробничий прохід Knip лише для залежностей, прив’язаний до останньої версії Knip, яку використовує цей script, з вимкненим мінімальним віком релізу pnpm для встановлення `dlx`. Він також запускає `pnpm deadcode:unused-files`, який порівнює виробничі знахідки Knip щодо невикористаних файлів із `scripts/deadcode-unused-files.allowlist.mjs`. Цей запобіжник завершується помилкою, коли PR додає новий непереглянутий невикористаний файл або залишає застарілий запис allowlist після очищення, водночас зберігаючи навмисні поверхні динамічних plugin, згенерованих артефактів, збірки, live-test і package bridge, які Knip не може статично розв’язати. -`Full Release Validation` — це ручний парасольковий workflow для «запустити все +`Full Release Validation` — це ручний umbrella workflow для «запустити все перед релізом». Він приймає branch, tag або повний commit SHA, dispatch-ить -ручний workflow `CI` з цією ціллю, dispatch-ить `Plugin Prerelease` для -release-only доказів plugin/package/static/Docker і dispatch-ить +ручний workflow `CI` із цією ціллю, dispatch-ить `Plugin Prerelease` для +релізного proof plugin/package/static/Docker, а також dispatch-ить `OpenClaw Release Checks` для install smoke, package acceptance, Docker release-path suites, live/E2E, OpenWebUI, QA Lab parity, Matrix і Telegram -напрямів. Він також може запускати post-publish workflow `NPM Telegram Beta E2E`, коли надано -published package spec. `release_profile=minimum|stable|full` керує шириною live/provider, -яку передають у release checks: `minimum` залишає найшвидші критичні для релізу напрями OpenAI/core, -`stable` додає стабільний набір provider/backend, а -`full` запускає широку advisory provider/media matrix. Парасолька записує -ids запущених дочірніх run, а фінальне завдання `Verify full validation` повторно перевіряє -поточні conclusions дочірніх run і додає таблиці найповільніших завдань для кожного дочірнього -run. Якщо дочірній workflow перезапущено і він став green, перезапустіть лише батьківське -завдання verifier, щоб оновити результат парасольки й підсумок часу. +ліній. Він також може запускати post-publish workflow `NPM Telegram Beta E2E`, коли +надано специфікацію опублікованого package. `release_profile=minimum|stable|full` керує широтою live/provider, +яка передається в release checks: `minimum` зберігає найшвидші OpenAI/core +критичні для релізу лінії, `stable` додає стабільний набір provider/backend, а +`full` запускає широку advisory-матрицю provider/media. Umbrella записує +ідентифікатори запущених дочірніх run, а фінальний job `Verify full validation` повторно перевіряє +поточні висновки дочірніх run і додає таблиці найповільніших job для кожного дочірнього +run. Якщо дочірній workflow перезапущено й він став green, перезапустіть лише батьківський +verifier job, щоб оновити результат umbrella та підсумок часу. Для відновлення `Full Release Validation` і `OpenClaw Release Checks` обидва -приймають `rerun_group`. Використовуйте `all` для release candidate, `ci` лише для -звичайного повного дочірнього CI, `release-checks` для кожної release child або вужчу +приймають `rerun_group`. Використовуйте `all` для кандидата на реліз, `ci` лише для +звичайного повного дочірнього CI, `release-checks` для кожної релізної дочірньої перевірки або вужчу release group: `install-smoke`, `cross-os`, `live-e2e`, `package`, `qa`, -`qa-parity`, `qa-live` або `npm-telegram` у парасольці. Це утримує перезапуск невдалого -release box у межах після сфокусованого виправлення. +`qa-parity`, `qa-live` або `npm-telegram` в umbrella. Це утримує перезапуск невдалого +release box у межах після цільового виправлення. -Дочірній live/E2E реліз зберігає широке native-покриття `pnpm test:live`, але -запускає його як іменовані шарди (`native-live-src-agents`, +Дочірній live/E2E release зберігає широке нативне покриття `pnpm test:live`, але +запускає його як іменовані shards (`native-live-src-agents`, `native-live-src-gateway-core`, відфільтровані за provider -завдання `native-live-src-gateway-profiles`, +jobs `native-live-src-gateway-profiles`, `native-live-src-gateway-backends`, `native-live-test`, `native-live-extensions-a-k`, `native-live-extensions-l-n`, `native-live-extensions-openai`, `native-live-extensions-o-z-other`, -`native-live-extensions-xai`, розділені media audio/video шарди та -відфільтровані за provider music шарди) через `scripts/test-live-shard.mjs` замість -одного послідовного завдання. Це зберігає те саме покриття файлів, але робить повільні збої live -provider легшими для повторного запуску й діагностики. Агреговані назви шардів +`native-live-extensions-xai`, розділені media audio/video shards і +відфільтровані за provider music shards) через `scripts/test-live-shard.mjs` замість +одного serial job. Це зберігає те саме файлове покриття й водночас спрощує перезапуск і діагностику +повільних live provider failures. Агреговані імена shard `native-live-extensions-o-z`, `native-live-extensions-media` і `native-live-extensions-media-music` залишаються чинними для ручних одноразових перезапусків. -Native live media шарди запускаються в -`ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`, зібраному workflow -`Live Media Runner Image`. Цей image попередньо встановлює `ffmpeg` і -`ffprobe`; media-завдання лише перевіряють binaries перед setup. Тримайте Docker-backed +Нативні live media shards запускаються в +`ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`, який збирає +workflow `Live Media Runner Image`. Цей image попередньо встановлює `ffmpeg` і +`ffprobe`; media jobs лише перевіряють binaries перед setup. Тримайте Docker-backed live suites на звичайних Blacksmith runners, бо container jobs — неправильне місце для запуску nested Docker tests. -Docker-backed live model/backend шарди використовують окремий спільний +Docker-backed live model/backend shards використовують окремий shared image `ghcr.io/openclaw/openclaw-live-test:` для кожного вибраного commit. Live -release workflow один раз збирає й публікує цей image, потім Docker live model, -gateway, CLI backend, ACP bind і Codex harness шарди запускаються з -`OPENCLAW_SKIP_DOCKER_BUILD=1`. Якщо ці шарди незалежно перебудовують повну source Docker -ціль, release run налаштовано неправильно, і він марнуватиме wall clock на дубльовані image builds. +release workflow збирає й пушить цей image один раз, після чого Docker live model, +gateway, CLI backend, ACP bind і Codex harness shards запускаються з +`OPENCLAW_SKIP_DOCKER_BUILD=1`. Якщо ці shards самостійно перебудовують повну source Docker +target, release run налаштовано неправильно, і він марнуватиме wall +clock на duplicate image builds. `OpenClaw Release Checks` використовує trusted workflow ref, щоб один раз розв’язати вибраний -ref у tarball `release-package-under-test`, потім передає цей artifact -і live/E2E release-path Docker workflow, і package acceptance -шарду. Це зберігає package bytes узгодженими між release boxes і уникає -повторного пакування того самого candidate у кількох дочірніх завданнях. +ref у tarball `release-package-under-test`, а потім передає цей artifact +як у live/E2E release-path Docker workflow, так і в shard package acceptance. +Це забезпечує узгодженість package bytes між release boxes і уникає +повторного пакування того самого кандидата в кількох дочірніх jobs. `Package Acceptance` — це side-run workflow для валідації package artifact -без блокування release workflow. Він розв’язує одного candidate з -published npm spec, trusted `package_ref`, зібраного з вибраним -`workflow_ref` harness, HTTPS tarball URL із SHA-256 або tarball artifact -з іншого GitHub Actions run, завантажує його як `package-under-test`, потім повторно використовує +без блокування release workflow. Він розв’язує одного кандидата з +опублікованої npm spec, trusted `package_ref`, зібраного вибраним +harness `workflow_ref`, HTTPS tarball URL із SHA-256 або tarball artifact +з іншого GitHub Actions run, завантажує його як `package-under-test`, а потім повторно використовує Docker release/E2E scheduler із цим tarball замість повторного пакування -workflow checkout. Profiles покривають smoke, package, product, full і custom -Docker lane selections. Profile `package` використовує offline plugin coverage, щоб -published-package validation не залежала від live-доступності ClawHub. Опційний Telegram-напрям повторно використовує -artifact `package-under-test` у workflow `NPM Telegram Beta E2E`, а -published npm spec path збережено для standalone dispatches. +workflow checkout. Профілі охоплюють smoke, package, product, full і custom +вибори Docker lanes. Профіль `package` використовує offline plugin coverage, щоб +валідація published-package не залежала від доступності live ClawHub. Необов’язкова +Telegram lane повторно використовує artifact +`package-under-test` у workflow `NPM Telegram Beta E2E`, а шлях published npm spec +зберігається для standalone dispatches. -## Приймання пакета +## Приймання package -Використовуйте `Package Acceptance`, коли питання звучить як «чи працює цей installable OpenClaw -package як product?» Він відрізняється від звичайного CI: звичайний CI перевіряє +Використовуйте `Package Acceptance`, коли питання таке: «чи працює цей інстальований package OpenClaw +як продукт?» Це відрізняється від звичайної CI: звичайна CI перевіряє source tree, тоді як package acceptance перевіряє один tarball через той самий -Docker E2E harness, який користувачі використовують після install або update. +Docker E2E harness, який користувачі задіюють після install або update. -Workflow має чотири завдання: +Workflow має чотири jobs: -1. `resolve_package` check out `workflow_ref`, розв’язує одного package candidate, +1. `resolve_package` checkout-ить `workflow_ref`, розв’язує одного package candidate, записує `.artifacts/docker-e2e-package/openclaw-current.tgz`, записує `.artifacts/docker-e2e-package/package-candidate.json`, завантажує обидва як artifact `package-under-test` і друкує source, workflow ref, package @@ -105,38 +107,38 @@ Workflow має чотири завдання: `openclaw-live-and-e2e-checks-reusable.yml` з `ref=workflow_ref` і `package_artifact_name=package-under-test`. Reusable workflow завантажує цей artifact, перевіряє tarball inventory, готує package-digest - Docker images за потреби й запускає вибрані Docker lanes проти цього + Docker images за потреби та запускає вибрані Docker lanes проти цього package замість пакування workflow checkout. Коли profile вибирає - кілька targeted `docker_lanes`, reusable workflow готує package - і shared images один раз, потім розгортає ці lanes як паралельні targeted Docker + кілька цільових `docker_lanes`, reusable workflow готує package + і shared images один раз, а потім розгортає ці lanes як parallel targeted Docker jobs з унікальними artifacts. -3. `package_telegram` опційно викликає `NPM Telegram Beta E2E`. Він запускається, коли - `telegram_mode` не є `none`, і встановлює той самий artifact `package-under-test`, - коли Package Acceptance розв’язав один; standalone Telegram dispatch - усе ще може встановити published npm spec. -4. `summary` валить workflow, якщо package resolution, Docker acceptance або - опційний Telegram-напрям зазнали невдачі. +3. `package_telegram` необов’язково викликає `NPM Telegram Beta E2E`. Він запускається, коли + `telegram_mode` не дорівнює `none`, і встановлює той самий artifact `package-under-test`, + коли Package Acceptance розв’язав його; standalone Telegram dispatch + все ще може встановити published npm spec. +4. `summary` завершує workflow помилкою, якщо package resolution, Docker acceptance або + необов’язкова Telegram lane завершилися невдало. -Джерела candidate: +Джерела кандидатів: - `source=npm`: приймає лише `openclaw@beta`, `openclaw@latest` або точну - release version OpenClaw, наприклад `openclaw@2026.4.27-beta.2`. Використовуйте це для - published beta/stable acceptance. -- `source=ref`: пакує trusted `package_ref` branch, tag або повний commit SHA. + версію релізу OpenClaw, наприклад `openclaw@2026.4.27-beta.2`. Використовуйте це для + приймання опублікованих beta/stable. +- `source=ref`: пакує trusted `package_ref` branch, tag або full commit SHA. Resolver fetch-ить OpenClaw branches/tags, перевіряє, що вибраний commit - reachable з repository branch history або release tag, встановлює deps у - detached worktree і пакує його з `scripts/package-openclaw-for-docker.mjs`. -- `source=url`: завантажує HTTPS `.tgz`; `package_sha256` обов’язковий. + досяжний з історії repository branch або release tag, встановлює deps у + detached worktree і пакує його за допомогою `scripts/package-openclaw-for-docker.mjs`. +- `source=url`: завантажує HTTPS `.tgz`; `package_sha256` є обов’язковим. - `source=artifact`: завантажує один `.tgz` з `artifact_run_id` і - `artifact_name`; `package_sha256` опційний, але його варто надати для + `artifact_name`; `package_sha256` необов’язковий, але його варто надати для externally shared artifacts. Тримайте `workflow_ref` і `package_ref` окремо. `workflow_ref` — це trusted -workflow/harness code, який запускає test. `package_ref` — source commit, +workflow/harness code, який запускає test. `package_ref` — це source commit, який пакується, коли `source=ref`. Це дає змогу поточному test harness перевіряти старіші trusted source commits без запуску старої workflow logic. -Profiles відповідають Docker coverage: +Профілі відповідають Docker coverage: - `smoke`: `npm-onboard-channel-agent`, `gateway-network`, `config-reload` - `package`: `npm-onboard-channel-agent`, `doctor-switch`, @@ -147,38 +149,38 @@ Profiles відповідають Docker coverage: - `full`: повні Docker release-path chunks з OpenWebUI - `custom`: точні `docker_lanes`; обов’язково, коли `suite_profile=custom` -Release checks викликають Package Acceptance з `source=ref`, +Release checks викликають Package Acceptance із `source=ref`, `package_ref=`, `workflow_ref=`, `suite_profile=custom`, `docker_lanes='bundled-channel-deps-compat plugins-offline'` і -`telegram_mode=mock-openai`. Release-path Docker -chunks покривають перетин package/update/plugin lanes, тоді як Package -Acceptance зберігає artifact-native bundled-channel compat, offline plugin і -Telegram proof проти того самого розв’язаного package tarball. +`telegram_mode=mock-openai`. Docker chunks release-path +покривають перетин package/update/plugin lanes, тоді як Package +Acceptance зберігає artifact-native proof для bundled-channel compat, offline plugin і +Telegram проти того самого розв’язаного package tarball. Cross-OS release checks усе ще покривають OS-specific onboarding, installer і platform behavior; package/update product validation має починатися з Package Acceptance. Windows packaged і installer fresh lanes також перевіряють, що -installed package може import browser-control override з raw absolute -Windows path. OpenAI cross-OS agent-turn smoke за замовчуванням використовує -`OPENCLAW_CROSS_OS_OPENAI_MODEL`, коли встановлено, інакше `openai/gpt-5.4-mini`, щоб -install і gateway proof залишалися швидкими й deterministic. Dedicated live -provider/model lanes усе ще покривають ширший model routing, включно з повільнішими +встановлений package може імпортувати browser-control override з raw absolute +Windows path. Cross-OS agent-turn smoke для OpenAI за замовчуванням використовує +`OPENCLAW_CROSS_OS_OPENAI_MODEL`, коли задано, інакше `openai/gpt-5.4-mini`, тому +install і gateway proof залишаються швидкими й детермінованими. Окремі live +provider/model lanes і надалі покривають ширшу model routing, включно з повільнішими frontier defaults. -Package Acceptance має обмежені вікна legacy-compatibility для вже -published packages. Packages до `2026.4.25` включно, включно з `2026.4.25-beta.*`, +Package Acceptance має обмежені windows legacy-compatibility для вже +опублікованих packages. Packages до `2026.4.25` включно, зокрема `2026.4.25-beta.*`, можуть використовувати compatibility path для відомих private QA entries у -`dist/postinstall-inventory.json`, які вказують на файли, omitted з tarball, -`doctor-switch` може пропускати subcase з persistence `gateway install --wrapper`, +`dist/postinstall-inventory.json`, які вказують на файли, пропущені tarball, +`doctor-switch` може пропустити subcase persistence `gateway install --wrapper`, коли package не expose-ить цей flag, `update-channel-switch` може prune -відсутні `pnpm.patchedDependencies` із tarball-derived fake git fixture і +відсутні `pnpm.patchedDependencies` з tarball-derived fake git fixture і може логувати відсутній persisted `update.channel`, plugin smokes можуть читати legacy install-record locations або приймати відсутню marketplace install-record -persistence, а `plugin-update` може дозволяти migration config metadata, усе ще -вимагаючи, щоб install record і no-reinstall behavior залишалися unchanged. Published -package `2026.4.26` також може warning для local build metadata stamp files, -які вже були shipped. Пізніші packages мають задовольняти modern contracts; ті самі -умови fail замість warn або skip. +persistence, а `plugin-update` може дозволити config metadata migration, водночас усе ще +вимагаючи, щоб install record і no-reinstall behavior залишалися незмінними. Опублікований +package `2026.4.26` також може попереджати про local build metadata stamp files, +які вже були shipped. Пізніші packages мають відповідати сучасним contracts; ті самі +умови завершуються помилкою замість warn або skip. Приклади: @@ -221,23 +223,27 @@ gh workflow run package-acceptance.yml \ -f docker_lanes='install-e2e plugin-update' ``` -Під час налагодження невдалого запуску перевірки прийнятності пакета почніть зі зведення `resolve_package`, щоб підтвердити джерело пакета, версію та SHA-256. Потім перевірте дочірній запуск `docker_acceptance` і його артефакти Docker: `.artifacts/docker-tests/**/summary.json`, `failures.json`, журнали lane, таймінги фаз і команди повторного запуску. Надавайте перевагу повторному запуску невдалого профілю пакета або точних Docker lane замість повторного запуску повної перевірки релізу. +Під час налагодження невдалого запуску приймання пакета починайте зі зведення `resolve_package`, щоб підтвердити джерело пакета, версію та SHA-256. Потім перевірте дочірній запуск `docker_acceptance` і його артефакти Docker: +`.artifacts/docker-tests/**/summary.json`, `failures.json`, журнали смуг, часові показники фаз і команди повторного запуску. Надавайте перевагу повторному запуску невдалого профілю пакета або точних смуг Docker замість повторного запуску повної валідації релізу. -QA Lab має окремі lane CI поза основним workflow зі смарт-обмеженням області. Workflow `Parity gate` запускається для відповідних змін у PR і вручну; він збирає приватний runtime QA та порівнює агентні пакети mock GPT-5.5 і Opus 4.6. Workflow `QA-Lab - All Lanes` запускається щоночі на `main` і вручну; він розгалужує mock parity gate, live Matrix lane, а також live lane Telegram і Discord як паралельні завдання. Live-завдання використовують середовище `qa-live-shared`, а Telegram/Discord використовують оренди Convex. Перевірки релізу запускають live transport lane Matrix і Telegram з детермінованим mock-провайдером і моделями, кваліфікованими як mock (`mock-openai/gpt-5.5` і `mock-openai/gpt-5.5-alt`), щоб контракт каналу був ізольований від затримок live-моделей і звичайного запуску provider-Plugin. Live transport gateway також вимикає пошук пам’яті, бо QA parity окремо покриває поведінку пам’яті; підключення provider покривається окремими наборами live model, native provider і Docker provider. Matrix використовує `--profile fast` для запланованих і релізних gates, додаючи `--fail-fast` лише коли checked-out CLI це підтримує. Значення CLI за замовчуванням і ручний ввід workflow залишаються `all`; ручний запуск `matrix_profile=all` завжди шардує повне покриття Matrix на завдання `transport`, `media`, `e2ee-smoke`, `e2ee-deep` і `e2ee-cli`. `OpenClaw Release Checks` також запускає критичні для релізу lane QA Lab перед схваленням релізу; його QA parity gate запускає candidate і baseline packs як паралельні lane-завдання, а потім завантажує обидва артефакти в невелике report-завдання для фінального порівняння parity. Не ставте шлях landing PR за `Parity gate`, якщо зміна фактично не зачіпає runtime QA, parity model-pack або поверхню, якою володіє parity workflow. Для звичайних виправлень каналів, config, docs або unit-test вважайте це необов’язковим сигналом і спирайтеся на evidence зі scoped CI/check. +QA Lab має окремі смуги CI поза головним робочим процесом із розумним визначенням області. Робочий процес `Parity gate` запускається для відповідних змін у PR і вручну; він збирає приватне середовище виконання QA та порівнює агентні пакети mock GPT-5.5 і Opus 4.6. Робочий процес `QA-Lab - All Lanes` запускається щоночі на `main` і вручну; він розгортає mock parity gate, живу смугу Matrix, а також живі смуги Telegram і Discord як паралельні завдання. Живі завдання використовують середовище `qa-live-shared`, а Telegram/Discord використовують оренди Convex. Перевірки релізу запускають живі транспортні смуги Matrix і Telegram із детермінованим mock-провайдером і mock-кваліфікованими моделями (`mock-openai/gpt-5.5` і `mock-openai/gpt-5.5-alt`), щоб контракт каналу був ізольований від затримки живої моделі та звичайного запуску provider-plugin. Живий транспортний Gateway також вимикає пошук у пам’яті, оскільки parity QA покриває поведінку пам’яті окремо; підключення провайдерів покривають окремі набори живої моделі, нативного провайдера та Docker-провайдера. Matrix використовує `--profile fast` для запланованих і релізних gate, додаючи `--fail-fast` лише тоді, коли CLI з checkout це підтримує. Стандартне значення CLI і ручний ввід робочого процесу залишаються `all`; ручний dispatch `matrix_profile=all` завжди шардить повне покриття Matrix на завдання `transport`, `media`, `e2ee-smoke`, `e2ee-deep` і `e2ee-cli`. `OpenClaw Release Checks` також запускає критичні для релізу смуги QA Lab перед затвердженням релізу; його QA parity gate запускає candidate і baseline пакети як паралельні завдання смуг, а потім завантажує обидва артефакти в невелике завдання звіту для фінального порівняння parity. +Не ставте шлях посадки PR за `Parity gate`, якщо зміна насправді не зачіпає середовище виконання QA, parity model-pack або поверхню, якою володіє parity workflow. +Для звичайних виправлень каналів, конфігурації, документації або модульних тестів вважайте це необов’язковим сигналом і дотримуйтеся доказів scoped CI/check. -Workflow `Duplicate PRs After Merge` — це ручний maintainer workflow для очищення дублікатів після landing. За замовчуванням він працює як dry-run і закриває лише явно перелічені PR, коли `apply=true`. Перед змінами в GitHub він перевіряє, що landed PR змерджено і що кожен дублікат має або спільну referenced issue, або перекриття змінених hunk. +Робочий процес `Duplicate PRs After Merge` — це ручний робочий процес мейнтейнера для очищення дублікатів після посадки. За замовчуванням він працює в dry-run і закриває лише явно перелічені PR, коли `apply=true`. Перед змінами в GitHub він перевіряє, що посаджений PR злито і що кожен дублікат має або спільну referenced issue, або перекривні змінені hunk. -Workflow `CodeQL` навмисно є вузьким security scanner першого проходу, а не повним sweep репозиторію. Щоденні та ручні запуски сканують код Actions workflow плюс найризиковіші JavaScript/TypeScript поверхні auth, secrets, sandbox, Cron і gateway за допомогою high-precision security queries. Завдання channel-runtime-boundary окремо сканує контракти реалізації основних каналів плюс runtime channel Plugin, gateway, Plugin SDK, secrets і audit touchpoints у категорії `/codeql-critical-security/channel-runtime-boundary`, щоб security signal каналів міг масштабуватися без розширення baseline категорії JS/TS. +Робочий процес `CodeQL` навмисно є вузьким першим проходом сканера безпеки, а не повним скануванням репозиторію. Щоденні та ручні запуски сканують код робочих процесів Actions, а також найризикованіші поверхні JavaScript/TypeScript для auth, secrets, sandbox, cron і gateway за допомогою високоточних security queries. Завдання channel-runtime-boundary окремо сканує контракти реалізації core channel, а також channel plugin runtime, gateway, Plugin SDK, secrets і audit touchpoints у категорії `/codeql-critical-security/channel-runtime-boundary`, щоб сигнал безпеки каналів міг масштабуватися без розширення базової категорії JS/TS. -Workflow `CodeQL Android Critical Security` — це запланований Android security shard. Він вручну збирає Android app для CodeQL на найменшому Blacksmith Linux runner label, прийнятому workflow sanity, і завантажує результати в категорії `/codeql-critical-security/android`. +Робочий процес `CodeQL Android Critical Security` — це запланований Android shard безпеки. Він вручну збирає Android app для CodeQL на найменшій мітці Blacksmith Linux runner, яку приймає workflow sanity, і завантажує результати в категорію `/codeql-critical-security/android`. -Workflow `CodeQL macOS Critical Security` — це щотижневий/ручний macOS security shard. Він вручну збирає macOS app для CodeQL на Blacksmith macOS, відфільтровує результати dependency build із завантаженого SARIF і завантажує результати в категорії `/codeql-critical-security/macos`. Тримайте його поза щоденним workflow за замовчуванням, бо macOS build домінує runtime навіть коли чистий. +Робочий процес `CodeQL macOS Critical Security` — це щотижневий/ручний macOS shard безпеки. Він вручну збирає macOS app для CodeQL на Blacksmith macOS, відфільтровує результати збірки залежностей із завантаженого SARIF і завантажує результати в категорію `/codeql-critical-security/macos`. Тримайте його поза щоденним стандартним робочим процесом, оскільки збірка macOS домінує за часом виконання навіть коли все чисто. -Workflow `CodeQL Critical Quality` — це відповідний non-security shard. Він запускає лише JavaScript/TypeScript quality queries із severity error і non-security над вузькими high-value поверхнями на меншому Blacksmith Linux runner. Його завдання core-auth-secrets сканує код security boundary для auth, secrets, sandbox, Cron і gateway в окремій категорії `/codeql-critical-quality/core-auth-secrets`. Завдання config-boundary сканує config schema, migration, normalization і IO contracts в окремій категорії `/codeql-critical-quality/config-boundary`. Завдання gateway-runtime-boundary сканує gateway protocol schemas і server method contracts в окремій категорії `/codeql-critical-quality/gateway-runtime-boundary`. Завдання channel-runtime-boundary сканує core channel implementation contracts в окремій категорії `/codeql-critical-quality/channel-runtime-boundary`. Завдання agent-runtime-boundary сканує command execution, model/provider dispatch, auto-reply dispatch і queues, а також ACP control-plane runtime contracts в окремій категорії `/codeql-critical-quality/agent-runtime-boundary`. Завдання mcp-process-runtime-boundary сканує MCP servers і tool bridges, process supervision helpers та outbound delivery contracts в окремій категорії `/codeql-critical-quality/mcp-process-runtime-boundary`. Завдання memory-runtime-boundary сканує memory host SDK, memory runtime facades, memory Plugin SDK aliases, memory runtime activation glue і memory doctor commands в окремій категорії `/codeql-critical-quality/memory-runtime-boundary`. Завдання ui-control-plane сканує Control UI bootstrap, local persistence, gateway control flows і task control-plane runtime contracts в окремій категорії `/codeql-critical-quality/ui-control-plane`. Завдання web-media-runtime-boundary сканує core web fetch/search, media IO, media understanding, image-generation і media-generation runtime contracts в окремій категорії `/codeql-critical-quality/web-media-runtime-boundary`. Завдання plugin-boundary сканує loader, registry, public-surface і Plugin SDK entrypoint contracts в окремій категорії `/codeql-critical-quality/plugin-boundary`. Завдання plugin-sdk-package-contract сканує опубліковане package-side джерело Plugin SDK і plugin package contract helpers в окремій категорії `/codeql-critical-quality/plugin-sdk-package-contract`. Тримайте workflow окремо від security, щоб quality findings можна було планувати, вимірювати, вимикати або розширювати без розмивання security signal. Розширення CodeQL для Swift, Python і bundled-plugin слід додати назад як scoped або sharded follow-up work лише після того, як вузькі профілі матимуть стабільний runtime і signal. +Робочий процес `CodeQL Critical Quality` — це відповідний не-безпековий shard. Він запускає лише не-безпекові quality queries JavaScript/TypeScript із severity error на вузьких цінних поверхнях на меншому Blacksmith Linux runner. Його ручний dispatch приймає `profile=all|plugin-sdk-package-contract`; вузький профіль є першим teaching/iteration hook для запуску одного quality shard в ізоляції без dispatch решти робочого процесу. +Його завдання core-auth-secrets сканує boundary code для auth, secrets, sandbox, cron і gateway security в окремій категорії `/codeql-critical-quality/core-auth-secrets`. Завдання config-boundary сканує config schema, migration, normalization і IO contracts в окремій категорії `/codeql-critical-quality/config-boundary`. Завдання gateway-runtime-boundary сканує схеми протоколу gateway і server method contracts в окремій категорії `/codeql-critical-quality/gateway-runtime-boundary`. Завдання channel-runtime-boundary сканує core channel implementation contracts в окремій категорії `/codeql-critical-quality/channel-runtime-boundary`. Завдання agent-runtime-boundary сканує command execution, model/provider dispatch, auto-reply dispatch and queues, а також ACP control-plane runtime contracts в окремій категорії `/codeql-critical-quality/agent-runtime-boundary`. Завдання mcp-process-runtime-boundary сканує MCP servers and tool bridges, process supervision helpers і outbound delivery contracts в окремій категорії `/codeql-critical-quality/mcp-process-runtime-boundary`. Завдання memory-runtime-boundary сканує memory host SDK, memory runtime facades, memory Plugin SDK aliases, memory runtime activation glue і memory doctor commands в окремій категорії `/codeql-critical-quality/memory-runtime-boundary`. Завдання ui-control-plane сканує Control UI bootstrap, local persistence, gateway control flows і task control-plane runtime contracts в окремій категорії `/codeql-critical-quality/ui-control-plane`. Завдання web-media-runtime-boundary сканує core web fetch/search, media IO, media understanding, image-generation і media-generation runtime contracts в окремій категорії `/codeql-critical-quality/web-media-runtime-boundary`. Завдання plugin-boundary сканує loader, registry, public-surface і Plugin SDK entrypoint contracts в окремій категорії `/codeql-critical-quality/plugin-boundary`. Завдання plugin-sdk-package-contract сканує опублікований package-side Plugin SDK source і plugin package contract helpers в окремій категорії `/codeql-critical-quality/plugin-sdk-package-contract`. Тримайте робочий процес окремо від security, щоб quality findings можна було планувати, вимірювати, вимикати або розширювати без затемнення сигналу безпеки. Розширення CodeQL для Swift, Python і bundled-plugin слід додавати назад лише як scoped або sharded follow-up work після того, як вузькі профілі матимуть стабільні runtime і signal. -Workflow `Docs Agent` — це event-driven Codex maintenance lane для підтримання наявної docs у відповідності з нещодавно landed changes. Він не має чистого розкладу: успішний non-bot push CI run на `main` може його запустити, а ручний dispatch може запустити його напряму. Workflow-run invocations пропускаються, коли `main` уже змістився або коли інший non-skipped Docs Agent run було створено за останню годину. Коли він запускається, він переглядає діапазон commit від попереднього non-skipped Docs Agent source SHA до поточного `main`, тож один погодинний запуск може покрити всі зміни main, накопичені з останнього проходу docs. +Робочий процес `Docs Agent` — це подієво-керована смуга підтримки Codex для утримання наявної документації узгодженою з нещодавно посадженими змінами. Він не має чистого розкладу: успішний non-bot push CI run на `main` може його запустити, а manual dispatch може запустити його напряму. Workflow-run invocations пропускаються, коли `main` уже зрушив далі або коли інший non-skipped Docs Agent run було створено за останню годину. Коли він запускається, він переглядає діапазон комітів від попереднього non-skipped Docs Agent source SHA до поточного `main`, тож один погодинний запуск може покрити всі зміни main, накопичені з останнього проходу документації. -Workflow `Test Performance Agent` — це event-driven Codex maintenance lane для повільних тестів. Він не має чистого розкладу: успішний non-bot push CI run на `main` може його запустити, але він пропускається, якщо інша workflow-run invocation уже запускалася або виконується цього UTC-дня. Ручний dispatch обходить цей daily activity gate. Lane будує grouped Vitest performance report для full-suite, дозволяє Codex вносити лише невеликі coverage-preserving test performance fixes замість широких refactors, потім повторно запускає full-suite report і відхиляє зміни, які зменшують baseline count прохідних тестів. Якщо baseline має failing tests, Codex може виправляти лише очевидні failures, а after-agent full-suite report має пройти перед тим, як щось буде закомічено. Коли `main` просувається до landing bot push, lane rebase validated patch, повторно запускає `pnpm check:changed` і повторює push; конфліктні stale patches пропускаються. Він використовує GitHub-hosted Ubuntu, щоб Codex action міг зберегти ту саму drop-sudo safety posture, що й docs agent. +Робочий процес `Test Performance Agent` — це подієво-керована смуга підтримки Codex для повільних тестів. Він не має чистого розкладу: успішний non-bot push CI run на `main` може його запустити, але він пропускається, якщо інший workflow-run invocation уже запускався або виконується цього UTC-дня. Manual dispatch обходить цей daily activity gate. Смуга формує full-suite grouped Vitest performance report, дозволяє Codex робити лише невеликі виправлення продуктивності тестів зі збереженням покриття замість широких рефакторингів, потім повторно запускає full-suite report і відхиляє зміни, які зменшують baseline count успішних тестів. Якщо baseline має failing tests, Codex може виправляти лише очевидні failures, а after-agent full-suite report має пройти перед будь-яким commit. Коли `main` просувається до посадки bot push, смуга rebase валідованого patch, повторно запускає `pnpm check:changed` і повторює push; conflict stale patches пропускаються. Вона використовує GitHub-hosted Ubuntu, щоб Codex action міг зберегти ту саму drop-sudo safety posture, що й docs agent. ```bash gh workflow run duplicate-after-merge.yml \ @@ -246,46 +252,46 @@ gh workflow run duplicate-after-merge.yml \ -f apply=true ``` -## Огляд завдань +## Огляд завдання -| Завдання | Призначення | Коли виконується | -| -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- | -| `preflight` | Виявляє зміни лише в документації, змінені області, змінені plugins і створює CI-маніфест | Завжди для недрафтових push і PR | -| `security-scm-fast` | Виявлення приватних ключів і аудит workflow через `zizmor` | Завжди для недрафтових push і PR | -| `security-dependency-audit` | Аудит production lockfile без залежностей за npm advisories | Завжди для недрафтових push і PR | -| `security-fast` | Обов’язковий агрегат для швидких security-завдань | Завжди для недрафтових push і PR | -| `build-artifacts` | Збірка `dist/`, Control UI, перевірки зібраних артефактів і reusable downstream artifacts | Зміни, релевантні для Node | -| `checks-fast-core` | Швидкі Linux-ланцюжки коректності, як-от bundled/plugin-contract/protocol checks | Зміни, релевантні для Node | -| `checks-fast-contracts-channels` | Sharded перевірки контрактів каналів зі стабільним агрегованим результатом перевірки | Зміни, релевантні для Node | -| `checks-node-core-test` | Shards тестів Core Node, за винятком channel, bundled, contract і extension lanes | Зміни, релевантні для Node | -| `check` | Sharded еквівалент основного локального gate: prod types, lint, guards, test types і strict smoke | Зміни, релевантні для Node | -| `check-additional` | Architecture, boundary, extension-surface guards, package-boundary і gateway-watch shards | Зміни, релевантні для Node | -| `build-smoke` | Built-CLI smoke tests і startup-memory smoke | Зміни, релевантні для Node | -| `checks` | Верифікатор для built-artifact channel tests | Зміни, релевантні для Node | -| `checks-node-compat-node22` | Збірка сумісності з Node 22 і smoke lane | Ручний запуск CI для релізів | -| `check-docs` | Форматування документації, lint і перевірки broken links | Документацію змінено | -| `skills-python` | Ruff + pytest для Python-backed skills | Зміни, релевантні для Python skills | -| `checks-windows` | Windows-specific process/path tests плюс regressions shared runtime import specifier | Зміни, релевантні для Windows | -| `macos-node` | macOS TypeScript test lane із використанням спільних built artifacts | Зміни, релевантні для macOS | -| `macos-swift` | Swift lint, build і tests для macOS app | Зміни, релевантні для macOS | -| `android` | Android unit tests для обох flavors плюс одна debug APK build | Зміни, релевантні для Android | -| `test-performance-agent` | Щоденна оптимізація повільних тестів Codex після довіреної активності | Успіх Main CI або ручний запуск | +| Завдання | Призначення | Коли запускається | +| -------------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------- | +| `preflight` | Виявляє зміни лише в документації, змінені області, змінені розширення та збирає маніфест CI | Завжди для недрафтових push і PR | +| `security-scm-fast` | Виявлення приватних ключів і аудит workflow через `zizmor` | Завжди для недрафтових push і PR | +| `security-dependency-audit` | Аудит production lockfile без залежностей на основі npm advisories | Завжди для недрафтових push і PR | +| `security-fast` | Обов’язковий агрегат для швидких завдань безпеки | Завжди для недрафтових push і PR | +| `build-artifacts` | Збирає `dist/`, Control UI, перевірки зібраних артефактів і перевикористовні downstream-артефакти | Зміни, релевантні для Node | +| `checks-fast-core` | Швидкі Linux-лінії коректності, як-от bundled/plugin-contract/protocol перевірки | Зміни, релевантні для Node | +| `checks-fast-contracts-channels` | Шардовані перевірки контрактів каналів зі стабільним агрегованим результатом перевірки | Зміни, релевантні для Node | +| `checks-node-core-test` | Шарди тестів ядра Node, без ліній каналів, bundled, контрактів і розширень | Зміни, релевантні для Node | +| `check` | Шардований еквівалент основного локального gate: prod-типи, lint, guards, тестові типи та строгий smoke | Зміни, релевантні для Node | +| `check-additional` | Архітектура, межі, guards поверхні розширень, package-boundary і шарди gateway-watch | Зміни, релевантні для Node | +| `build-smoke` | Smoke-тести зібраного CLI та smoke стартової пам’яті | Зміни, релевантні для Node | +| `checks` | Верифікатор для тестів каналів зібраних артефактів | Зміни, релевантні для Node | +| `checks-node-compat-node22` | Лінія збірки й smoke сумісності з Node 22 | Ручний запуск CI для релізів | +| `check-docs` | Форматування документації, lint і перевірки битих посилань | Змінено документацію | +| `skills-python` | Ruff + pytest для Skills на основі Python | Зміни, релевантні для Python Skills | +| `checks-windows` | Специфічні для Windows тести процесів/шляхів і спільні регресії специфікаторів імпорту runtime | Зміни, релевантні для Windows | +| `macos-node` | Лінія тестів TypeScript для macOS, що використовує спільні зібрані артефакти | Зміни, релевантні для macOS | +| `macos-swift` | Swift lint, збірка й тести для застосунку macOS | Зміни, релевантні для macOS | +| `android` | Модульні тести Android для обох flavor плюс одна збірка debug APK | Зміни, релевантні для Android | +| `test-performance-agent` | Щоденна оптимізація повільних тестів Codex після довіреної активності | Успіх Main CI або ручний запуск | -Ручні запуски CI виконують той самий граф завдань, що й звичайний CI, але примусово вмикають кожен -scoped lane, не пов’язаний з Android: Linux Node shards, bundled-plugin shards, channel -contracts, сумісність із Node 22, `check`, `check-additional`, build smoke, перевірки документації, -Python skills, Windows, macOS і Control UI i18n. Окремі ручні запуски CI -виконують лише Android з `include_android=true`; повний release -umbrella вмикає Android, передаючи `include_android=true`. Статичні перевірки prerelease для Plugin, -release-only shard `agentic-plugins`, повний batch sweep для extensions -і Docker lanes для prerelease Plugin виключено з CI. Набір Docker -prerelease виконується лише тоді, коли `Full Release Validation` запускає +Ручні запуски CI виконують той самий граф завдань, що й звичайний CI, але примусово +вмикають кожну не-Android scoped-лінію: Linux Node shards, bundled-plugin shards, channel +contracts, сумісність із Node 22, `check`, `check-additional`, build smoke, перевірки +документації, Python Skills, Windows, macOS і Control UI i18n. Окремі ручні запуски CI +виконують лише Android з `include_android=true`; повна релізна +парасолька вмикає Android, передаючи `include_android=true`. Статичні перевірки попереднього випуску Plugin, +release-only шард `agentic-plugins`, повний пакетний sweep розширень +і Docker-лінії попереднього випуску Plugin виключено з CI. Docker +набір попереднього випуску запускається лише тоді, коли `Full Release Validation` запускає окремий workflow `Plugin Prerelease` з увімкненим gate release-validation. Ручні запуски використовують унікальну concurrency group, щоб повний набір release-candidate не скасовувався -іншим push або PR run на тому самому ref. Необов’язковий input `target_ref` дає -довіреному виклику змогу запустити цей граф для branch, tag або повного commit SHA, водночас -використовуючи workflow file з вибраного dispatch ref. +іншим push або PR-запуском на тому самому ref. Необов’язковий input `target_ref` дає змогу +довіреному виклику запустити цей граф для branch, tag або повного commit SHA, +використовуючи файл workflow з вибраного dispatch ref. ```bash gh workflow run ci.yml --ref release/YYYY.M.D @@ -295,56 +301,56 @@ gh workflow run full-release-validation.yml --ref main -f ref= ## Порядок fail-fast -Завдання впорядковано так, щоб дешеві перевірки завершувалися з помилкою до запуску дорогих: +Завдання впорядковано так, щоб дешеві перевірки падали до запуску дорогих: -1. `preflight` вирішує, які lanes взагалі існують. Логіка `docs-scope` і `changed-scope` є кроками всередині цього завдання, а не окремими завданнями. -2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs` і `skills-python` швидко завершуються з помилкою, не чекаючи на важчі завдання artifact і platform matrix. -3. `build-artifacts` виконується паралельно зі швидкими Linux lanes, щоб downstream consumers могли стартувати щойно спільна збірка буде готова. -4. Після цього розгортаються важчі platform і runtime lanes: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-core-test`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`. +1. `preflight` вирішує, які лінії взагалі існують. Логіка `docs-scope` і `changed-scope` є кроками всередині цього завдання, а не окремими завданнями. +2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs` і `skills-python` швидко падають, не чекаючи важчих матричних завдань для артефактів і платформ. +3. `build-artifacts` перекривається зі швидкими Linux-лініями, щоб downstream-споживачі могли стартувати, щойно спільна збірка буде готова. +4. Після цього розгалужуються важчі лінії платформ і runtime: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-core-test`, `checks`, `checks-windows`, `macos-node`, `macos-swift` і `android`. -Логіка області живе в `scripts/ci-changed-scope.mjs` і покрита модульними тестами в `src/scripts/ci-changed-scope.test.ts`. -Ручний запуск пропускає виявлення зміненої області й змушує preflight-маніфест -діяти так, ніби змінилася кожна область із визначеним scope. -Редагування CI workflow перевіряють граф Node CI плюс linting workflow, але самі по собі не примушують запускати нативні збірки Windows, Android або macOS; ці платформні lanes залишаються прив’язаними до змін платформного вихідного коду. -Редагування, що стосуються лише маршрутизації CI, вибрані дешеві редагування core-test fixtures і вузькі редагування helper/test-routing для контрактів плагінів використовують швидкий Node-only шлях маніфесту: preflight, security і одне завдання `checks-fast-core`. Цей шлях уникає build artifacts, сумісності з Node 22, контрактів каналів, повних core shards, bundled-plugin shards і додаткових guard matrices, коли змінені файли обмежені поверхнями маршрутизації або helper, які швидке завдання перевіряє безпосередньо. -Windows Node checks обмежені специфічними для Windows wrappers процесів/шляхів, npm/pnpm/UI runner helpers, конфігурацією package manager і поверхнями CI workflow, які виконують цю lane; непов’язані зміни source, plugin, install-smoke і test-only залишаються на Linux Node lanes, щоб вони не резервували 16-vCPU Windows worker для покриття, яке вже перевіряється звичайними test shards. -Окремий workflow `install-smoke` повторно використовує той самий scope script через власне завдання `preflight`. Він розділяє smoke coverage на `run_fast_install_smoke` і `run_full_install_smoke`. Pull requests запускають fast path для Docker/package surfaces, змін package/manifest вбудованих плагінів і поверхонь core plugin/channel/gateway/Plugin SDK, які перевіряють Docker smoke jobs. Зміни лише у вихідному коді вбудованих плагінів, test-only edits і docs-only edits не резервують Docker workers. Fast path один раз збирає root Dockerfile image, перевіряє CLI, запускає agents delete shared-workspace CLI smoke, запускає container gateway-network e2e, перевіряє build arg вбудованого розширення і запускає bounded bundled-plugin Docker profile під 240-секундним aggregate command timeout, причому Docker run для кожного scenario обмежений окремо. Full path зберігає QR package install і installer Docker/update coverage для nightly scheduled runs, manual dispatches, workflow-call release checks і pull requests, які справді зачіпають installer/package/Docker surfaces. `main` pushes, зокрема merge commits, не примушують full path; коли changed-scope logic запитала б full coverage на push, workflow зберігає fast Docker smoke і залишає full install smoke для nightly або release validation. Повільний Bun global install image-provider smoke окремо gated через `run_bun_global_install_smoke`; він запускається за nightly schedule і з release checks workflow, а manual `install-smoke` dispatches можуть opt into it, але pull requests і `main` pushes його не запускають. QR і installer Docker tests зберігають власні install-focused Dockerfiles. Локальний `test:docker:all` prebuilds один shared live-test image, один раз пакує OpenClaw як npm tarball і збирає два shared `scripts/e2e/Dockerfile` images: bare Node/Git runner для installer/update/plugin-dependency lanes і functional image, який installs той самий tarball у `/app` для normal functionality lanes. Визначення Docker lanes живуть у `scripts/lib/docker-e2e-scenarios.mjs`, planner logic живе в `scripts/lib/docker-e2e-plan.mjs`, а runner виконує лише вибраний plan. Scheduler вибирає image для кожної lane через `OPENCLAW_DOCKER_E2E_BARE_IMAGE` і `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`, потім запускає lanes з `OPENCLAW_SKIP_DOCKER_BUILD=1`; налаштуйте default main-pool slot count 10 через `OPENCLAW_DOCKER_ALL_PARALLELISM` і provider-sensitive tail-pool slot count 10 через `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM`. Heavy lane caps за замовчуванням дорівнюють `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`, щоб npm install і multi-service lanes не overcommit Docker, поки lighter lanes все ще заповнюють доступні slots. Одна lane, важча за effective caps, все одно може стартувати з empty pool, а потім виконується самостійно, доки не звільнить capacity. Lane starts за замовчуванням рознесені на 2 секунди, щоб уникнути local Docker daemon create storms; перевизначте через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` або інше значення в мілісекундах. Local aggregate preflights Docker, removes stale OpenClaw E2E containers, emits active-lane status, persists lane timings для longest-first ordering і підтримує `OPENCLAW_DOCKER_ALL_DRY_RUN=1` для scheduler inspection. Він припиняє планувати new pooled lanes після першого failure за замовчуванням, і кожна lane має 120-minute fallback timeout, overrideable через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; selected live/tail lanes використовують tighter per-lane caps. `OPENCLAW_DOCKER_ALL_LANES=` запускає точні scheduler lanes, зокрема release-only lanes як-от `install-e2e` і split bundled update lanes як-от `bundled-channel-update-acpx`, пропускаючи cleanup smoke, щоб agents могли відтворити одну failed lane. Reusable live/E2E workflow запитує в `scripts/test-docker-all.mjs --plan-json`, яке package, image kind, live image, lane і credential coverage потрібні, потім `scripts/docker-e2e.mjs` перетворює цей plan на GitHub outputs і summaries. Він або пакує OpenClaw через `scripts/package-openclaw-for-docker.mjs`, downloads current-run package artifact, або downloads package artifact з `package_artifact_run_id`; validates tarball inventory; builds and pushes package-digest-tagged bare/functional GHCR Docker E2E images через Docker layer cache Blacksmith, коли plan needs package-installed lanes; і повторно використовує надані inputs `docker_e2e_bare_image`/`docker_e2e_functional_image` або existing package-digest images замість rebuild. Docker image pulls retries with a bounded 180-second per-attempt timeout, щоб stuck registry/cache stream швидко retry, а не споживав більшу частину CI critical path. Workflow `Package Acceptance` є high-level package gate: він resolves candidate з npm, trusted `package_ref`, HTTPS tarball plus SHA-256 або prior workflow artifact, а потім передає цей єдиний artifact `package-under-test` у reusable Docker E2E workflow. Він тримає `workflow_ref` окремо від `package_ref`, щоб current acceptance logic могла validate older trusted commits без checkout old workflow code. Release checks запускають custom Package Acceptance delta для target ref: bundled-channel compat, offline plugin fixtures і Telegram package QA against the resolved tarball. Release-path Docker suite запускає smaller chunked jobs з `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб кожен chunk pulls only the image kind it needs і executes multiple lanes through the same weighted scheduler (`OPENCLAW_DOCKER_ALL_PROFILE=release-path`, `OPENCLAW_DOCKER_ALL_CHUNK=core|package-update-openai|package-update-anthropic|package-update-core|plugins-runtime-plugins|plugins-runtime-services|plugins-runtime-install-a|plugins-runtime-install-b|plugins-runtime-install-c|plugins-runtime-install-d|plugins-runtime-install-e|plugins-runtime-install-f|plugins-runtime-install-g|plugins-runtime-install-h|bundled-channels`). OpenWebUI folded into `plugins-runtime-services`, коли full release-path coverage requests it, і зберігає standalone `openwebui` chunk лише для OpenWebUI-only dispatches. Legacy aggregate chunk names `package-update`, `plugins-runtime-core`, `plugins-runtime` і `plugins-integrations` досі працюють для manual reruns, але release workflow uses split chunks, щоб installer E2E і bundled plugin install/uninstall sweeps не dominated the critical path. Lane alias `install-e2e` залишається aggregate manual rerun alias для обох provider installer lanes. Chunk `bundled-channels` запускає split `bundled-channel-*` і `bundled-channel-update-*` lanes замість serial all-in-one `bundled-channel-deps` lane. Кожен chunk uploads `.artifacts/docker-tests/` з lane logs, timings, `summary.json`, `failures.json`, phase timings, scheduler plan JSON, slow-lane tables і per-lane rerun commands. Input workflow `docker_lanes` запускає selected lanes against the prepared images замість chunk jobs, що keeps failed-lane debugging bounded to one targeted Docker job і prepares, downloads, or reuses the package artifact for that run; якщо selected lane є live Docker lane, targeted job builds the live-test image locally for that rerun. Generated per-lane GitHub rerun commands include `package_artifact_run_id`, `package_artifact_name` і prepared image inputs, коли ці значення існують, щоб failed lane могла reuse the exact package and images from the failed run. Використовуйте `pnpm test:docker:rerun `, щоб download Docker artifacts from a GitHub run і print combined/per-lane targeted rerun commands; використовуйте `pnpm test:docker:timings ` для slow-lane and phase critical-path summaries. Scheduled live/E2E workflow запускає full release-path Docker suite daily. Bundled update matrix split by update target, щоб repeated npm update і doctor repair passes могли shard with other bundled checks. +Логіка області дії міститься в `scripts/ci-changed-scope.mjs` і покрита модульними тестами в `src/scripts/ci-changed-scope.test.ts`. +Ручний запуск пропускає визначення changed-scope і змушує preflight-маніфест +поводитися так, ніби змінилася кожна область дії. +Зміни CI workflow перевіряють граф Node CI та linting workflow, але самі по собі не примушують запускати нативні збірки Windows, Android або macOS; ці платформні лінії залишаються прив'язаними до змін у платформному вихідному коді. +Зміни лише маршрутизації CI, вибрані дешеві зміни core-test fixture, а також вузькі зміни plugin contract helper/test-routing використовують швидкий шлях маніфесту лише для Node: preflight, security і одне завдання `checks-fast-core`. Цей шлях уникає артефактів збірки, сумісності з Node 22, контрактів каналів, повних core shards, bundled-plugin shards і додаткових guard matrices, коли змінені файли обмежені поверхнями маршрутизації або helper, які швидке завдання перевіряє напряму. +Перевірки Windows Node обмежені специфічними для Windows обгортками процесів/шляхів, npm/pnpm/UI runner helpers, конфігурацією package manager і поверхнями CI workflow, які виконують цю лінію; непов'язані зміни у вихідному коді, plugin, install-smoke і лише тестові зміни залишаються на Linux Node lanes, щоб вони не резервували 16-vCPU Windows worker для покриття, яке вже виконується звичайними test shards. +Окремий workflow `install-smoke` повторно використовує той самий скрипт області дії через власне завдання `preflight`. Він ділить smoke-покриття на `run_fast_install_smoke` і `run_full_install_smoke`. Pull requests запускають швидкий шлях для Docker/package surfaces, змін bundled plugin package/manifest, а також core plugin/channel/gateway/Plugin SDK surfaces, які перевіряють Docker smoke jobs. Зміни лише вихідного коду bundled plugin, лише тестові зміни та лише docs-зміни не резервують Docker workers. Швидкий шлях один раз збирає образ root Dockerfile, перевіряє CLI, запускає agents delete shared-workspace CLI smoke, запускає container gateway-network e2e, перевіряє bundled extension build arg і запускає обмежений bundled-plugin Docker profile із 240-секундним сукупним таймаутом команди, де Docker run кожного сценарію окремо обмежений. Повний шлях зберігає QR package install і installer Docker/update coverage для нічних scheduled runs, manual dispatches, workflow-call release checks і pull requests, які справді зачіпають installer/package/Docker surfaces. Пуші в `main`, зокрема merge commits, не примушують повний шлях; коли логіка changed-scope запитала б повне покриття на push, workflow зберігає fast Docker smoke і залишає full install smoke для нічної або релізної валідації. Повільний Bun global install image-provider smoke окремо керується через `run_bun_global_install_smoke`; він запускається за нічним розкладом і з release checks workflow, а ручні `install-smoke` dispatches можуть увімкнути його опціонально, але pull requests і пуші в `main` його не запускають. QR і installer Docker tests зберігають власні install-focused Dockerfiles. Локальний `test:docker:all` попередньо збирає один спільний live-test image, один раз пакує OpenClaw як npm tarball і збирає два спільні образи `scripts/e2e/Dockerfile`: bare Node/Git runner для installer/update/plugin-dependency lanes і функціональний образ, який встановлює той самий tarball у `/app` для normal functionality lanes. Визначення Docker lane містяться в `scripts/lib/docker-e2e-scenarios.mjs`, логіка планувальника міститься в `scripts/lib/docker-e2e-plan.mjs`, а runner виконує лише вибраний план. Scheduler вибирає образ для кожної lane за допомогою `OPENCLAW_DOCKER_E2E_BARE_IMAGE` і `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`, а потім запускає lanes з `OPENCLAW_SKIP_DOCKER_BUILD=1`; налаштуйте стандартну кількість слотів main-pool 10 через `OPENCLAW_DOCKER_ALL_PARALLELISM` і чутливу до provider кількість слотів tail-pool 10 через `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM`. Обмеження heavy lanes за замовчуванням становлять `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`, `OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` і `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`, щоб npm install і multi-service lanes не перевантажували Docker, тоді як легші lanes усе ще заповнюють доступні слоти. Одна lane, важча за ефективні обмеження, усе одно може стартувати з порожнього pool, а потім виконується сама, доки не звільнить capacity. Запуски lanes за замовчуванням рознесені на 2 секунди, щоб уникнути локальних create storms Docker daemon; перевизначте через `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=0` або інше значення в мілісекундах. Локальний aggregate попередньо перевіряє Docker, видаляє застарілі контейнери OpenClaw E2E, виводить статус active-lane, зберігає timings lanes для longest-first ordering і підтримує `OPENCLAW_DOCKER_ALL_DRY_RUN=1` для інспекції scheduler. За замовчуванням він припиняє планувати нові pooled lanes після першого збою, і кожна lane має 120-хвилинний fallback timeout, який можна перевизначити через `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS`; вибрані live/tail lanes використовують жорсткіші per-lane caps. `OPENCLAW_DOCKER_ALL_LANES=` запускає точні scheduler lanes, зокрема release-only lanes, як-от `install-e2e`, і split bundled update lanes, як-от `bundled-channel-update-acpx`, пропускаючи cleanup smoke, щоб agents могли відтворити одну невдалу lane. Багаторазовий live/E2E workflow запитує в `scripts/test-docker-all.mjs --plan-json`, яке package, image kind, live image, lane і credential coverage потрібні, а потім `scripts/docker-e2e.mjs` перетворює цей план на GitHub outputs і summaries. Він або пакує OpenClaw через `scripts/package-openclaw-for-docker.mjs`, завантажує package artifact поточного run, або завантажує package artifact з `package_artifact_run_id`; перевіряє tarball inventory; збирає та пушить package-digest-tagged bare/functional GHCR Docker E2E images через Docker layer cache від Blacksmith, коли план потребує package-installed lanes; і повторно використовує надані inputs `docker_e2e_bare_image`/`docker_e2e_functional_image` або наявні package-digest images замість повторної збірки. Завантаження Docker images повторюються з обмеженим 180-секундним таймаутом на спробу, щоб завислий registry/cache stream швидко повторився, а не споживав більшу частину критичного шляху CI. Workflow `Package Acceptance` є високорівневим package gate: він визначає candidate з npm, довіреного `package_ref`, HTTPS tarball плюс SHA-256 або попереднього workflow artifact, а потім передає цей єдиний artifact `package-under-test` у багаторазовий Docker E2E workflow. Він тримає `workflow_ref` окремо від `package_ref`, щоб поточна acceptance logic могла перевіряти старіші довірені commits без checkout старого workflow code. Release checks запускають custom Package Acceptance delta для target ref: bundled-channel compat, offline plugin fixtures і Telegram package QA для resolved tarball. Docker suite release-path запускає менші chunked jobs з `OPENCLAW_SKIP_DOCKER_BUILD=1`, щоб кожен chunk завантажував лише потрібний йому image kind і виконував кілька lanes через той самий weighted scheduler (`OPENCLAW_DOCKER_ALL_PROFILE=release-path`, `OPENCLAW_DOCKER_ALL_CHUNK=core|package-update-openai|package-update-anthropic|package-update-core|plugins-runtime-plugins|plugins-runtime-services|plugins-runtime-install-a|plugins-runtime-install-b|plugins-runtime-install-c|plugins-runtime-install-d|plugins-runtime-install-e|plugins-runtime-install-f|plugins-runtime-install-g|plugins-runtime-install-h|bundled-channels`). OpenWebUI включається в `plugins-runtime-services`, коли повне release-path coverage запитує його, і зберігає окремий chunk `openwebui` лише для OpenWebUI-only dispatches. Застарілі aggregate chunk names `package-update`, `plugins-runtime-core`, `plugins-runtime` і `plugins-integrations` усе ще працюють для manual reruns, але release workflow використовує split chunks, щоб installer E2E і bundled plugin install/uninstall sweeps не домінували в критичному шляху. Lane alias `install-e2e` залишається aggregate manual rerun alias для обох provider installer lanes. Chunk `bundled-channels` запускає split `bundled-channel-*` і `bundled-channel-update-*` lanes замість послідовної all-in-one lane `bundled-channel-deps`. Кожен chunk завантажує `.artifacts/docker-tests/` з lane logs, timings, `summary.json`, `failures.json`, phase timings, scheduler plan JSON, slow-lane tables і per-lane rerun commands. Input workflow `docker_lanes` запускає вибрані lanes проти підготовлених images замість chunk jobs, що тримає debugging failed-lane обмеженим одним targeted Docker job і готує, завантажує або повторно використовує package artifact для цього run; якщо вибрана lane є live Docker lane, targeted job локально збирає live-test image для цього rerun. Згенеровані per-lane GitHub rerun commands містять `package_artifact_run_id`, `package_artifact_name` і prepared image inputs, коли ці значення існують, щоб failed lane могла повторно використати точні package і images з failed run. Використовуйте `pnpm test:docker:rerun `, щоб завантажити Docker artifacts з GitHub run і вивести combined/per-lane targeted rerun commands; використовуйте `pnpm test:docker:timings ` для slow-lane і phase critical-path summaries. Scheduled live/E2E workflow щодня запускає повний release-path Docker suite. Bundled update matrix розділена за update target, щоб повторні npm update і doctor repair passes могли shard-итися з іншими bundled checks. -Current release Docker chunks: `core`, `package-update-openai`, `package-update-anthropic`, `package-update-core`, `plugins-runtime-plugins`, `plugins-runtime-services`, `plugins-runtime-install-a`, `plugins-runtime-install-b`, `plugins-runtime-install-c`, `plugins-runtime-install-d`, `plugins-runtime-install-e`, `plugins-runtime-install-f`, `plugins-runtime-install-g`, `plugins-runtime-install-h`, `bundled-channels-core`, `bundled-channels-update-a`, `bundled-channels-update-discord`, `bundled-channels-update-b` і `bundled-channels-contracts`. Aggregate chunk `bundled-channels` залишається available for manual one-shot reruns, а `plugins-runtime-core`, `plugins-runtime` і `plugins-integrations` залишаються aggregate plugin/runtime aliases, але release workflow використовує split chunks, щоб channel smokes, update targets, plugin runtime checks і bundled plugin install/uninstall sweeps могли run in parallel. Targeted `docker_lanes` dispatches також split multiple selected lanes into parallel jobs після одного shared package/image preparation step, а bundled-channel update lanes retry once for transient npm network failures. +Поточні release Docker chunks: `core`, `package-update-openai`, `package-update-anthropic`, `package-update-core`, `plugins-runtime-plugins`, `plugins-runtime-services`, `plugins-runtime-install-a`, `plugins-runtime-install-b`, `plugins-runtime-install-c`, `plugins-runtime-install-d`, `plugins-runtime-install-e`, `plugins-runtime-install-f`, `plugins-runtime-install-g`, `plugins-runtime-install-h`, `bundled-channels-core`, `bundled-channels-update-a`, `bundled-channels-update-discord`, `bundled-channels-update-b` і `bundled-channels-contracts`. Aggregate chunk `bundled-channels` залишається доступним для ручних one-shot reruns, а `plugins-runtime-core`, `plugins-runtime` і `plugins-integrations` залишаються aggregate plugin/runtime aliases, але release workflow використовує split chunks, щоб channel smokes, update targets, plugin runtime checks і bundled plugin install/uninstall sweeps могли виконуватися паралельно. Targeted `docker_lanes` dispatches також розділяють кілька вибраних lanes на паралельні jobs після одного спільного package/image preparation step, а bundled-channel update lanes повторюють спробу один раз у разі transient npm network failures. -Local changed-lane logic живе в `scripts/changed-lanes.mjs` і виконується `scripts/check-changed.mjs`. Цей local check gate суворіший щодо architecture boundaries, ніж broad CI platform scope: core production changes запускають core prod і core test typecheck плюс core lint/guards, core test-only changes запускають лише core test typecheck plus core lint, extension production changes запускають extension prod і extension test typecheck plus extension lint, а extension test-only changes запускають extension test typecheck plus extension lint. Public Plugin SDK або plugin-contract changes expand to extension typecheck, бо extensions залежать від цих core contracts, але Vitest extension sweeps є explicit test work. Release metadata-only version bumps запускають targeted version/config/root-dependency checks. Unknown root/config changes fail safe to all check lanes. -Local changed-test routing живе в `scripts/test-projects.test-support.mjs` і -навмисно дешевший за `check:changed`: direct test edits запускають themselves, -source edits prefer explicit mappings, потім sibling tests і import-graph -dependents. Shared group-room delivery config є одним з explicit mappings: -зміни до group visible-reply config, source reply delivery mode або -message-tool system prompt route through the core reply tests плюс Discord і -Slack delivery regressions, щоб shared default change failed before the first PR +Локальна логіка changed-lane міститься в `scripts/changed-lanes.mjs` і виконується через `scripts/check-changed.mjs`. Цей локальний check gate суворіший щодо architecture boundaries, ніж широка platform scope CI: зміни core production запускають core prod і core test typecheck плюс core lint/guards, зміни лише core test запускають лише core test typecheck плюс core lint, зміни extension production запускають extension prod і extension test typecheck плюс extension lint, а зміни лише extension test запускають extension test typecheck плюс extension lint. Зміни public Plugin SDK або plugin-contract розширюються до extension typecheck, тому що extensions залежать від цих core contracts, але Vitest extension sweeps є явною test work. Release metadata-only version bumps запускають targeted version/config/root-dependency checks. Невідомі root/config changes безпечно переходять до всіх check lanes. +Локальна маршрутизація changed-test міститься в `scripts/test-projects.test-support.mjs` і +навмисно дешевша за `check:changed`: прямі зміни тестів запускають самі себе, +зміни вихідного коду віддають перевагу явним mappings, а потім sibling tests і import-graph +dependents. Shared group-room delivery config є одним із explicit mappings: +зміни group visible-reply config, source reply delivery mode або +message-tool system prompt проходять через core reply tests плюс Discord і +Slack delivery regressions, щоб зміна shared default впала до першого PR push. Використовуйте `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed` лише тоді, коли зміна -достатньо harness-wide, що cheap mapped set не є trustworthy proxy. +настільки широка для harness, що дешевий mapped set не є надійним proxy. -Для перевірки Testbox запускайте з кореня репозиторію й надавайте перевагу свіжому прогрітому боксу для широкого підтвердження. Перед тим як витрачати повільний gate на бокс, який було повторно використано, термін дії якого минув або який щойно повідомив про неочікувано велику синхронізацію, спочатку запустіть `pnpm testbox:sanity` всередині боксу. Перевірка справності швидко завершується з помилкою, коли зникли обов’язкові кореневі файли, як-от `pnpm-lock.yaml`, або коли `git status --short` показує щонайменше 200 відстежуваних видалень. Зазвичай це означає, що стан віддаленої синхронізації не є надійною копією PR. Зупиніть цей бокс і прогрійте свіжий замість налагодження збою продуктового тесту. Для PR із навмисними великими видаленнями встановіть `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1` для цього запуску перевірки справності. `pnpm testbox:run` також завершує локальний виклик Blacksmith CLI, який залишається у фазі синхронізації понад п’ять хвилин без виводу після синхронізації. Установіть `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0`, щоб вимкнути цей захист, або використайте більше значення в мілісекундах для незвично великих локальних diff. +Для перевірки через Testbox запускайте з кореня репозиторію і для широкого підтвердження надавайте перевагу свіжому прогрітому box. Перш ніж витрачати повільний gate на box, який було повторно використано, строк дії якого минув або який щойно повідомив про неочікувано велику синхронізацію, спершу запустіть `pnpm testbox:sanity` всередині box. Sanity-перевірка швидко завершується помилкою, коли зникли потрібні кореневі файли, як-от `pnpm-lock.yaml`, або коли `git status --short` показує щонайменше 200 відстежуваних видалень. Зазвичай це означає, що стан віддаленої синхронізації не є надійною копією PR. Зупиніть цей box і прогрійте свіжий замість того, щоб налагоджувати збій продуктового тесту. Для PR із навмисними великими видаленнями встановіть `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1` для цього sanity-запуску. `pnpm testbox:run` також завершує локальний виклик Blacksmith CLI, який залишається у фазі синхронізації понад п’ять хвилин без виводу після синхронізації. Встановіть `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0`, щоб вимкнути цей захист, або використайте більше значення в мілісекундах для незвично великих локальних diff. -Ручні запуски CI виконують `checks-node-compat-node22` як широке покриття сумісності. Android вмикається окремо для автономного ручного CI через `include_android=true` і завжди ввімкнений для `Full Release Validation`. `Plugin Prerelease` є дорожчим покриттям продукту/пакета, тому це окремий workflow, який запускається `Full Release Validation` або явним оператором. Звичайні pull request, push у `main` і автономні ручні запуски CI тримають цей набір вимкненим. +Ручні CI-dispatch запускають `checks-node-compat-node22` як широке покриття сумісності. Android є опціональним для окремого ручного CI через `include_android=true` і завжди ввімкнений для `Full Release Validation`. `Plugin Prerelease` є дорожчим покриттям продукту/пакета, тому це окремий workflow, який запускається через `Full Release Validation` або явно оператором. Звичайні pull request, push у `main` і окремі ручні CI-dispatch тримають цей набір вимкненим. -Найповільніші сімейства тестів Node розділено або збалансовано так, щоб кожне завдання залишалося невеликим без надмірного резервування runner: контрактні перевірки каналів виконуються як три зважені shard, малі core unit lane об’єднано в пари, auto-reply виконується як чотири збалансовані worker із піддеревом reply, розділеним на shard для agent-runner, dispatch і commands/state-routing, а agentic gateway/plugin configs розподілено між наявними source-only agentic Node завданнями замість очікування на зібрані артефакти. Широкі browser, QA, media та різні plugin тести використовують власні конфіги Vitest замість спільного plugin catch-all. `Plugin Prerelease` балансує тести bundled plugin між вісьмома extension worker; ці extension shard завдання запускають до двох груп plugin config одночасно з одним Vitest worker на групу та більшим heap Node, щоб import-heavy plugin пакети не створювали додаткових CI завдань. Широка agents lane використовує спільний file-parallel планувальник Vitest, бо вона визначається імпортом/плануванням, а не одним повільним тестовим файлом. `runtime-config` виконується разом з infra core-runtime shard, щоб спільний runtime shard не володів хвостом. Include-pattern shards записують timing entries з використанням назви CI shard, тому `.artifacts/vitest-shard-timings.json` може відрізнити цілий config від відфільтрованого shard. `check-additional` тримає package-boundary compile/canary роботу разом і відокремлює архітектуру runtime topology від покриття gateway watch; boundary guard shard запускає свої малі незалежні guard паралельно всередині одного завдання. Gateway watch, тести каналів і core support-boundary shard виконуються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` уже зібрані, зберігаючи їхні старі назви перевірок як легкі verifier jobs, але уникаючи двох додаткових Blacksmith worker і другої черги споживачів артефактів. -Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, а потім збирає Play debug APK. Third-party flavor не має окремого source set або manifest; його unit-test lane усе ще компілює цей flavor із прапорцями BuildConfig для SMS/call-log, уникаючи дублювання завдання пакування debug APK для кожного push, релевантного Android. -GitHub може позначати замінені завдання як `cancelled`, коли новіший push потрапляє в той самий PR або ref `main`. Вважайте це шумом CI, якщо найновіший запуск для того самого ref також не падає. Aggregate shard checks використовують `!cancelled() && always()`, тому вони все ще повідомляють звичайні збої shard, але не стають у чергу після того, як увесь workflow уже було замінено. -Автоматичний ключ конкурентності CI версійовано (`CI-v7-*`), щоб zombie з боку GitHub у старій групі черги не міг нескінченно блокувати новіші запуски main. Ручні full-suite запуски використовують `CI-manual-v1-*` і не скасовують уже запущені виконання. +Найповільніші сімейства тестів Node розділено або збалансовано, щоб кожна job залишалася малою без надмірного резервування runner: контракти каналів запускаються як три зважені shard, малі core unit lanes поєднані в пари, auto-reply запускається як чотири збалансовані worker із розділенням піддерева reply на shard agent-runner, dispatch і commands/state-routing, а agentic Gateway/Plugin-конфіги розподілено між наявними source-only agentic Node jobs замість очікування built artifacts. Широкі browser, QA, media та різні plugin-тести використовують свої dedicated Vitest configs замість спільного plugin catch-all. `Plugin Prerelease` балансує тести bundled Plugin між вісьмома extension workers; ці extension shard jobs запускають до двох plugin config groups одночасно з одним Vitest worker на групу і більшим Node heap, щоб насичені імпортами plugin batches не створювали додаткові CI jobs. Широкий agents lane використовує спільний Vitest file-parallel scheduler, бо він обмежений імпортами/плануванням, а не одним повільним тестовим файлом. `runtime-config` запускається з infra core-runtime shard, щоб спільний runtime shard не володів хвостом. Include-pattern shards записують timing entries з назвою CI shard, тож `.artifacts/vitest-shard-timings.json` може відрізняти цілий config від filtered shard. `check-additional` тримає package-boundary compile/canary роботу разом і відокремлює runtime topology architecture від gateway watch coverage; boundary guard shard запускає свої малі незалежні guards паралельно всередині однієї job. Gateway watch, тести каналів і core support-boundary shard запускаються паралельно всередині `build-artifacts` після того, як `dist/` і `dist-runtime/` уже зібрані, зберігаючи їхні старі назви check як легкі verifier jobs і водночас уникаючи двох додаткових Blacksmith workers та другої artifact-consumer queue. +Android CI запускає і `testPlayDebugUnitTest`, і `testThirdPartyDebugUnitTest`, а потім збирає Play debug APK. Third-party flavor не має окремого source set або manifest; його unit-test lane все одно компілює цей flavor із SMS/call-log BuildConfig flags, уникаючи дубльованої debug APK packaging job на кожному push, що стосується Android. +GitHub може позначати витіснені jobs як `cancelled`, коли новіший push потрапляє на той самий PR або ref `main`. Вважайте це CI-шумом, якщо найновіший run для того самого ref також не падає. Aggregate shard checks використовують `!cancelled() && always()`, тож вони все ще звітують про звичайні shard failures, але не стають у чергу після того, як весь workflow уже було витіснено. +Автоматичний CI concurrency key має версію (`CI-v7-*`), щоб GitHub-side zombie у старій queue group не міг безстроково блокувати новіші main runs. Ручні full-suite runs використовують `CI-manual-v1-*` і не скасовують runs, що виконуються. ## Runner -| Runner | Завдання | +| Runner | Jobs | | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ubuntu-24.04` | `preflight`, швидкі security завдання й aggregate (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі protocol/contract/bundled перевірки, sharded channel contract перевірки, `check` shards окрім lint, `check-additional` shards і aggregate, Node test aggregate verifiers, перевірки документації, Python skills, workflow-sanity, labeler, auto-response; install-smoke preflight також використовує GitHub-hosted Ubuntu, щоб Blacksmith matrix могла стати в чергу раніше | -| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`, нижчі за вагою extension shards, `checks-fast-core`, `checks-node-compat-node22`, `check-prod-types` і `check-test-types` | +| `ubuntu-24.04` | `preflight`, швидкі security jobs і aggregates (`security-scm-fast`, `security-dependency-audit`, `security-fast`), швидкі protocol/contract/bundled checks, sharded channel contract checks, `check` shards окрім lint, `check-additional` shards і aggregates, Node test aggregate verifiers, docs checks, Python skills, workflow-sanity, labeler, auto-response; install-smoke preflight також використовує GitHub-hosted Ubuntu, щоб Blacksmith matrix могла стати в чергу раніше | +| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`, менш вагомі extension shards, `checks-fast-core`, `checks-node-compat-node22`, `check-prod-types` і `check-test-types` | | `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`, build-smoke, Linux Node test shards, bundled plugin test shards, `android` | -| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`, який залишається достатньо чутливим до CPU, тож 8 vCPU коштували більше, ніж заощаджували; install-smoke Docker builds, де час очікування в черзі 32-vCPU коштував більше, ніж заощаджував | +| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`, який залишається достатньо CPU-чутливим, що 8 vCPU коштували більше, ніж заощаджували; install-smoke Docker builds, де час очікування в черзі для 32-vCPU коштував більше, ніж заощаджував | | `blacksmith-16vcpu-windows-2025` | `checks-windows` | -| `blacksmith-6vcpu-macos-latest` | `macos-node` на `openclaw/openclaw`; forks fallback до `macos-latest` | -| `blacksmith-12vcpu-macos-latest` | `macos-swift` на `openclaw/openclaw`; forks fallback до `macos-latest` | +| `blacksmith-6vcpu-macos-latest` | `macos-node` на `openclaw/openclaw`; forks повертаються до `macos-latest` | +| `blacksmith-12vcpu-macos-latest` | `macos-swift` на `openclaw/openclaw`; forks повертаються до `macos-latest` | -## Локальні відповідники +## Локальні еквіваленти ```bash pnpm changed:lanes # inspect the local changed-lane classifier for origin/main...HEAD @@ -373,4 +379,4 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac ## Пов’язане - [Огляд встановлення](/uk/install) -- [Канали випусків](/uk/install/development-channels) +- [Канали релізів](/uk/install/development-channels)