docs/docs/uk/help/testing.md
2026-04-23 19:53:31 +00:00

109 KiB
Raw Blame History

read_when summary title x-i18n
Запуск тестів локально або в CI
Додавання регресійних тестів для багів моделі/провайдера
Налагодження поведінки Gateway + агента
Набір для тестування: набори unit/e2e/live, Docker-ранери та що охоплює кожен тест Тестування
generated_at model provider source_hash source_path workflow
2026-04-23T19:48:40Z gpt-5.4 openai a868c91c94d862b75375a90bc9b5b0d8cf618e81c437e275ef1830c4a3a70c38 help/testing.md 15

OpenClaw має три набори Vitest (unit/integration, e2e, live) і невеликий набір Docker-ранерів. Цей документ — посібник «як ми тестуємо»:

  • Що охоплює кожен набір (і що він навмисно не охоплює).
  • Які команди запускати для типових сценаріїв роботи (локально, перед push, налагодження).
  • Як live-тести знаходять облікові дані та вибирають моделі/провайдерів.
  • Як додавати регресійні тести для реальних проблем із моделями/провайдерами.

Швидкий старт

У більшості випадків:

  • Повний контрольний прогін (очікується перед push): pnpm build && pnpm check && pnpm check:test-types && pnpm test
  • Швидший локальний запуск усього набору на потужній машині: pnpm test:max
  • Прямий цикл спостереження Vitest: pnpm test:watch
  • Прямий таргетинг файлів тепер також маршрутизує шляхи extension/channel: pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts
  • Коли ви ітеруєтеся над одним падінням, спочатку віддавайте перевагу цільовим запускам.
  • QA-сайт на базі Docker: pnpm qa:lab:up
  • QA-лінія на базі Linux VM: pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline

Коли ви торкаєтесь тестів або хочете додаткової впевненості:

  • Контрольний прогін покриття: pnpm test:coverage
  • Набір E2E: pnpm test:e2e

Під час налагодження реальних провайдерів/моделей (потрібні реальні облікові дані):

  • Набір live (моделі + probe Gateway для інструментів/зображень): pnpm test:live
  • Точково запустити один live-файл у тихому режимі: pnpm test:live -- src/agents/models.profiles.live.test.ts
  • Docker-прогін live-моделей: pnpm test:docker:live-models
    • Кожна вибрана модель тепер виконує текстовий хід і невеликий probe у стилі читання файлу. Моделі, у чиїх метаданих вказано вхід image, також виконують мініатюрний хід із зображенням. Вимкніть додаткові probe через OPENCLAW_LIVE_MODEL_FILE_PROBE=0 або OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0, коли ізолюєте збої провайдера.
    • Покриття в CI: щоденні OpenClaw Scheduled Live And E2E Checks і ручні OpenClaw Release Checks обидва викликають повторно використовуваний workflow live/E2E з include_live_suites: true, який включає окремі матричні job-и Docker live-моделей, розшардовані за провайдером.
    • Для точкових повторних запусків у CI dispatch-ніть OpenClaw Live And E2E Checks (Reusable) з include_live_suites: true і live_models_only: true.
    • Додавайте нові високосигнальні секрети провайдерів до scripts/ci-hydrate-live-auth.sh, а також до .github/workflows/openclaw-live-and-e2e-checks-reusable.yml і його запланованих/релізних викликів.
  • Димовий тест вартості Moonshot/Kimi: коли встановлено MOONSHOT_API_KEY, виконайте openclaw models list --provider moonshot --json, а потім ізольований openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json для moonshot/kimi-k2.6. Переконайтеся, що JSON повідомляє Moonshot/K2.6, а транскрипт асистента зберігає нормалізоване usage.cost.

Порада: коли вам потрібен лише один збійний випадок, віддавайте перевагу звуженню live-тестів через env-змінні allowlist, описані нижче.

Спеціальні QA-ранери

Ці команди розташовані поруч з основними наборами тестів, коли вам потрібен реалізм qa-lab:

CI запускає QA Lab в окремих workflow. Parity gate виконується для відповідних PR і з ручного dispatch із mock-провайдерами. QA-Lab - All Lanes виконується щоночі на main і з ручного dispatch з mock parity gate, live-лінією Matrix та live-лінією Telegram, керованою Convex, як паралельними job-ами. OpenClaw Release Checks запускає ті самі лінії перед схваленням релізу.

  • pnpm openclaw qa suite
    • Запускає сценарії QA з репозиторію безпосередньо на хості.
    • За замовчуванням запускає кілька вибраних сценаріїв паралельно з ізольованими воркерами Gateway. qa-channel за замовчуванням має concurrency 4 (обмежується кількістю вибраних сценаріїв). Використовуйте --concurrency <count>, щоб налаштувати кількість воркерів, або --concurrency 1 для старішої послідовної лінії.
    • Завершується з ненульовим кодом, якщо будь-який сценарій падає. Використовуйте --allow-failures, коли вам потрібні артефакти без коду завершення з помилкою.
    • Підтримує режими провайдера live-frontier, mock-openai і aimock. aimock запускає локальний сервер провайдера на базі AIMock для експериментального покриття фікстур і протокольних mock-ів, не замінюючи орієнтовану на сценарії лінію mock-openai.
  • pnpm openclaw qa suite --runner multipass
    • Запускає той самий набір QA усередині одноразової Linux VM Multipass.
    • Зберігає ту саму поведінку вибору сценаріїв, що й qa suite на хості.
    • Повторно використовує ті самі прапорці вибору провайдера/моделі, що й qa suite.
    • Live-запуски передають підтримувані вхідні дані автентифікації QA, практичні для гостьової системи: ключі провайдерів на основі env, шлях до конфігурації QA live provider та CODEX_HOME, якщо він присутній.
    • Каталоги виводу мають залишатися в межах кореня репозиторію, щоб гостьова система могла записувати назад через змонтований workspace.
    • Записує звичайний QA-звіт + підсумок, а також журнали Multipass у .artifacts/qa-e2e/....
  • pnpm qa:lab:up
    • Запускає QA-сайт на базі Docker для QA-роботи в операторському стилі.
  • pnpm test:docker:npm-onboard-channel-agent
    • Збирає npm tarball із поточного checkout, глобально встановлює його в Docker, виконує неінтерактивне налаштування з API-ключем OpenAI, за замовчуванням налаштовує Telegram, перевіряє, що ввімкнення plugin встановлює runtime-залежності за потреби, запускає doctor і виконує один локальний хід агента проти mock-endpoint OpenAI.
    • Використовуйте OPENCLAW_NPM_ONBOARD_CHANNEL=discord, щоб запустити ту саму лінію встановлення з пакета з Discord.
  • pnpm test:docker:bundled-channel-deps
    • Пакує та встановлює поточну збірку OpenClaw у Docker, запускає Gateway зі сконфігурованим OpenAI, а потім вмикає bundled channel/plugins через редагування конфігурації.
    • Перевіряє, що виявлення налаштування залишає runtime-залежності несконфігурованих plugins відсутніми, що перший сконфігурований запуск Gateway або doctor встановлює runtime-залежності кожного bundled plugin за потреби, і що другий перезапуск не перевстановлює залежності, які вже були активовані.
    • Також установлює відому старішу npm-базову версію, вмикає Telegram перед запуском openclaw update --tag <candidate>, і перевіряє, що doctor кандидата після оновлення відновлює runtime-залежності bundled channel без postinstall-відновлення з боку harness.
  • pnpm openclaw qa aimock
    • Запускає лише локальний сервер провайдера AIMock для прямого димового тестування протоколу.
  • pnpm openclaw qa matrix
    • Запускає live-лінію QA Matrix проти одноразового homeserver Tuwunel на базі Docker.
    • Цей хост QA сьогодні призначений лише для repo/dev. Упаковані встановлення OpenClaw не постачають qa-lab, тому вони не надають openclaw qa.
    • Checkout-и репозиторію завантажують bundled runner безпосередньо; окремий крок встановлення plugin не потрібен.
    • Створює трьох тимчасових користувачів Matrix (driver, sut, observer) плюс одну приватну кімнату, а потім запускає дочірній QA gateway із реальним Matrix plugin як транспортом SUT.
    • За замовчуванням використовує зафіксований стабільний образ Tuwunel ghcr.io/matrix-construct/tuwunel:v1.5.1. Перевизначайте через OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE, коли потрібно протестувати інший образ.
    • Matrix не надає спільних прапорців джерела облікових даних, оскільки лінія локально створює одноразових користувачів.
    • Записує QA-звіт Matrix, підсумок, артефакт observed-events і комбінований журнал виводу stdout/stderr у .artifacts/qa-e2e/....
  • pnpm openclaw qa telegram
    • Запускає live-лінію QA Telegram проти реальної приватної групи, використовуючи токени бота driver і SUT з env.
    • Потребує OPENCLAW_QA_TELEGRAM_GROUP_ID, OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN і OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN. Ідентифікатор групи має бути числовим Telegram chat id.
    • Підтримує --credential-source convex для спільних пулованих облікових даних. За замовчуванням використовуйте режим env або встановіть OPENCLAW_QA_CREDENTIAL_SOURCE=convex, щоб увімкнути пуловані оренди.
    • Завершується з ненульовим кодом, якщо будь-який сценарій падає. Використовуйте --allow-failures, коли вам потрібні артефакти без коду завершення з помилкою.
    • Потребує двох різних ботів в одній приватній групі, причому бот SUT має мати Telegram username.
    • Для стабільного спостереження bot-to-bot увімкніть режим Bot-to-Bot Communication Mode у @BotFather для обох ботів і переконайтеся, що бот driver може спостерігати трафік ботів у групі.
    • Записує QA-звіт Telegram, підсумок і артефакт observed-messages у .artifacts/qa-e2e/.... Сценарії з відповідями включають RTT від запиту надсилання driver до спостереженої відповіді SUT.

Live-транспортні лінії використовують єдиний стандартний контракт, щоб нові транспорти не розходилися:

qa-channel залишається широким синтетичним набором QA і не є частиною матриці покриття live-транспорту.

Лінія Canary Гейтінг згадок Блокування allowlist Відповідь верхнього рівня Відновлення після перезапуску Подальша відповідь у треді Ізоляція тредів Спостереження реакцій Команда help
Matrix x x x x x x x x
Telegram x x

Спільні облікові дані Telegram через Convex (v1)

Коли для openclaw qa telegram увімкнено --credential-source convex (або OPENCLAW_QA_CREDENTIAL_SOURCE=convex), QA lab отримує ексклюзивну оренду з пулу на базі Convex, надсилає Heartbeat для цієї оренди, поки лінія виконується, і звільняє оренду під час завершення роботи.

Еталонний каркас проєкту Convex:

  • qa/convex-credential-broker/

Обов’язкові env-змінні:

  • OPENCLAW_QA_CONVEX_SITE_URL (наприклад, https://your-deployment.convex.site)
  • Один секрет для вибраної ролі:
    • OPENCLAW_QA_CONVEX_SECRET_MAINTAINER для maintainer
    • OPENCLAW_QA_CONVEX_SECRET_CI для ci
  • Вибір ролі облікових даних:
    • CLI: --credential-role maintainer|ci
    • Env за замовчуванням: OPENCLAW_QA_CREDENTIAL_ROLE (у CI за замовчуванням ci, інакше maintainer)

Необов’язкові env-змінні:

  • OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS (за замовчуванням 1200000)
  • OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS (за замовчуванням 30000)
  • OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS (за замовчуванням 90000)
  • OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS (за замовчуванням 15000)
  • OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX (за замовчуванням /qa-credentials/v1)
  • OPENCLAW_QA_CREDENTIAL_OWNER_ID (необов’язковий trace id)
  • OPENCLAW_QA_ALLOW_INSECURE_HTTP=1 дозволяє loopback http:// URL Convex лише для локальної розробки.

OPENCLAW_QA_CONVEX_SITE_URL у звичайному режимі роботи має використовувати https://.

Адміністративні команди для супровідників (додавання/видалення/список пулу) вимагають саме OPENCLAW_QA_CONVEX_SECRET_MAINTAINER.

CLI-допоміжні команди для супровідників:

pnpm openclaw qa credentials add --kind telegram --payload-file qa/telegram-credential.json
pnpm openclaw qa credentials list --kind telegram
pnpm openclaw qa credentials remove --credential-id <credential-id>

Використовуйте --json для машинозчитуваного виводу в скриптах і утилітах CI.

Контракт endpoint за замовчуванням (OPENCLAW_QA_CONVEX_SITE_URL + /qa-credentials/v1):

  • POST /acquire
    • Запит: { kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }
    • Успіх: { status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }
    • Вичерпано/можна повторити: { status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }
  • POST /heartbeat
    • Запит: { kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }
    • Успіх: { status: "ok" } (або порожній 2xx)
  • POST /release
    • Запит: { kind, ownerId, actorRole, credentialId, leaseToken }
    • Успіх: { status: "ok" } (або порожній 2xx)
  • POST /admin/add (лише секрет maintainer)
    • Запит: { kind, actorId, payload, note?, status? }
    • Успіх: { status: "ok", credential }
  • POST /admin/remove (лише секрет maintainer)
    • Запит: { credentialId, actorId }
    • Успіх: { status: "ok", changed, credential }
    • Захист активної оренди: { status: "error", code: "LEASE_ACTIVE", ... }
  • POST /admin/list (лише секрет maintainer)
    • Запит: { kind?, status?, includePayload?, limit? }
    • Успіх: { status: "ok", credentials, count }

Форма payload для типу Telegram:

  • { groupId: string, driverToken: string, sutToken: string }
  • groupId має бути рядком із числовим Telegram chat id.
  • admin/add перевіряє цю форму для kind: "telegram" і відхиляє некоректні payload.

Додавання каналу до QA

Додавання каналу до markdown-системи QA вимагає рівно двох речей:

  1. Транспортного адаптера для каналу.
  2. Набору сценаріїв, який перевіряє контракт каналу.

Не додавайте новий кореневий QA-командний рівень, якщо спільний хост qa-lab може керувати цим потоком.

qa-lab відповідає за спільну хостову механіку:

  • кореневу команду openclaw qa
  • запуск і завершення suite
  • concurrency воркерів
  • запис артефактів
  • генерацію звітів
  • виконання сценаріїв
  • compatibility aliases для старіших сценаріїв qa-channel

Runner plugins відповідають за транспортний контракт:

  • як openclaw qa <runner> монтується під спільним коренем qa
  • як Gateway налаштовується для цього транспорту
  • як перевіряється готовність
  • як інжектяться вхідні події
  • як спостерігаються вихідні повідомлення
  • як надаються транскрипти й нормалізований стан транспорту
  • як виконуються дії, підтримувані транспортом
  • як обробляється транспортно-специфічний reset або cleanup

Мінімальний поріг впровадження нового каналу такий:

  1. Залишайте qa-lab власником спільного кореня qa.
  2. Реалізуйте transport runner на спільному host seam qa-lab.
  3. Залишайте транспортно-специфічну механіку всередині runner plugin або harness каналу.
  4. Монтуйте runner як openclaw qa <runner> замість реєстрації конкуруючої кореневої команди. Runner plugins повинні оголошувати qaRunners у openclaw.plugin.json і експортувати відповідний масив qaRunnerCliRegistrations із runtime-api.ts. Тримайте runtime-api.ts легким; ліниве виконання CLI і runner має залишатися за окремими entrypoint.
  5. Створюйте або адаптуйте markdown-сценарії в тематичних каталогах qa/scenarios/.
  6. Використовуйте загальні scenario helpers для нових сценаріїв.
  7. Зберігайте працездатність наявних compatibility aliases, якщо тільки в репозиторії не виконується навмисна міграція.

Правило прийняття рішення суворе:

  • Якщо поведінку можна один раз виразити в qa-lab, розміщуйте її в qa-lab.
  • Якщо поведінка залежить від одного транспорту каналу, залишайте її в цьому runner plugin або plugin harness.
  • Якщо сценарію потрібна нова можливість, якою може користуватися більше ніж один канал, додавайте загальний helper замість channel-specific гілки в suite.ts.
  • Якщо поведінка має сенс лише для одного транспорту, залишайте сценарій transport-specific і явно фіксуйте це в контракті сценарію.

Бажані назви generic helper для нових сценаріїв:

  • waitForTransportReady
  • waitForChannelReady
  • injectInboundMessage
  • injectOutboundMessage
  • waitForTransportOutboundMessage
  • waitForChannelOutboundMessage
  • waitForNoTransportOutbound
  • getTransportSnapshot
  • readTransportMessage
  • readTransportTranscript
  • formatTransportTranscript
  • resetTransport

Compatibility aliases залишаються доступними для наявних сценаріїв, зокрема:

  • waitForQaChannelReady
  • waitForOutboundMessage
  • waitForNoOutbound
  • formatConversationTranscript
  • resetBus

Нова робота над каналами має використовувати generic helper names. Compatibility aliases існують, щоб уникнути міграції в стилі flag day, а не як модель для створення нових сценаріїв.

Набори тестів (що де запускається)

Сприймайте набори як «зростання реалізму» (і зростання нестабільності/вартості):

Unit / integration (за замовчуванням)

  • Команда: pnpm test
  • Конфігурація: нетаргетовані запуски використовують набір шардів vitest.full-*.config.ts і можуть розгортати multi-project шарди в per-project конфігурації для паралельного планування
  • Файли: core/unit inventory у src/**/*.test.ts, packages/**/*.test.ts, test/**/*.test.ts і whitelist node-тести ui, які покриває vitest.unit.config.ts
  • Обсяг:
    • Чисті unit-тести
    • In-process integration-тести (автентифікація Gateway, маршрутизація, інструменти, парсинг, конфігурація)
    • Детерміновані регресії для відомих багів
  • Очікування:
    • Запускається в CI

    • Реальні ключі не потрібні

    • Має бути швидким і стабільним - Нетаргетовані запуски pnpm test використовують дванадцять менших shard-конфігурацій (core-unit-fast, core-unit-src, core-unit-security, core-unit-ui, core-unit-support, core-support-boundary, core-contracts, core-bundled, core-runtime, agentic, auto-reply, extensions) замість одного гігантського native root-project process. Це зменшує піковий RSS на завантажених машинах і не дає роботі auto-reply/extension виснажувати не пов’язані набори. - pnpm test --watch як і раніше використовує native root-граф проєкту vitest.config.ts, оскільки цикл спостереження з multi-shard не є практичним. - pnpm test, pnpm test:watch і pnpm test:perf:imports спочатку маршрутизують явні target файлу/каталогу через scoped lanes, тож pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts уникає повної вартості запуску root project. - pnpm test:changed розгортає змінені git-шляхи в ті самі scoped lanes, коли diff торкається лише routable source/test файлів; редагування config/setup, як і раніше, повертаються до широкого повторного запуску root project. - pnpm check:changed — це стандартний розумний локальний контрольний прогін для вузької роботи. Він класифікує diff на core, core tests, extensions, extension tests, apps, docs, release metadata і tooling, а потім запускає відповідні lanes typecheck/lint/test. Зміни в публічному Plugin SDK і plugin-contract включають перевірку extensions, оскільки extensions залежать від цих core-контрактів. Оновлення версій, що стосуються лише release metadata, запускають таргетовані перевірки version/config/root-dependency замість повного набору, із захистом, який відхиляє зміни package поза полем версії верхнього рівня. - Полегшені з точки зору імпортів unit-тести для agents, commands, plugins, helper-функцій auto-reply, plugin-sdk та подібних чистих utility-областей маршрутизуються через lane unit-fast, яка пропускає test/setup-openclaw-runtime.ts; файли зі stateful/runtime-heavy поведінкою залишаються на наявних lanes. - Вибрані helper source-файли plugin-sdk і commands також відображають changed-mode запуски на явні sibling-тести в цих легких lanes, тож редагування helper уникають повторного запуску повного важкого набору для цього каталогу. - auto-reply має три виділені bucket: helper-функції core верхнього рівня, integration-тести верхнього рівня reply.* і піддерево src/auto-reply/reply/**. Це прибирає найважчу роботу harness reply із дешевих тестів status/chunk/token.

      - Коли ви змінюєте вхідні дані для виявлення message-tool або runtime-контекст Compaction, зберігайте обидва рівні покриття. - Додавайте вузько сфокусовані helper-регресії для чистих меж маршрутизації та нормалізації. - Підтримуйте в робочому стані integration suites embedded runner: `src/agents/pi-embedded-runner/compact.hooks.test.ts`, `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` і `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`. - Ці набори перевіряють, що scoped id і поведінка Compaction, як і раніше, проходять через реальні шляхи `run.ts` / `compact.ts`; helper-only тести не є достатньою заміною для цих integration-шляхів. - Базова конфігурація Vitest за замовчуванням використовує `threads`. - Спільна конфігурація Vitest фіксує `isolate: false` і використовує non-isolated runner в root projects, а також у конфігураціях e2e і live. - Root UI lane зберігає своє налаштування `jsdom` й optimizer, але також працює на спільному non-isolated runner. - Кожен shard `pnpm test` успадковує ті самі значення за замовчуванням `threads` + `isolate: false` зі спільної конфігурації Vitest. - `scripts/run-vitest.mjs` за замовчуванням додає `--no-maglev` для дочірніх Node-процесів Vitest, щоб зменшити churn компіляції V8 під час великих локальних запусків. Встановіть `OPENCLAW_VITEST_ENABLE_MAGLEV=1`, щоб порівняти зі стандартною поведінкою V8. - `pnpm changed:lanes` показує, які архітектурні lanes запускає diff. - Pre-commit hook запускає `pnpm check:changed --staged` після staged formatting/linting, тож commit-и лише для core не оплачують вартість тестів extension, якщо вони не торкаються публічних контрактів, орієнтованих на extension. Commit-и лише з release metadata залишаються на таргетованій lane version/config/root-dependency. - Якщо точний staged-набір змін уже був перевірений рівними або сильнішими контрольними прогоном, використовуйте `scripts/committer --fast "" `, щоб пропустити лише повторний запуск changed-scope hook. Staged format/lint усе одно виконуються. Згадайте завершені контрольні прогони у вашому handoff. Це також прийнятно після повторного запуску ізольованого flaky hook failure, який пройшов із scoped proof. - `pnpm test:changed` маршрутизується через scoped lanes, коли змінені шляхи чисто відображаються на менший набір. - `pnpm test:max` і `pnpm test:changed:max` зберігають ту саму поведінку маршрутизації, лише з вищим лімітом воркерів. - Автоматичне масштабування локальних воркерів навмисно є консервативним і знижує навантаження, коли середнє навантаження хоста вже високе, тож кілька паралельних запусків Vitest за замовчуванням завдають менше шкоди. - Базова конфігурація Vitest позначає файли projects/config як `forceRerunTriggers`, щоб reruns у changed-mode залишалися коректними, коли змінюється wiring тестів. - Конфігурація зберігає `OPENCLAW_VITEST_FS_MODULE_CACHE` увімкненим на підтримуваних хостах; встановіть `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`, якщо хочете одну явну локацію кешу для прямого profiling. - `pnpm test:perf:imports` вмикає звітність Vitest про тривалість імпорту плюс вивід import-breakdown. - `pnpm test:perf:imports:changed` звужує той самий вигляд profiling до файлів, змінених відносно `origin/main`. - `pnpm test:perf:changed:bench -- --ref ` порівнює маршрутизований `test:changed` із native root-project шляхом для цього закоміченого diff і виводить wall time плюс macOS max RSS. - `pnpm test:perf:changed:bench -- --worktree` бенчмаркує поточне брудне дерево, маршрутизуючи список змінених файлів через `scripts/test-projects.mjs` і root-конфігурацію Vitest. - `pnpm test:perf:profile:main` записує CPU-профіль main-thread для витрат Vitest/Vite на startup і transform. - `pnpm test:perf:profile:runner` записує CPU+heap профілі runner для unit-набору з вимкненим file parallelism.

Stability (Gateway)

  • Команда: pnpm test:stability:gateway
  • Конфігурація: vitest.gateway.config.ts, примусово один воркер
  • Обсяг:
    • Запускає реальний loopback Gateway з увімкненою діагностикою за замовчуванням
    • Пропускає синтетичне churn повідомлень gateway, пам’яті та великих payload через діагностичний шлях подій
    • Виконує запити до diagnostics.stability через WS RPC Gateway
    • Покриває helper-функції збереження diagnostic stability bundle
    • Перевіряє, що recorder залишається обмеженим, синтетичні вибірки RSS залишаються в межах бюджету тиску, а глибини черг для кожної сесії знову знижуються до нуля
  • Очікування:
    • Безпечно для CI і без ключів
    • Вузька lane для подальшої роботи над stability-регресіями, а не заміна повного набору Gateway

E2E (димове тестування gateway)

  • Команда: pnpm test:e2e
  • Конфігурація: vitest.e2e.config.ts
  • Файли: src/**/*.e2e.test.ts, test/**/*.e2e.test.ts і bundled-plugin E2E-тести в extensions/
  • Значення runtime за замовчуванням:
    • Використовує Vitest threads з isolate: false, як і решта репозиторію.
    • Використовує адаптивну кількість воркерів (CI: до 2, локально: 1 за замовчуванням).
    • За замовчуванням запускається в тихому режимі, щоб зменшити накладні витрати на console I/O.
  • Корисні перевизначення:
    • OPENCLAW_E2E_WORKERS=<n>, щоб примусово задати кількість воркерів (обмежено 16).
    • OPENCLAW_E2E_VERBOSE=1, щоб знову ввімкнути докладний вивід у консоль.
  • Обсяг:
    • Наскрізна поведінка gateway з кількома інстансами
    • Поверхні WebSocket/HTTP, pairing Node і важча мережева взаємодія
  • Очікування:
    • Запускається в CI (коли ввімкнено в pipeline)
    • Реальні ключі не потрібні
    • Більше рухомих частин, ніж в unit-тестах (може бути повільнішим)

E2E: димове тестування backend OpenShell

  • Команда: pnpm test:e2e:openshell
  • Файл: extensions/openshell/src/backend.e2e.test.ts
  • Обсяг:
    • Запускає ізольований gateway OpenShell на хості через Docker
    • Створює sandbox із тимчасового локального Dockerfile
    • Перевіряє backend OpenShell в OpenClaw через реальні sandbox ssh-config + SSH exec
    • Перевіряє поведінку файлової системи в remote-canonical режимі через bridge файлової системи sandbox
  • Очікування:
    • Лише за явним увімкненням; не входить до стандартного запуску pnpm test:e2e
    • Потребує локального CLI openshell і працюючого Docker daemon
    • Використовує ізольовані HOME / XDG_CONFIG_HOME, а потім знищує test gateway і sandbox
  • Корисні перевизначення:
    • OPENCLAW_E2E_OPENSHELL=1, щоб увімкнути тест під час ручного запуску ширшого набору e2e
    • OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell, щоб вказати нестандартний бінарний файл CLI або wrapper script

Live (реальні провайдери + реальні моделі)

  • Команда: pnpm test:live
  • Конфігурація: vitest.live.config.ts
  • Файли: src/**/*.live.test.ts, test/**/*.live.test.ts і bundled-plugin live-тести в extensions/
  • За замовчуванням: увімкнено через pnpm test:live (встановлює OPENCLAW_LIVE_TEST=1)
  • Обсяг:
    • «Чи справді цей провайдер/модель працює сьогодні з реальними обліковими даними?»
    • Виявлення змін форматів провайдерів, особливостей виклику інструментів, проблем автентифікації та поведінки rate limit
  • Очікування:
    • За задумом нестабільний для CI (реальні мережі, реальні політики провайдерів, квоти, збої)
    • Коштує грошей / витрачає rate limits
    • Краще запускати звужені підмножини, а не «все підряд»
  • Live-запуски використовують ~/.profile, щоб підхопити відсутні API-ключі.
  • За замовчуванням live-запуски все одно ізолюють HOME і копіюють матеріали config/auth у тимчасовий test home, щоб unit-фікстури не могли змінити ваш реальний ~/.openclaw.
  • Встановлюйте OPENCLAW_LIVE_USE_REAL_HOME=1 лише тоді, коли вам навмисно потрібно, щоб live-тести використовували ваш реальний домашній каталог.
  • pnpm test:live тепер за замовчуванням працює в тихішому режимі: він залишає вивід прогресу [live] ..., але приглушує додаткове повідомлення про ~/.profile і вимикає журнали bootstrap gateway/шум Bonjour. Встановіть OPENCLAW_LIVE_TEST_QUIET=0, якщо хочете повернути повні журнали запуску.
  • Ротація API-ключів (специфічна для провайдера): встановлюйте *_API_KEYS у форматі з комами/крапками з комою або *_API_KEY_1, *_API_KEY_2 (наприклад, OPENAI_API_KEYS, ANTHROPIC_API_KEYS, GEMINI_API_KEYS) або використовуйте перевизначення для live через OPENCLAW_LIVE_*_KEY; тести повторюють спробу у відповідь на rate limit.
  • Вивід прогресу/Heartbeat:
    • Live-набори тепер виводять рядки прогресу в stderr, тож довгі виклики провайдерів помітно активні навіть тоді, коли перехоплення консолі Vitest тихе.
    • vitest.live.config.ts вимикає перехоплення консолі Vitest, щоб рядки прогресу провайдера/gateway одразу передавалися під час live-запусків.
    • Налаштовуйте Heartbeat для прямої моделі через OPENCLAW_LIVE_HEARTBEAT_MS.
    • Налаштовуйте Heartbeat для gateway/probe через OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS.

Який набір мені запускати?

Скористайтеся цією таблицею рішень:

  • Редагуєте логіку/тести: запускайте pnpm test (і pnpm test:coverage, якщо ви багато що змінили)
  • Торкаєтеся мережевої взаємодії gateway / протоколу WS / pairing: додайте pnpm test:e2e
  • Налагоджуєте «мій бот не працює» / специфічні для провайдера збої / виклик інструментів: запускайте звужений pnpm test:live

Live: перевірка можливостей Android Node

  • Тест: src/gateway/android-node.capabilities.live.test.ts
  • Скрипт: pnpm android:test:integration
  • Мета: викликати кожну команду, яку наразі рекламує підключений Android Node, і перевірити поведінку контракту команд.
  • Обсяг:
    • Попередньо підготовлене/ручне налаштування (набір не встановлює, не запускає і не виконує pairing app).
    • Перевірка node.invoke gateway команда за командою для вибраного Android Node.
  • Необхідне попереднє налаштування:
    • Android app уже підключено та спарено з gateway.
    • App утримується на передньому плані.
    • Для можливостей, які ви очікуєте успішно пройти, надано дозволи/згоду на захоплення.
  • Необов’язкові перевизначення цілі:
    • OPENCLAW_ANDROID_NODE_ID або OPENCLAW_ANDROID_NODE_NAME.
    • OPENCLAW_ANDROID_GATEWAY_URL / OPENCLAW_ANDROID_GATEWAY_TOKEN / OPENCLAW_ANDROID_GATEWAY_PASSWORD.
  • Повні подробиці налаштування Android: Android App

Live: димове тестування моделі (ключі профілів)

Live-тести поділено на два шари, щоб можна було ізолювати збої:

  • «Пряма модель» показує, що провайдер/модель взагалі може відповідати з наданим ключем.
  • «Димове тестування Gateway» показує, що повний pipeline gateway+agent працює для цієї моделі (сесії, історія, інструменти, політика sandbox тощо).

Шар 1: Пряме завершення моделі (без gateway)

  • Тест: src/agents/models.profiles.live.test.ts
  • Мета:
    • Перелічити виявлені моделі
    • Використати getApiKeyForModel, щоб вибрати моделі, для яких у вас є облікові дані
    • Виконати невелике completion для кожної моделі (і цільові регресії там, де потрібно)
  • Як увімкнути:
    • pnpm test:live (або OPENCLAW_LIVE_TEST=1, якщо викликаєте Vitest напряму)
  • Встановіть OPENCLAW_LIVE_MODELS=modern (або all, псевдонім для modern), щоб справді запустити цей набір; інакше його буде пропущено, щоб pnpm test:live залишався зосередженим на димовому тестуванні gateway
  • Як вибирати моделі:
    • OPENCLAW_LIVE_MODELS=modern, щоб запустити modern allowlist (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)
    • OPENCLAW_LIVE_MODELS=all — псевдонім для modern allowlist
    • або OPENCLAW_LIVE_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,..." (allowlist через кому)
    • Прогони modern/all за замовчуванням обмежені відібраною high-signal межею; встановіть OPENCLAW_LIVE_MAX_MODELS=0 для вичерпного прогону modern або додатне число для меншого ліміту.
  • Як вибирати провайдерів:
    • OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli" (allowlist через кому)
  • Звідки беруться ключі:
    • За замовчуванням: сховище профілів і env fallback-и
    • Встановіть OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1, щоб примусово використовувати лише сховище профілів
  • Навіщо це існує:
    • Відокремлює «API провайдера зламане / ключ недійсний» від «pipeline агента gateway зламаний»
    • Містить невеликі ізольовані регресії (приклад: OpenAI Responses/Codex Responses reasoning replay + потоки tool-call)

Шар 2: Димове тестування Gateway + dev agent (що насправді робить "@openclaw")

  • Тест: src/gateway/gateway-models.profiles.live.test.ts
  • Мета:
    • Підняти in-process gateway
    • Створити/оновити сесію agent:dev:* (перевизначення моделі для кожного запуску)
    • Ітеруватися моделями-з-ключами і перевіряти:
      • «змістовну» відповідь (без інструментів)
      • що працює реальний виклик інструмента (read probe)
      • необов’язкові додаткові probe інструментів (exec+read probe)
      • що регресійні шляхи OpenAI (лише tool-call → подальша відповідь) і далі працюють
  • Подробиці probe (щоб ви могли швидко пояснювати збої):
    • read probe: тест записує файл із nonce у workspace і просить агента read його та повернути nonce.
    • exec+read probe: тест просить агента через exec записати nonce у тимчасовий файл, а потім read-ом прочитати його назад.
    • image probe: тест прикріплює згенерований PNG (cat + випадковий код) і очікує, що модель поверне cat <CODE>.
    • Посилання на реалізацію: src/gateway/gateway-models.profiles.live.test.ts і src/gateway/live-image-probe.ts.
  • Як увімкнути:
    • pnpm test:live (або OPENCLAW_LIVE_TEST=1, якщо викликаєте Vitest напряму)
  • Як вибирати моделі:
    • За замовчуванням: modern allowlist (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)
    • OPENCLAW_LIVE_GATEWAY_MODELS=all — псевдонім для modern allowlist
    • Або встановіть OPENCLAW_LIVE_GATEWAY_MODELS="provider/model" (або список через кому), щоб звузити
    • Прогони modern/all gateway за замовчуванням обмежені відібраною high-signal межею; встановіть OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0 для вичерпного прогону modern або додатне число для меншого ліміту.
  • Як вибирати провайдерів (уникати «усе з OpenRouter»):
    • OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax" (allowlist через кому)
  • Probe інструментів і зображень у цьому live-тесті завжди ввімкнені:
    • read probe + exec+read probe (навантаження на інструменти)
    • image probe запускається, коли модель рекламує підтримку вхідних зображень
    • Потік (на високому рівні):
      • Тест генерує крихітний PNG із “CAT” + випадковим кодом (src/gateway/live-image-probe.ts)
      • Надсилає його через agent attachments: [{ mimeType: "image/png", content: "<base64>" }]
      • Gateway парсить вкладення в images[] (src/gateway/server-methods/agent.ts + src/gateway/chat-attachments.ts)
      • Embedded agent передає моделі мультимодальне повідомлення користувача
      • Перевірка: відповідь містить cat + код (допуск OCR: незначні помилки дозволені)

Порада: щоб побачити, що саме ви можете тестувати на своїй машині (і точні id provider/model), виконайте:

openclaw models list
openclaw models list --json

Live: димове тестування backend CLI (Claude, Codex, Gemini або інші локальні CLI)

  • Тест: src/gateway/gateway-cli-backend.live.test.ts
  • Мета: перевірити pipeline Gateway + agent, використовуючи локальний backend CLI, не торкаючись вашої стандартної конфігурації.
  • Значення димового тестування backend за замовчуванням для конкретного backend містяться у визначенні cli-backend.ts extension-власника.
  • Увімкнення:
    • pnpm test:live (або OPENCLAW_LIVE_TEST=1, якщо викликаєте Vitest напряму)
    • OPENCLAW_LIVE_CLI_BACKEND=1
  • Значення за замовчуванням:
    • Провайдер/модель за замовчуванням: claude-cli/claude-sonnet-4-6
    • Поведінка команди/аргументів/зображень береться з метаданих plugin-а backend CLI-власника.
  • Перевизначення (необов’язково):
    • OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.5"
    • OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/codex"
    • OPENCLAW_LIVE_CLI_BACKEND_ARGS='["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]'
    • OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1, щоб надіслати реальне вкладення-зображення (шляхи інжектяться в prompt).
    • OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image", щоб передавати шляхи до файлів зображень як аргументи CLI замість інжекції в prompt.
    • OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat" (або "list"), щоб керувати способом передавання аргументів зображень, коли встановлено IMAGE_ARG.
    • OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1, щоб надіслати другий хід і перевірити потік resume.
    • OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0, щоб вимкнути стандартний probe безперервності тієї самої сесії Claude Sonnet -> Opus (встановіть 1, щоб примусово його ввімкнути, коли вибрана модель підтримує ціль перемикання).

Приклад:

OPENCLAW_LIVE_CLI_BACKEND=1 \
  OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.5" \
  pnpm test:live src/gateway/gateway-cli-backend.live.test.ts

Рецепт Docker:

pnpm test:docker:live-cli-backend

Рецепти Docker для окремих провайдерів:

pnpm test:docker:live-cli-backend:claude
pnpm test:docker:live-cli-backend:claude-subscription
pnpm test:docker:live-cli-backend:codex
pnpm test:docker:live-cli-backend:gemini

Примітки:

  • Docker-ранер розміщений у scripts/test-live-cli-backend-docker.sh.
  • Він запускає димове тестування live CLI-backend усередині Docker-образу репозиторію від імені непривілейованого користувача node.
  • Він визначає метадані димового тестування CLI з extension-власника, а потім встановлює відповідний Linux-пакет CLI (@anthropic-ai/claude-code, @openai/codex або @google/gemini-cli) у кешований доступний для запису префікс за адресою OPENCLAW_DOCKER_CLI_TOOLS_DIR (за замовчуванням: ~/.cache/openclaw/docker-cli-tools).
  • pnpm test:docker:live-cli-backend:claude-subscription вимагає переносиму OAuth-автентифікацію підписки Claude Code через або ~/.claude/.credentials.json із claudeAiOauth.subscriptionType, або CLAUDE_CODE_OAUTH_TOKEN із claude setup-token. Спочатку він доводить прямий запуск claude -p у Docker, а потім виконує два ходи Gateway CLI-backend без збереження env-змінних API-ключа Anthropic. Ця лінія підписки за замовчуванням вимикає probe Claude MCP/tool і image, оскільки Claude наразі маршрутизує використання сторонніх застосунків через тарифікацію extra-usage, а не через звичайні ліміти плану підписки.
  • Димове тестування live CLI-backend тепер перевіряє той самий наскрізний потік для Claude, Codex і Gemini: текстовий хід, хід класифікації зображення, потім виклик інструмента MCP cron, перевірений через CLI gateway.
  • Стандартне димове тестування Claude також оновлює сесію з Sonnet до Opus і перевіряє, що відновлена сесія все ще пам’ятає попередню нотатку.

Live: димове тестування ACP bind (/acp spawn ... --bind here)

  • Тест: src/gateway/gateway-acp-bind.live.test.ts
  • Мета: перевірити реальний потік conversation-bind ACP із live ACP agent:
    • надіслати /acp spawn <agent> --bind here
    • прив’язати синтетичну розмову message-channel на місці
    • надіслати звичайний подальший запит у тій самій розмові
    • перевірити, що подальший запит потрапляє до транскрипту прив’язаної ACP-сесії
  • Увімкнення:
    • pnpm test:live src/gateway/gateway-acp-bind.live.test.ts
    • OPENCLAW_LIVE_ACP_BIND=1
  • Значення за замовчуванням:
    • ACP-агенти в Docker: claude,codex,gemini
    • ACP-агент для прямого pnpm test:live ...: claude
    • Синтетичний канал: контекст розмови у стилі Slack DM
    • ACP-backend: acpx
  • Перевизначення:
    • OPENCLAW_LIVE_ACP_BIND_AGENT=claude
    • OPENCLAW_LIVE_ACP_BIND_AGENT=codex
    • OPENCLAW_LIVE_ACP_BIND_AGENT=gemini
    • OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini
    • OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@<version>'
    • OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL=gpt-5.5
  • Примітки:
    • Ця лінія використовує поверхню gateway chat.send з admin-only синтетичними полями originating-route, щоб тести могли прикріплювати контекст message-channel без удавання зовнішньої доставки.
    • Коли OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND не встановлено, тест використовує вбудований реєстр агентів plugin acpx для вибраного ACP harness agent.

Приклад:

OPENCLAW_LIVE_ACP_BIND=1 \
  OPENCLAW_LIVE_ACP_BIND_AGENT=claude \
  pnpm test:live src/gateway/gateway-acp-bind.live.test.ts

Рецепт Docker:

pnpm test:docker:live-acp-bind

Рецепти Docker для окремих агентів:

pnpm test:docker:live-acp-bind:claude
pnpm test:docker:live-acp-bind:codex
pnpm test:docker:live-acp-bind:gemini

Примітки щодо Docker:

  • Docker-ранер розміщений у scripts/test-live-acp-bind-docker.sh.
  • За замовчуванням він запускає димове тестування ACP bind послідовно для всіх підтримуваних live CLI agent: claude, codex, потім gemini.
  • Використовуйте OPENCLAW_LIVE_ACP_BIND_AGENTS=claude, OPENCLAW_LIVE_ACP_BIND_AGENTS=codex або OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini, щоб звузити матрицю.
  • Він використовує ~/.profile, готує відповідний auth-матеріал CLI у контейнері, встановлює acpx у доступний для запису npm-префікс, а потім, якщо потрібно, встановлює запитаний live CLI (@anthropic-ai/claude-code, @openai/codex або @google/gemini-cli).
  • Усередині Docker раннер встановлює OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx, щоб acpx зберігав env-змінні провайдера з profile, доступні для дочірнього harness CLI.

Live: димове тестування harness app-server Codex

  • Мета: перевірити harness Codex, що належить plugin, через стандартний метод gateway agent:
    • завантажити bundled plugin codex
    • вибрати OPENCLAW_AGENT_RUNTIME=codex
    • надіслати перший хід gateway agent до codex/gpt-5.5
    • надіслати другий хід у ту саму сесію OpenClaw і перевірити, що потік app-server може відновитися
    • запустити /codex status і /codex models через той самий шлях команди gateway
    • за потреби виконати два shell-probe з підвищеними правами, перевірені Guardian: одну нешкідливу команду, яку має бути схвалено, і одне фальшиве завантаження секрету, яке має бути відхилено, щоб агент перепитав
  • Тест: src/gateway/gateway-codex-harness.live.test.ts
  • Увімкнення: OPENCLAW_LIVE_CODEX_HARNESS=1
  • Модель за замовчуванням: codex/gpt-5.5
  • Необов’язковий image probe: OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1
  • Необов’язковий MCP/tool probe: OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1
  • Необов’язковий Guardian probe: OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1
  • Це димове тестування встановлює OPENCLAW_AGENT_HARNESS_FALLBACK=none, щоб зламаний harness Codex не міг пройти, тихо переключившись на PI.
  • Автентифікація: OPENAI_API_KEY із shell/profile, плюс необов’язково скопійовані ~/.codex/auth.json і ~/.codex/config.toml

Локальний рецепт:

source ~/.profile
OPENCLAW_LIVE_CODEX_HARNESS=1 \
  OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1 \
  OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1 \
  OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1 \
  OPENCLAW_LIVE_CODEX_HARNESS_MODEL=codex/gpt-5.5 \
  pnpm test:live -- src/gateway/gateway-codex-harness.live.test.ts

Рецепт Docker:

source ~/.profile
pnpm test:docker:live-codex-harness

Примітки щодо Docker:

  • Docker-ранер розміщений у scripts/test-live-codex-harness-docker.sh.
  • Він використовує змонтований ~/.profile, передає OPENAI_API_KEY, копіює файли автентифікації Codex CLI, якщо вони є, встановлює @openai/codex у доступний для запису змонтований npm-префікс, готує дерево вихідних файлів, а потім запускає лише live-тест Codex-harness.
  • Docker за замовчуванням вмикає image-, MCP/tool- і Guardian-probe. Встановіть OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0, або OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0, або OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0, коли вам потрібен вужчий прогін для налагодження.
  • Docker також експортує OPENCLAW_AGENT_HARNESS_FALLBACK=none, як і конфігурація live-тесту, щоб fallback openai-codex/* або PI не міг приховати регресію Codex harness.

Рекомендовані рецепти live

Найшвидші та найменш нестабільні — вузькі, явні allowlist:

  • Одна модель, напряму (без gateway):

    • OPENCLAW_LIVE_MODELS="openai/gpt-5.5" pnpm test:live src/agents/models.profiles.live.test.ts
  • Одна модель, димове тестування gateway:

    • OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
  • Виклик інструментів у кількох провайдерів:

    • OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
  • Фокус на Google (API-ключ Gemini + Antigravity):

    • Gemini (API-ключ): OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
    • Antigravity (OAuth): OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts

Примітки:

  • google/... використовує Gemini API (API-ключ).
  • google-antigravity/... використовує міст Antigravity OAuth (endpoint агента в стилі Cloud Code Assist).
  • google-gemini-cli/... використовує локальний Gemini CLI на вашій машині (окрема автентифікація + особливості інструментів).
  • Gemini API проти Gemini CLI:
    • API: OpenClaw викликає розміщений Google Gemini API через HTTP (автентифікація API-ключем / профілем); зазвичай саме це більшість користувачів мають на увазі під “Gemini”.
    • CLI: OpenClaw викликає локальний бінарний файл gemini; він має власну автентифікацію та може поводитися інакше (streaming/підтримка інструментів/version skew).

Live: матриця моделей (що ми покриваємо)

Немає фіксованого «списку моделей CI» (live вмикається за потреби), але це рекомендовані моделі для регулярного покриття на dev-машині з ключами.

Сучасний набір димового тестування (виклик інструментів + image)

Це прогін «типових моделей», який ми очікуємо підтримувати в робочому стані:

  • OpenAI (не Codex): openai/gpt-5.5 (необов’язково: openai/gpt-5.4-mini)
  • OpenAI Codex: openai-codex/gpt-5.5
  • Anthropic: anthropic/claude-opus-4-6 (або anthropic/claude-sonnet-4-6)
  • Google (Gemini API): google/gemini-3.1-pro-preview і google/gemini-3-flash-preview (уникайте старіших моделей Gemini 2.x)
  • Google (Antigravity): google-antigravity/claude-opus-4-6-thinking і google-antigravity/gemini-3-flash
  • Z.AI (GLM): zai/glm-4.7
  • MiniMax: minimax/MiniMax-M2.7

Запуск димового тестування gateway з інструментами + image: OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,openai-codex/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts

Базовий рівень: виклик інструментів (Read + необов’язковий Exec)

Виберіть щонайменше одну модель з кожної родини провайдерів:

  • OpenAI: openai/gpt-5.5 (або openai/gpt-5.4-mini)
  • Anthropic: anthropic/claude-opus-4-6 (або anthropic/claude-sonnet-4-6)
  • Google: google/gemini-3-flash-preview (або google/gemini-3.1-pro-preview)
  • Z.AI (GLM): zai/glm-4.7
  • MiniMax: minimax/MiniMax-M2.7

Необов’язкове додаткове покриття (було б добре мати):

  • xAI: xai/grok-4 (або найновіша доступна)
  • Mistral: mistral/… (виберіть одну модель із підтримкою tools, яку у вас увімкнено)
  • Cerebras: cerebras/… (якщо у вас є доступ)
  • LM Studio: lmstudio/… (локально; виклик інструментів залежить від режиму API)

Vision: надсилання image (вкладення → мультимодальне повідомлення)

Додайте щонайменше одну модель із підтримкою зображень у OPENCLAW_LIVE_GATEWAY_MODELS (варіанти Claude/Gemini/OpenAI з підтримкою vision тощо), щоб перевірити image probe.

Агрегатори / альтернативні Gateway

Якщо у вас увімкнені ключі, ми також підтримуємо тестування через:

  • OpenRouter: openrouter/... (сотні моделей; використовуйте openclaw models scan, щоб знайти кандидатів із підтримкою tools+image)
  • OpenCode: opencode/... для Zen і opencode-go/... для Go (автентифікація через OPENCODE_API_KEY / OPENCODE_ZEN_API_KEY)

Більше провайдерів, які можна включити в live-матрицю (якщо у вас є облікові дані/конфігурація):

  • Вбудовані: openai, openai-codex, anthropic, google, google-vertex, google-antigravity, google-gemini-cli, zai, openrouter, opencode, opencode-go, xai, groq, cerebras, mistral, github-copilot
  • Через models.providers (custom endpoint): minimax (cloud/API), а також будь-який OpenAI/Anthropic-сумісний proxy (LM Studio, vLLM, LiteLLM тощо)

Порада: не намагайтеся жорстко зашивати в документацію «всі моделі». Авторитетний список — це те, що повертає discoverModels(...) на вашій машині, плюс ті ключі, які доступні.

Облікові дані (ніколи не комітьте)

Live-тести знаходять облікові дані так само, як і CLI. Практичні наслідки:

  • Якщо CLI працює, live-тести мають знайти ті самі ключі.

  • Якщо live-тест каже «немає облікових даних», налагоджуйте це так само, як налагоджували б openclaw models list / вибір моделі.

  • Профілі автентифікації для окремих агентів: ~/.openclaw/agents/<agentId>/agent/auth-profiles.json (саме це означає «ключі профілів» у live-тестах)

  • Конфігурація: ~/.openclaw/openclaw.json (або OPENCLAW_CONFIG_PATH)

  • Каталог застарілого стану: ~/.openclaw/credentials/ (копіюється в підготовлений live-home, якщо присутній, але не є основним сховищем ключів профілів)

  • Локальні live-запуски за замовчуванням копіюють активну конфігурацію, файли auth-profiles.json для окремих агентів, застарілий credentials/ і підтримувані зовнішні каталоги автентифікації CLI у тимчасовий test home; підготовлені live-home пропускають workspace/ і sandboxes/, а перевизначення шляхів agents.*.workspace / agentDir видаляються, щоб probe не торкалися вашого реального workspace хоста.

Якщо ви хочете покладатися на env-ключі (наприклад, експортовані у вашому ~/.profile), запускайте локальні тести після source ~/.profile, або використовуйте Docker-ранери нижче (вони можуть монтувати ~/.profile у контейнер).

Live Deepgram (транскрипція аудіо)

  • Тест: extensions/deepgram/audio.live.test.ts
  • Увімкнення: DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live extensions/deepgram/audio.live.test.ts

Live BytePlus coding plan

  • Тест: extensions/byteplus/live.test.ts
  • Увімкнення: BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live extensions/byteplus/live.test.ts
  • Необов’язкове перевизначення моделі: BYTEPLUS_CODING_MODEL=ark-code-latest

Live ComfyUI workflow media

  • Тест: extensions/comfy/comfy.live.test.ts
  • Увімкнення: OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts
  • Обсяг:
    • Перевіряє bundled-шляхи comfy для image, video і music_generate
    • Пропускає кожну можливість, якщо не налаштовано models.providers.comfy.<capability>
    • Корисно після змін у надсиланні workflow comfy, polling, завантаженнях або реєстрації plugin

Live генерація зображень

  • Тест: test/image-generation.runtime.live.test.ts
  • Команда: pnpm test:live test/image-generation.runtime.live.test.ts
  • Harness: pnpm test:live:media image
  • Обсяг:
    • Перелічує кожен зареєстрований plugin провайдера генерації зображень
    • Завантажує відсутні env-змінні провайдера з вашого login shell (~/.profile) перед probe
    • За замовчуванням використовує live/env API-ключі раніше за збережені auth-профілі, щоб застарілі тестові ключі в auth-profiles.json не маскували реальні shell-облікові дані
    • Пропускає провайдерів без придатної автентифікації/профілю/моделі
    • Запускає стандартні варіанти генерації зображень через спільну runtime-можливість:
      • google:flash-generate
      • google:pro-generate
      • google:pro-edit
      • openai:default-generate
  • Поточні bundled-провайдери, які покриваються:
    • fal
    • google
    • minimax
    • openai
    • vydra
    • xai
  • Необов’язкове звуження:
    • OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="openai,google,xai"
    • OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-2,google/gemini-3.1-flash-image-preview,xai/grok-imagine-image"
    • OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit,xai:default-generate,xai:default-edit"
  • Необов’язкова поведінка автентифікації:
    • OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1, щоб примусово використовувати автентифікацію зі сховища профілів і ігнорувати перевизначення лише через env

Live генерація музики

  • Тест: extensions/music-generation-providers.live.test.ts
  • Увімкнення: OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts
  • Harness: pnpm test:live:media music
  • Обсяг:
    • Перевіряє спільний bundled-шлях провайдера генерації музики
    • Наразі охоплює Google і MiniMax
    • Завантажує env-змінні провайдера з вашого login shell (~/.profile) перед probe
    • За замовчуванням використовує live/env API-ключі раніше за збережені auth-профілі, щоб застарілі тестові ключі в auth-profiles.json не маскували реальні shell-облікові дані
    • Пропускає провайдерів без придатної автентифікації/профілю/моделі
    • Запускає обидва оголошені runtime-режими, коли вони доступні:
      • generate з вхідними даними лише у вигляді prompt
      • edit, коли провайдер оголошує capabilities.edit.enabled
    • Поточне покриття спільної лінії:
      • google: generate, edit
      • minimax: generate
      • comfy: окремий live-файл Comfy, не цей спільний прогін
  • Необов’язкове звуження:
    • OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"
    • OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"
  • Необов’язкова поведінка автентифікації:
    • OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1, щоб примусово використовувати автентифікацію зі сховища профілів і ігнорувати перевизначення лише через env

Live генерація відео

  • Тест: extensions/video-generation-providers.live.test.ts
  • Увімкнення: OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts
  • Harness: pnpm test:live:media video
  • Обсяг:
    • Перевіряє спільний bundled-шлях провайдера генерації відео
    • За замовчуванням використовує безпечний для релізу шлях димового тестування: провайдери без FAL, один запит text-to-video на провайдера, одноcекундний lobster prompt і обмеження операції для кожного провайдера з OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS (180000 за замовчуванням)
    • За замовчуванням пропускає FAL, оскільки затримка черги на боці провайдера може домінувати над часом релізу; передайте --video-providers fal або OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal", щоб явно його запустити
    • Завантажує env-змінні провайдера з вашого login shell (~/.profile) перед probe
    • За замовчуванням використовує live/env API-ключі раніше за збережені auth-профілі, щоб застарілі тестові ключі в auth-profiles.json не маскували реальні shell-облікові дані
    • Пропускає провайдерів без придатної автентифікації/профілю/моделі
    • За замовчуванням запускає лише generate
    • Встановіть OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1, щоб також запускати оголошені режими перетворення, коли вони доступні:
      • imageToVideo, коли провайдер оголошує capabilities.imageToVideo.enabled і вибраний провайдер/модель приймає локальний image-вхід на основі buffer у спільному прогоні
      • videoToVideo, коли провайдер оголошує capabilities.videoToVideo.enabled і вибраний провайдер/модель приймає локальний video-вхід на основі buffer у спільному прогоні
    • Поточні оголошені, але пропущені провайдери imageToVideo у спільному прогоні:
      • vydra, тому що bundled veo3 підтримує лише text, а bundled kling вимагає віддалений image URL
    • Специфічне для провайдера покриття Vydra:
      • OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts
      • цей файл запускає veo3 text-to-video плюс лінію kling, яка за замовчуванням використовує фікстуру з віддаленим image URL
    • Поточне live-покриття videoToVideo:
      • лише runway, коли вибрана модель — runway/gen4_aleph
    • Поточні оголошені, але пропущені провайдери videoToVideo у спільному прогоні:
      • alibaba, qwen, xai, тому що ці шляхи наразі вимагають віддалені reference URL http(s) / MP4
      • google, тому що поточна спільна лінія Gemini/Veo використовує локальний вхід на основі buffer, і цей шлях не приймається у спільному прогоні
      • openai, тому що поточна спільна лінія не гарантує організаційно-специфічний доступ до video inpaint/remix
  • Необов’язкове звуження:
    • OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"
    • OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"
    • OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS="", щоб включити кожного провайдера до стандартного прогону, зокрема FAL
    • OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000, щоб зменшити обмеження операції для кожного провайдера під час агресивного димового прогону
  • Необов’язкова поведінка автентифікації:
    • OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1, щоб примусово використовувати автентифікацію зі сховища профілів і ігнорувати перевизначення лише через env

Harness для media live

  • Команда: pnpm test:live:media
  • Призначення:
    • Запускає спільні live-набори для image, music і video через один рідний для репозиторію entrypoint
    • Автоматично завантажує відсутні env-змінні провайдера з ~/.profile
    • За замовчуванням автоматично звужує кожен набір до провайдерів, які наразі мають придатну автентифікацію
    • Повторно використовує scripts/test-live.mjs, тож поведінка Heartbeat і тихого режиму залишається узгодженою
  • Приклади:
    • pnpm test:live:media
    • pnpm test:live:media image video --providers openai,google,minimax
    • pnpm test:live:media video --video-providers openai,runway --all-providers
    • pnpm test:live:media music --quiet

Docker-ранери (необов’язкові перевірки «працює в Linux»)

Ці Docker-ранери поділяються на дві групи:

  • Live-model ранери: test:docker:live-models і test:docker:live-gateway запускають лише відповідний live-файл із profile-key усередині Docker-образу репозиторію (src/agents/models.profiles.live.test.ts і src/gateway/gateway-models.profiles.live.test.ts), монтують ваш локальний каталог конфігурації та workspace (і використовують ~/.profile, якщо його змонтовано). Відповідні локальні entrypoint — test:live:models-profiles і test:live:gateway-profiles.
  • Docker live-ранери за замовчуванням використовують меншу межу димового тестування, щоб повний Docker-прогін залишався практичним: test:docker:live-models за замовчуванням використовує OPENCLAW_LIVE_MAX_MODELS=12, а test:docker:live-gateway за замовчуванням використовує OPENCLAW_LIVE_GATEWAY_SMOKE=1, OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8, OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000 і OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000. Перевизначайте ці env-змінні, коли вам явно потрібне більше вичерпне сканування.
  • test:docker:all один раз збирає live Docker-образ через test:docker:live-build, а потім повторно використовує його для двох Docker-ліній live. Воно також збирає один спільний образ scripts/e2e/Dockerfile через test:docker:e2e-build і повторно використовує його для контейнерних E2E-ранерів димового тестування, які перевіряють зібраний app.
  • Контейнерні ранери димового тестування: test:docker:openwebui, test:docker:onboard, test:docker:npm-onboard-channel-agent, test:docker:gateway-network, test:docker:mcp-channels, test:docker:pi-bundle-mcp-tools, test:docker:cron-mcp-cleanup, test:docker:plugins, test:docker:plugin-update і test:docker:config-reload піднімають один або кілька реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня.

Docker-ранери live-model також bind-монтують лише потрібні домівки автентифікації CLI (або всі підтримувані, коли прогін не звужено), а потім копіюють їх у домашній каталог контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени без зміни сховища автентифікації хоста:

  • Прямі моделі: pnpm test:docker:live-models (скрипт: scripts/test-live-models-docker.sh)
  • Димове тестування ACP bind: pnpm test:docker:live-acp-bind (скрипт: scripts/test-live-acp-bind-docker.sh)
  • Димове тестування CLI backend: pnpm test:docker:live-cli-backend (скрипт: scripts/test-live-cli-backend-docker.sh)
  • Димове тестування harness app-server Codex: pnpm test:docker:live-codex-harness (скрипт: scripts/test-live-codex-harness-docker.sh)
  • Gateway + dev agent: pnpm test:docker:live-gateway (скрипт: scripts/test-live-gateway-models-docker.sh)
  • Димове тестування Open WebUI live: pnpm test:docker:openwebui (скрипт: scripts/e2e/openwebui-docker.sh)
  • Майстер онбордингу (TTY, повне scaffolding): pnpm test:docker:onboard (скрипт: scripts/e2e/onboard-docker.sh)
  • Димове тестування онбордингу/каналу/агента через npm tarball: pnpm test:docker:npm-onboard-channel-agent глобально встановлює запакований tarball OpenClaw у Docker, налаштовує OpenAI через онбординг з env-ref плюс Telegram за замовчуванням, перевіряє, що ввімкнення plugin встановлює його runtime deps за потреби, запускає doctor і виконує один хід агента з mock OpenAI. Повторно використовуйте попередньо зібраний tarball через OPENCLAW_NPM_ONBOARD_PACKAGE_TGZ=/path/to/openclaw-*.tgz, пропустіть host rebuild через OPENCLAW_NPM_ONBOARD_HOST_BUILD=0 або перемкніть канал через OPENCLAW_NPM_ONBOARD_CHANNEL=discord.
  • Димове тестування глобального встановлення Bun: bash scripts/e2e/bun-global-install-smoke.sh пакує поточне дерево, встановлює його через bun install -g в ізольованому home і перевіряє, що openclaw infer image providers --json повертає bundled-провайдерів зображень замість зависання. Повторно використовуйте попередньо зібраний tarball через OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz, пропустіть host build через OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0 або скопіюйте dist/ зі зібраного Docker-образу через OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local.
  • Мережева взаємодія Gateway (два контейнери, WS auth + health): pnpm test:docker:gateway-network (скрипт: scripts/e2e/gateway-network-docker.sh)
  • Мінімальна reasoning-регресія OpenAI Responses web_search: pnpm test:docker:openai-web-search-minimal (скрипт: scripts/e2e/openai-web-search-minimal-docker.sh) запускає mock OpenAI server через Gateway, перевіряє, що web_search підвищує reasoning.effort з minimal до low, потім примусово викликає відхилення schema провайдера й перевіряє, що сирі подробиці з’являються в логах Gateway.
  • Міст каналу MCP (seeded Gateway + міст stdio + димове тестування raw Claude notification-frame): pnpm test:docker:mcp-channels (скрипт: scripts/e2e/mcp-channels-docker.sh)
  • Інструменти Pi bundle MCP (реальний stdio MCP server + димове тестування allow/deny профілю embedded Pi): pnpm test:docker:pi-bundle-mcp-tools (скрипт: scripts/e2e/pi-bundle-mcp-tools-docker.sh)
  • Очищення MCP Cron/subagent (реальний Gateway + завершення дочірнього stdio MCP після ізольованих прогонів cron і одноразового subagent): pnpm test:docker:cron-mcp-cleanup (скрипт: scripts/e2e/cron-mcp-cleanup-docker.sh)
  • Plugins (димове тестування встановлення + псевдонім /plugin + семантика перезапуску Claude-bundle): pnpm test:docker:plugins (скрипт: scripts/e2e/plugins-docker.sh)
  • Димове тестування незмінного оновлення Plugin: pnpm test:docker:plugin-update (скрипт: scripts/e2e/plugin-update-unchanged-docker.sh)
  • Димове тестування метаданих перезавантаження конфігурації: pnpm test:docker:config-reload (скрипт: scripts/e2e/config-reload-source-docker.sh)
  • Runtime deps bundled plugin: pnpm test:docker:bundled-channel-deps за замовчуванням збирає невеликий образ Docker-ранера, один раз збирає та пакує OpenClaw на host, а потім монтує цей tarball у кожний сценарій встановлення Linux. Повторно використовуйте образ через OPENCLAW_SKIP_DOCKER_BUILD=1, пропустіть host rebuild після свіжої локальної збірки через OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0 або вкажіть наявний tarball через OPENCLAW_BUNDLED_CHANNEL_PACKAGE_TGZ=/path/to/openclaw-*.tgz.
  • Звужуйте runtime deps bundled plugin під час ітерацій, вимикаючи не пов’язані сценарії, наприклад: OPENCLAW_BUNDLED_CHANNEL_SCENARIOS=0 OPENCLAW_BUNDLED_CHANNEL_UPDATE_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_ROOT_OWNED_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_SETUP_ENTRY_SCENARIO=0 pnpm test:docker:bundled-channel-deps.

Щоб вручну попередньо зібрати та повторно використовувати спільний образ built-app:

OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e:local pnpm test:docker:e2e-build
OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels

Перевизначення образів для конкретних наборів, як-от OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE, усе ще мають пріоритет, якщо встановлені. Коли OPENCLAW_SKIP_DOCKER_BUILD=1 вказує на віддалений спільний образ, скрипти завантажують його, якщо його ще немає локально. Docker-тести QR та інсталятора зберігають власні Dockerfile, тому що вони перевіряють поведінку package/install, а не runtime спільного built-app.

Docker-ранери live-model також монтують поточний checkout лише для читання і підготовлюють його у тимчасовому workdir усередині контейнера. Це зберігає runtime image компактним, водночас усе одно запускаючи Vitest проти ваших точних локальних source/config. Крок підготовки пропускає великі локальні кеші та результати збірки app, такі як .pnpm-store, .worktrees, __openclaw_vitest__ і локальні для app каталоги .build або виводу Gradle, щоб Docker live-запуски не витрачали хвилини на копіювання машинно-специфічних артефактів. Вони також встановлюють OPENCLAW_SKIP_CHANNELS=1, щоб live-probe Gateway не запускали реальні воркери каналів Telegram/Discord тощо всередині контейнера. test:docker:live-models усе ще запускає pnpm test:live, тож також передавайте OPENCLAW_LIVE_GATEWAY_*, коли вам потрібно звузити або виключити покриття gateway live з цієї Docker-лінії. test:docker:openwebui — це димове тестування сумісності вищого рівня: воно запускає контейнер gateway OpenClaw з увімкненими OpenAI-сумісними HTTP endpoint, запускає pin-ований контейнер Open WebUI проти цього gateway, виконує вхід через Open WebUI, перевіряє, що /api/models надає openclaw/default, а потім надсилає реальний chat-запит через proxy /api/chat/completions Open WebUI. Перший запуск може бути помітно повільнішим, тому що Docker може потребувати завантаження образу Open WebUI, а Open WebUI може потребувати завершення власного cold-start налаштування. Ця лінія очікує наявність придатного live-ключа моделі, а OPENCLAW_PROFILE_FILE (~/.profile за замовчуванням) — основний спосіб надати його в Dockerized-запусках. Успішні запуски виводять невеликий JSON payload на кшталт { "ok": true, "model": "openclaw/default", ... }. test:docker:mcp-channels навмисно є детермінованим і не потребує реального облікового запису Telegram, Discord або iMessage. Воно запускає seeded контейнер Gateway, запускає другий контейнер, який піднімає openclaw mcp serve, а потім перевіряє виявлення маршрутизованих розмов, читання транскриптів, метадані вкладень, поведінку черги live-подій, маршрутизацію outbound send, а також channel- і permission-сповіщення у стилі Claude через реальний stdio MCP bridge. Перевірка сповіщень безпосередньо аналізує raw stdio MCP frames, тож димове тестування перевіряє те, що міст реально випромінює, а не лише те, що випадково надає конкретний SDK клієнта. test:docker:pi-bundle-mcp-tools є детермінованим і не потребує live-ключа моделі. Воно збирає Docker-образ репозиторію, запускає реальний stdio MCP probe server усередині контейнера, матеріалізує цей server через runtime embedded Pi bundle MCP, виконує tool, а потім перевіряє, що coding і messaging зберігають інструменти bundle-mcp, тоді як minimal і tools.deny: ["bundle-mcp"] їх фільтрують. test:docker:cron-mcp-cleanup є детермінованим і не потребує live-ключа моделі. Воно запускає seeded Gateway з реальним stdio MCP probe server, виконує ізольований хід cron і одноразовий дочірній хід /subagents spawn, а потім перевіряє, що дочірній процес MCP завершується після кожного запуску.

Ручне димове тестування ACP plain-language thread (не CI):

  • bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...
  • Зберігайте цей скрипт для workflow регресії/налагодження. Він може знову знадобитися для перевірки маршрутизації ACP thread, тож не видаляйте його.

Корисні env-змінні:

  • OPENCLAW_CONFIG_DIR=... (за замовчуванням: ~/.openclaw) монтується в /home/node/.openclaw
  • OPENCLAW_WORKSPACE_DIR=... (за замовчуванням: ~/.openclaw/workspace) монтується в /home/node/.openclaw/workspace
  • OPENCLAW_PROFILE_FILE=... (за замовчуванням: ~/.profile) монтується в /home/node/.profile і використовується перед запуском тестів
  • OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1, щоб перевірити лише env-змінні, використані з OPENCLAW_PROFILE_FILE, використовуючи тимчасові каталоги config/workspace і без зовнішніх монтувань auth CLI
  • OPENCLAW_DOCKER_CLI_TOOLS_DIR=... (за замовчуванням: ~/.cache/openclaw/docker-cli-tools) монтується в /home/node/.npm-global для кешованих встановлень CLI усередині Docker
  • Зовнішні каталоги/файли auth CLI під $HOME монтуються лише для читання під /host-auth..., а потім копіюються в /home/node/... перед початком тестів
    • Каталоги за замовчуванням: .minimax
    • Файли за замовчуванням: ~/.codex/auth.json, ~/.codex/config.toml, .claude.json, ~/.claude/.credentials.json, ~/.claude/settings.json, ~/.claude/settings.local.json
    • Звужені запуски провайдерів монтують лише потрібні каталоги/файли, визначені з OPENCLAW_LIVE_PROVIDERS / OPENCLAW_LIVE_GATEWAY_PROVIDERS
    • Перевизначайте вручну через OPENCLAW_DOCKER_AUTH_DIRS=all, OPENCLAW_DOCKER_AUTH_DIRS=none або список через кому, наприклад OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex
  • OPENCLAW_LIVE_GATEWAY_MODELS=... / OPENCLAW_LIVE_MODELS=..., щоб звузити прогін
  • OPENCLAW_LIVE_GATEWAY_PROVIDERS=... / OPENCLAW_LIVE_PROVIDERS=..., щоб відфільтрувати провайдерів у контейнері
  • OPENCLAW_SKIP_DOCKER_BUILD=1, щоб повторно використовувати наявний образ openclaw:local-live для повторних запусків, яким не потрібне перебирання
  • OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1, щоб переконатися, що облікові дані надходять зі сховища профілів (а не з env)
  • OPENCLAW_OPENWEBUI_MODEL=..., щоб вибрати модель, яку gateway надає для димового тестування Open WebUI
  • OPENCLAW_OPENWEBUI_PROMPT=..., щоб перевизначити prompt перевірки nonce, використаний у димовому тестуванні Open WebUI
  • OPENWEBUI_IMAGE=..., щоб перевизначити pin-ований тег образу Open WebUI

Перевірка коректності документації

Після редагування документації запускайте перевірки docs: pnpm check:docs. Запускайте повну перевірку anchor у Mintlify, коли вам також потрібні перевірки heading у межах сторінки: pnpm docs:check-links:anchors.

Офлайн-регресія (безпечна для CI)

Це регресії «реального pipeline» без реальних провайдерів:

  • Виклик інструментів Gateway (mock OpenAI, реальний цикл gateway + agent): src/gateway/gateway.test.ts (case: "runs a mock OpenAI tool call end-to-end via gateway agent loop")
  • Майстер Gateway (WS wizard.start/wizard.next, примусовий запис config + auth): src/gateway/gateway.test.ts (case: "runs wizard over ws and writes auth token config")

Оцінювання надійності агента (Skills)

У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності агента»:

  • Mock-виклик інструментів через реальний цикл gateway + agent (src/gateway/gateway.test.ts).
  • Наскрізні потоки майстра, які перевіряють прив’язку сесії та ефекти конфігурації (src/gateway/gateway.test.ts).

Що все ще відсутнє для Skills (див. Skills):

  • Прийняття рішень: коли Skills перелічено в prompt, чи обирає агент правильний Skill (або уникає нерелевантних)?
  • Відповідність: чи читає агент SKILL.md перед використанням і чи виконує потрібні кроки/аргументи?
  • Контракти workflow: multi-turn сценарії, які перевіряють порядок інструментів, перенесення історії сесії та межі sandbox.

Майбутні evals спочатку мають залишатися детермінованими:

  • Scenario runner з mock-провайдерами для перевірки викликів інструментів + порядку, читання skill-файлів і прив’язки сесії.
  • Невеликий набір сценаріїв, орієнтованих на skills (використовувати чи уникати, gating, prompt injection).
  • Необов’язкові live evals (увімкнення за потреби, обмеження через env) лише після того, як буде готовий безпечний для CI набір.

Контрактні тести (форма plugin і channel)

Контрактні тести перевіряють, що кожен зареєстрований plugin і channel відповідає своєму інтерфейсному контракту. Вони ітеруються за всіма виявленими plugins і запускають набір перевірок форми та поведінки. Стандартна unit-лінія pnpm test навмисно пропускає ці файли спільних seam і smoke; запускайте контрактні команди явно, коли торкаєтеся спільних поверхонь channel або provider.

Команди

  • Усі контрактні тести: pnpm test:contracts
  • Лише контрактні тести channel: pnpm test:contracts:channels
  • Лише контрактні тести provider: pnpm test:contracts:plugins

Контрактні тести channel

Розміщені в src/channels/plugins/contracts/*.contract.test.ts:

  • plugin - Базова форма plugin (id, name, capabilities)
  • setup - Контракт майстра налаштування
  • session-binding - Поведінка прив’язки сесії
  • outbound-payload - Структура payload повідомлення
  • inbound - Обробка вхідних повідомлень
  • actions - Обробники дій channel
  • threading - Обробка ID thread
  • directory - API directory/roster
  • group-policy - Застосування групової політики

Контракти статусу provider

Розміщені в src/plugins/contracts/*.contract.test.ts.

  • status - Перевірки статусу channel
  • registry - Форма реєстру plugin

Контрактні тести provider

Розміщені в src/plugins/contracts/*.contract.test.ts:

  • auth - Контракт потоку автентифікації
  • auth-choice - Вибір/добір автентифікації
  • catalog - API каталогу моделей
  • discovery - Виявлення plugin
  • loader - Завантаження plugin
  • runtime - Runtime provider
  • shape - Форма/інтерфейс plugin
  • wizard - Майстер налаштування

Коли запускати

  • Після зміни export або subpath у plugin-sdk
  • Після додавання або зміни channel чи provider plugin
  • Після рефакторингу реєстрації plugin або виявлення

Контрактні тести запускаються в CI і не потребують реальних API-ключів.

Додавання регресій (рекомендації)

Коли ви виправляєте проблему provider/model, виявлену в live:

  • За можливості додавайте безпечну для CI регресію (mock/stub provider або захоплення точної трансформації форми запиту)
  • Якщо проблема за своєю природою лише live (rate limits, політики автентифікації), залишайте live-тест вузьким і таким, що вмикається через env vars
  • Віддавайте перевагу найменшому шару, який виявляє баг:
    • баг перетворення/повторення запиту provider → тест прямих моделей
    • баг pipeline сесії/історії/інструментів gateway → live smoke gateway або безпечний для CI mock-тест gateway
  • Захист SecretRef traversal:
    • src/secrets/exec-secret-ref-id-parity.test.ts виводить по одній вибірковій цілі для кожного класу SecretRef із метаданих реєстру (listSecretTargetRegistryEntries()), а потім перевіряє, що exec id із traversal-segment відхиляються.
    • Якщо ви додаєте нову родину цілей SecretRef includeInPlan у src/secrets/target-registry-data.ts, оновіть classifyTargetClass у цьому тесті. Тест навмисно падає на некласифікованих target id, щоб нові класи не можна було тихо пропустити.