Перейти до основного вмісту

Тестування

OpenClaw має три набори Vitest (unit/integration, e2e, live) і невеликий набір раннерів Docker. Цей документ — посібник «як ми тестуємо»:
  • Що охоплює кожен набір (і що він навмисно не охоплює)
  • Які команди запускати для типових сценаріїв роботи (локально, перед push, налагодження)
  • Як live-тести знаходять облікові дані та вибирають моделі/провайдерів
  • Як додавати регресійні тести для реальних проблем моделей/провайдерів

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

У більшості випадків:
  • Повний набір перевірок (очікується перед push): pnpm build && pnpm check && 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-набір (моделі + gateway-перевірки tool/image): pnpm test:live
  • Тихий запуск одного live-файлу: pnpm test:live -- src/agents/models.profiles.live.test.ts
Порада: якщо вам потрібен лише один збійний випадок, віддавайте перевагу звуженню live-тестів через змінні середовища allowlist, описані нижче.

QA-специфічні раннери

Ці команди розміщені поряд з основними наборами тестів, коли вам потрібен рівень реалістичності QA-lab:
  • pnpm openclaw qa suite
    • Запускає QA-сценарії з репозиторію безпосередньо на хості.
    • За замовчуванням запускає кілька вибраних сценаріїв паралельно з ізольованими gateway-воркерами, до 64 воркерів або кількості вибраних сценаріїв. Використовуйте --concurrency <count>, щоб налаштувати кількість воркерів, або --concurrency 1 для старішої послідовної лінії.
  • pnpm openclaw qa suite --runner multipass
    • Запускає той самий QA-набір усередині тимчасової Linux VM Multipass.
    • Зберігає ту саму поведінку вибору сценаріїв, що й qa suite на хості.
    • Повторно використовує ті самі прапорці вибору провайдера/моделі, що й qa suite.
    • Live-запуски пересилають підтримувані QA-входи автентифікації, практичні для гостьової системи: ключі провайдерів через env, шлях до конфігурації live-провайдера QA і CODEX_HOME, якщо він є.
    • Каталоги виводу мають залишатися в межах кореня репозиторію, щоб гість міг записувати назад через змонтований workspace.
    • Записує звичайний QA-звіт + підсумок, а також логи Multipass у .artifacts/qa-e2e/....
  • pnpm qa:lab:up
    • Запускає QA-сайт на базі Docker для QA-роботи в операторському стилі.
  • pnpm openclaw qa matrix
    • Запускає live QA-лінію Matrix проти тимчасового homeserver Tuwunel на базі Docker.
    • Ініціалізує трьох тимчасових користувачів Matrix (driver, sut, observer) плюс одну приватну кімнату, а потім запускає дочірній QA gateway з реальним Plugin Matrix як транспортом SUT.
    • За замовчуванням використовує зафіксований стабільний образ Tuwunel ghcr.io/matrix-construct/tuwunel:v1.5.1. Перевизначайте через OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE, якщо потрібно протестувати інший образ.
    • Matrix наразі підтримує лише --credential-source env, оскільки ця лінія локально ініціалізує тимчасових користувачів.
    • Записує QA-звіт Matrix, підсумок і артефакт observed-events у .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.
    • Підтримує --credential-source convex для спільних пулів облікових даних. Типово використовуйте режим env або задайте OPENCLAW_QA_CREDENTIAL_SOURCE=convex, щоб увімкнути оренду зі спільного пулу.
    • Потребує двох різних ботів у тій самій приватній групі, причому бот SUT має мати ім’я користувача Telegram.
    • Для стабільного спостереження bot-to-bot увімкніть Bot-to-Bot Communication Mode у @BotFather для обох ботів і переконайтеся, що бот driver може спостерігати трафік ботів у групі.
    • Записує QA-звіт Telegram, підсумок і артефакт observed-messages у .artifacts/qa-e2e/....
Live transport lanes share one standard contract so new transports do not drift: qa-channel лишається широким синтетичним QA-набором і не входить до матриці покриття live transport.
ЛініяCanaryГейтінг згадокБлокування allowlistВідповідь верхнього рівняВідновлення після перезапускуПодальша взаємодія в тредіІзоляція тредівСпостереження за реакціямиКоманда help
Matrixxxxxxxxx
Telegramxx

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

Коли для openclaw qa telegram увімкнено --credential-source convex (або OPENCLAW_QA_CREDENTIAL_SOURCE=convex), QA lab отримує ексклюзивну оренду з пулу на базі Convex, надсилає Heartbeat для цієї оренди, поки лінія виконується, і звільняє оренду під час завершення. Еталонний каркас проєкту Convex:
  • qa/convex-credential-broker/
Обов’язкові змінні середовища:
  • 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 (типово maintainer)
Необов’язкові змінні середовища:
  • 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://. Адміністраторські команди maintainer (додавання/видалення/список пулу) вимагають саме OPENCLAW_QA_CONVEX_SECRET_MAINTAINER. CLI-хелпери для maintainer:
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.
  • admin/add перевіряє цю форму для kind: "telegram" і відхиляє некоректний payload.

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

Додавання каналу до markdown-системи QA вимагає рівно двох речей:
  1. Адаптера транспорту для каналу.
  2. Набору сценаріїв, який перевіряє контракт каналу.
Не додавайте QA-раннер, специфічний для каналу, якщо спільний раннер qa-lab може взяти на себе цей потік. qa-lab відповідає за спільну механіку:
  • запуск і завершення набору
  • паралелізм воркерів
  • запис артефактів
  • генерацію звітів
  • виконання сценаріїв
  • аліаси сумісності для старіших сценаріїв qa-channel
Адаптер каналу відповідає за контракт транспорту:
  • як налаштовується gateway для цього транспорту
  • як перевіряється готовність
  • як інжектуються вхідні події
  • як спостерігаються вихідні повідомлення
  • як надаються транскрипти й нормалізований стан транспорту
  • як виконуються дії на базі транспорту
  • як обробляється специфічне для транспорту скидання або очищення
Мінімальний поріг впровадження для нового каналу:
  1. Реалізувати адаптер транспорту на спільному шві qa-lab.
  2. Зареєструвати адаптер у реєстрі транспортів.
  3. Тримати специфічну для транспорту механіку всередині адаптера або harness каналу.
  4. Написати або адаптувати markdown-сценарії в qa/scenarios/.
  5. Використовувати generic-хелпери сценаріїв для нових сценаріїв.
  6. Зберігати роботу наявних аліасів сумісності, якщо в репозиторії не виконується навмисна міграція.
Правило ухвалення рішення суворе:
  • Якщо поведінку можна виразити один раз у qa-lab, розміщуйте її в qa-lab.
  • Якщо поведінка залежить від транспорту одного каналу, тримайте її в цьому адаптері або harness Plugin.
  • Якщо сценарію потрібна нова можливість, яку можуть використовувати більше ніж один канал, додайте generic-хелпер замість гілки, специфічної для каналу, в suite.ts.
  • Якщо поведінка має сенс лише для одного транспорту, залишайте сценарій специфічним для цього транспорту і чітко позначайте це в контракті сценарію.
Бажані назви generic-хелперів для нових сценаріїв:
  • waitForTransportReady
  • waitForChannelReady
  • injectInboundMessage
  • injectOutboundMessage
  • waitForTransportOutboundMessage
  • waitForChannelOutboundMessage
  • waitForNoTransportOutbound
  • getTransportSnapshot
  • readTransportMessage
  • readTransportTranscript
  • formatTransportTranscript
  • resetTransport
Аліаси сумісності залишаються доступними для наявних сценаріїв, зокрема:
  • waitForQaChannelReady
  • waitForOutboundMessage
  • waitForNoOutbound
  • formatConversationTranscript
  • resetBus
Нова робота з каналами має використовувати generic-хелпери. Аліаси сумісності існують, щоб уникнути одночасної міграції всього, а не як модель для написання нових сценаріїв.

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

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

Unit / integration (типовий)

  • Команда: pnpm test
  • Конфігурація: десять послідовних запусків шардів (vitest.full-*.config.ts) поверх наявних scoped-проєктів Vitest
  • Файли: інвентарі core/unit у src/**/*.test.ts, packages/**/*.test.ts, test/**/*.test.ts і дозволені node-тести ui, охоплені vitest.unit.config.ts
  • Область:
    • Чисті unit-тести
    • In-process integration-тести (автентифікація gateway, маршрутизація, інструменти, парсинг, конфігурація)
    • Детерміновані регресії для відомих багів
  • Очікування:
    • Запускається в CI
    • Реальні ключі не потрібні
    • Має бути швидким і стабільним
  • Примітка щодо проєктів:
    • Ненацілений pnpm test тепер запускає одинадцять менших конфігурацій шардів (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 процесу. Це зменшує піковий RSS на завантажених машинах і не дозволяє роботі auto-reply/extension витісняти інші набори.
    • pnpm test --watch і далі використовує native-граф проєкту root vitest.config.ts, оскільки цикл спостереження з кількома шардами непрактичний.
    • pnpm test, pnpm test:watch і pnpm test:perf:imports спочатку маршрутизують явні цілі файлів/каталогів через scoped-лінії, тому pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts уникає повної вартості запуску root project.
    • pnpm test:changed розгортає змінені шляхи git у ті самі scoped-лінії, коли diff зачіпає лише маршрутизовані файли source/test; зміни config/setup, як і раніше, повертаються до широкого повторного запуску root project.
    • Import-light unit-тести з agents, commands, plugins, helper-ів auto-reply, plugin-sdk та подібних чистих utility-областей маршрутизуються через лінію unit-fast, яка пропускає test/setup-openclaw-runtime.ts; stateful/runtime-heavy файли лишаються на наявних лініях.
    • Деякі helper source-файли plugin-sdk і commands також зіставляють запуски changed-mode з явними sibling-тестами в цих легких лініях, тому редагування helper-ів не змушує повторно запускати весь важкий набір для цього каталогу.
    • auto-reply тепер має три окремі бакети: top-level core helper-и, top-level integration-тести reply.* і піддерево src/auto-reply/reply/**. Це тримає найважчу роботу harness reply подалі від дешевих тестів status/chunk/token.
  • Примітка щодо embedded runner:
    • Коли ви змінюєте входи discovery message-tool або runtime-контекст Compaction, зберігайте обидва рівні покриття.
    • Додавайте сфокусовані helper-регресії для чистих меж routing/normalization.
    • Також підтримуйте в доброму стані integration-набори 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-тести не є достатньою заміною для цих integration-шляхів.
  • Примітка щодо pool:
    • Базова конфігурація Vitest тепер типово використовує threads.
    • Спільна конфігурація Vitest також фіксує isolate: false і використовує non-isolated runner у root projects, e2e і live-конфігураціях.
    • Коренева лінія UI зберігає свій jsdom setup і optimizer, але тепер теж працює на спільному non-isolated runner.
    • Кожен shard pnpm test успадковує ті самі типові значення threads + isolate: false зі спільної конфігурації Vitest.
    • Спільний launcher scripts/run-vitest.mjs тепер також типово додає --no-maglev для дочірніх Node-процесів Vitest, щоб зменшити churn компіляції V8 під час великих локальних запусків. Установіть OPENCLAW_VITEST_ENABLE_MAGLEV=1, якщо потрібно порівняти зі стандартною поведінкою V8.
  • Примітка щодо швидкої локальної ітерації:
    • pnpm test:changed маршрутизує через scoped-лінії, коли змінені шляхи чисто зіставляються з меншим набором.
    • pnpm test:max і pnpm test:changed:max зберігають ту саму поведінку маршрутизації, лише з вищим лімітом воркерів.
    • Автомасштабування локальних воркерів тепер навмисно консервативне й також зменшується, коли середнє навантаження хоста вже високе, тож кілька одночасних запусків Vitest за замовчуванням завдають менше шкоди.
    • Базова конфігурація Vitest позначає файли projects/config як forceRerunTriggers, щоб повторні запуски changed-mode лишалися коректними, коли змінюється тестова обв’язка.
    • Конфігурація тримає OPENCLAW_VITEST_FS_MODULE_CACHE увімкненим на підтримуваних хостах; установіть OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path, якщо хочете одну явну локацію кешу для прямого профілювання.
  • Примітка щодо налагодження продуктивності:
    • pnpm test:perf:imports вмикає звітність Vitest щодо тривалості імпорту плюс вивід розбивки імпорту.
    • pnpm test:perf:imports:changed обмежує той самий профілювальний перегляд файлами, зміненими від origin/main.
  • pnpm test:perf:changed:bench -- --ref <git-ref> порівнює маршрутизований test:changed із native-шляхом root project для цього зафіксованого diff і виводить wall time плюс macOS max RSS.
  • pnpm test:perf:changed:bench -- --worktree виконує бенчмарк поточного dirty tree, маршрутизуючи список змінених файлів через scripts/test-projects.mjs і root-конфігурацію Vitest.
    • pnpm test:perf:profile:main записує CPU-профіль main-thread для витрат запуску й transform у Vitest/Vite.
    • pnpm test:perf:profile:runner записує CPU+heap-профілі runner-а для unit-набору з вимкненим паралелізмом файлів.

E2E (gateway smoke)

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

E2E: backend smoke OpenShell

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

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

  • Команда: pnpm test:live
  • Конфігурація: vitest.live.config.ts
  • Файли: src/**/*.live.test.ts
  • Типово: увімкнено через pnpm test:live (встановлює OPENCLAW_LIVE_TEST=1)
  • Область:
    • «Чи працює цей провайдер/модель сьогодні з реальними обліковими даними?»
    • Виявлення змін формату провайдера, особливостей виклику інструментів, проблем автентифікації та поведінки при rate limit
  • Очікування:
    • За задумом нестабільні для CI (реальні мережі, реальні політики провайдерів, квоти, збої)
    • Коштують грошей / витрачають rate limit
    • Краще запускати звужені підмножини, а не «все»
  • 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 для direct-model через OPENCLAW_LIVE_HEARTBEAT_MS.
    • Налаштовуйте Heartbeat для gateway/probe через OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS.

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

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

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

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

Live: smoke моделей (ключі профілів)

Live-тести поділено на два шари, щоб можна було ізолювати збої:
  • «Direct model» показує, чи взагалі може відповісти провайдер/модель із заданим ключем.
  • «Gateway smoke» показує, чи працює для цієї моделі повний конвеєр gateway+agent (сесії, історія, інструменти, політика sandbox тощо).

Шар 1: Direct model completion (без 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 smoke
  • Як вибирати моделі:
    • 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.4,anthropic/claude-opus-4-6,..." (allowlist через кому)
    • Розгортки modern/all за замовчуванням використовують curated high-signal cap; установіть OPENCLAW_LIVE_MAX_MODELS=0 для вичерпного modern sweep або додатне число для меншого ліміту.
  • Як вибирати провайдерів:
    • OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli" (allowlist через кому)
  • Звідки беруться ключі:
    • Типово: profile store і резервні значення з env
    • Установіть OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1, щоб примусово використовувати лише profile store
  • Навіщо це існує:
    • Відокремлює «API провайдера зламане / ключ недійсний» від «зламано конвеєр gateway agent»
    • Містить невеликі ізольовані регресії (приклад: reasoning replay OpenAI Responses/Codex Responses + потоки tool-call)

Шар 2: Gateway + smoke dev agent (що реально робить “@openclaw”)

  • Тест: src/gateway/gateway-models.profiles.live.test.ts
  • Мета:
    • Підняти in-process gateway
    • Створити/оновити сесію agent:dev:* (перевизначення моделі для кожного запуску)
    • Ітеруватися по моделях-із-ключами й перевіряти:
      • «змістовну» відповідь (без інструментів)
      • що реальний виклик інструмента працює (read probe)
      • необов’язкові додаткові перевірки інструментів (exec+read probe)
      • що регресійні шляхи OpenAI (лише tool-call → подальший крок) продовжують працювати
  • Деталі probe (щоб можна було швидко пояснити збої):
    • probe read: тест записує nonce-файл у workspace і просить агента read його та повернути nonce.
    • probe exec+read: тест просить агента записати nonce у тимчасовий файл через exec, а потім прочитати його назад через 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 sweeps типово використовують curated high-signal cap; установіть OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0 для вичерпного modern sweep або додатне число для меншого ліміту.
  • Як вибирати провайдерів (уникати «всього OpenRouter»):
    • OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax" (allowlist через кому)
  • Probe інструментів + зображень у цьому live-тесті завжди ввімкнені:
    • probe read + probe exec+read (навантаження на інструменти)
    • 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-tolerance: незначні помилки допустимі)
Порада: щоб побачити, що саме можна тестувати на вашій машині (і точні ідентифікатори provider/model), виконайте:
openclaw models list
openclaw models list --json

Live: smoke backend CLI (Claude, Codex, Gemini або інші локальні CLI)

  • Тест: src/gateway/gateway-cli-backend.live.test.ts
  • Мета: перевірити конвеєр Gateway + agent із використанням локального backend CLI, не торкаючись вашої типової конфігурації.
  • Типові значення smoke, специфічні для backend, розміщені у визначенні cli-backend.ts extension-власника.
  • Увімкнення:
    • pnpm test:live (або OPENCLAW_LIVE_TEST=1, якщо викликаєте Vitest напряму)
    • OPENCLAW_LIVE_CLI_BACKEND=1
  • Типові значення:
    • Типовий провайдер/модель: claude-cli/claude-sonnet-4-6
    • Поведінка command/args/image походить із метаданих Plugin backend CLI-власника.
  • Перевизначення (необов’язкові):
    • OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4"
    • 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, щоб надіслати другий хід і перевірити flow відновлення.
    • 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.4" \
  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 smoke backend CLI всередині Docker-образу репозиторію як непривілейований користувач node.
  • Він визначає метадані smoke 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 вимагає portable OAuth підписки Claude Code через ~/.claude/.credentials.json із claudeAiOauth.subscriptionType або CLAUDE_CODE_OAUTH_TOKEN з claude setup-token. Спочатку він доводить прямий claude -p у Docker, а потім виконує два ходи Gateway CLI-backend без збереження env-змінних ключа Anthropic API. Ця subscription-лінія типово вимикає Claude MCP/tool і image probes, оскільки Claude наразі маршрутизує використання сторонніх застосунків через білінг extra-usage замість звичайних лімітів плану підписки.
  • Live smoke backend CLI тепер перевіряє той самий наскрізний flow для Claude, Codex і Gemini: текстовий хід, хід класифікації зображення, потім виклик інструмента MCP cron, перевірений через Gateway CLI.
  • Типовий smoke Claude також оновлює сесію з Sonnet до Opus і перевіряє, що відновлена сесія все ще пам’ятає попередню нотатку.

Live: smoke прив’язки ACP (/acp spawn ... --bind here)

  • Тест: src/gateway/gateway-acp-bind.live.test.ts
  • Мета: перевірити реальний flow conversation-bind ACP із live ACP-агентом:
    • надіслати /acp spawn <agent> --bind here
    • прив’язати synthetic conversation каналу повідомлень на місці
    • надіслати звичайне подальше повідомлення в цій самій conversation
    • перевірити, що подальше повідомлення потрапляє в transcript прив’язаної сесії 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
    • Synthetic channel: контекст conversation у стилі Slack DM
    • Backend ACP: 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>'
  • Примітки:
    • Ця лінія використовує поверхню gateway chat.send з synthetic-полями originating-route лише для адміністратора, щоб тести могли додавати контекст message-channel без імітації зовнішньої доставки.
    • Коли OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND не задано, тест використовує вбудований реєстр агентів Plugin acpx для вибраного ACP harness-агента.
Приклад:
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.
  • Типово він послідовно запускає smoke прив’язки ACP для всіх підтримуваних live CLI-агентів: 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-змінні провайдера із sourced profile доступними для дочірнього harness CLI.

Live: smoke harness app-server Codex

  • Мета: перевірити harness Codex, що належить Plugin, через звичайний метод gateway agent:
    • завантажити вбудований Plugin codex
    • вибрати OPENCLAW_AGENT_RUNTIME=codex
    • надіслати перший хід gateway agent до codex/gpt-5.4
    • надіслати другий хід у ту саму сесію OpenClaw і перевірити, що thread app-server може відновитися
    • запустити /codex status і /codex models через той самий шлях команди gateway
  • Тест: src/gateway/gateway-codex-harness.live.test.ts
  • Увімкнення: OPENCLAW_LIVE_CODEX_HARNESS=1
  • Типова модель: codex/gpt-5.4
  • Необов’язковий image probe: OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1
  • Необов’язковий MCP/tool probe: OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1
  • Smoke встановлює OPENCLAW_AGENT_HARNESS_FALLBACK=none, щоб зламаний harness Codex не міг пройти тест, тихо переключившись на запасний PI.
  • Auth: 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_MODEL=codex/gpt-5.4 \
  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, копіює файли auth Codex CLI, якщо вони є, встановлює @openai/codex у записуваний змонтований npm префікс, підготовлює дерево вихідного коду, а потім запускає лише live-тест Codex-harness.
  • Docker типово вмикає image і MCP/tool probes. Установіть OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 або OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0, коли потрібен вужчий запуск для налагодження.
  • Docker також експортує OPENCLAW_AGENT_HARNESS_FALLBACK=none, узгоджено з live- конфігурацією тесту, щоб запасний перехід на openai-codex/* або PI не міг приховати регресію harness Codex.

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

Вузькі, явні allowlist — найшвидші та найменш нестабільні:
  • Одна модель, direct (без gateway):
    • OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts
  • Одна модель, gateway smoke:
    • OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
  • Виклик інструментів для кількох провайдерів:
    • OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,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/... використовує міст OAuth Antigravity (endpoint агента у стилі Cloud Code Assist).
  • google-gemini-cli/... використовує локальний Gemini CLI на вашій машині (окрема автентифікація + особливості інструментів).
  • Gemini API проти Gemini CLI:
    • API: OpenClaw викликає розміщений Google Gemini API через HTTP (автентифікація через API-ключ / профіль); це те, що більшість користувачів мають на увазі під «Gemini».
    • CLI: OpenClaw виконує shell-виклик локального двійкового файла gemini; він має власну автентифікацію і може поводитися інакше (streaming/підтримка інструментів/version skew).

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

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

Сучасний smoke-набір (виклик інструментів + зображення)

Це запуск «поширених моделей», який ми очікуємо зберігати працездатним:
  • OpenAI (не Codex): openai/gpt-5.4 (необов’язково: openai/gpt-5.4-mini)
  • OpenAI Codex: openai-codex/gpt-5.4
  • 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 smoke з інструментами + зображенням: OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,openai-codex/gpt-5.4,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.4 (або 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: надсилання зображення (вкладення → мультимодальне повідомлення)

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

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

Якщо у вас увімкнено ключі, ми також підтримуємо тестування через:
  • OpenRouter: openrouter/... (сотні моделей; використовуйте openclaw models scan, щоб знайти кандидатів із підтримкою tool+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 endpoints): minimax (cloud/API), а також будь-який OpenAI/Anthropic-сумісний проксі (LM Studio, vLLM, LiteLLM тощо)
Порада: не намагайтеся жорстко закодувати в документації «усі моделі». Авторитетний список — це все, що discoverModels(...) повертає на вашій машині + усі доступні ключі.

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

Live-тести виявляють облікові дані так само, як і CLI. Практичні наслідки:
  • Якщо CLI працює, live-тести мають знаходити ті самі ключі.
  • Якщо live-тест каже «немає облікових даних», налагоджуйте це так само, як налагоджували б openclaw models list / вибір моделі.
  • Профілі автентифікації для кожного агента: ~/.openclaw/agents/<agentId>/agent/auth-profiles.json (саме це означають «profile keys» у live-тестах)
  • Конфігурація: ~/.openclaw/openclaw.json (або OPENCLAW_CONFIG_PATH)
  • Каталог застарілого стану: ~/.openclaw/credentials/ (копіюється у staged live home, якщо присутній, але це не основне сховище profile keys)
  • Локальні live-запуски за замовчуванням копіюють активну конфігурацію, файли auth-profiles.json для кожного агента, застарілий credentials/ і підтримувані зовнішні каталоги автентифікації CLI у тимчасовий test home; staged live home пропускають workspace/ і sandboxes/, а перевизначення шляхів agents.*.workspace / agentDir видаляються, щоб probes не працювали у вашому реальному хостовому workspace.
Якщо ви хочете покладатися на env-ключі (наприклад, експортовані у вашому ~/.profile), запускайте локальні тести після source ~/.profile або використовуйте Docker-раннери нижче (вони можуть змонтувати ~/.profile у контейнер).

Live: Deepgram (транскрибування аудіо)

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

Live: план кодування BytePlus

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

Live: медіа workflow ComfyUI

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

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

  • Тест: src/image-generation/runtime.live.test.ts
  • Команда: pnpm test:live src/image-generation/runtime.live.test.ts
  • Harness: pnpm test:live:media image
  • Область:
    • Перелічує кожен зареєстрований Plugin провайдера генерації зображень
    • Завантажує відсутні env-змінні провайдерів із вашого login shell (~/.profile) перед probe
    • За замовчуванням використовує live/env API-ключі раніше за збережені профілі автентифікації, щоб застарілі тестові ключі в auth-profiles.json не маскували реальні shell-облікові дані
    • Пропускає провайдерів без придатної автентифікації/профілю/моделі
    • Запускає стандартні варіанти генерації зображень через спільну runtime-можливість:
      • google:flash-generate
      • google:pro-generate
      • google:pro-edit
      • openai:default-generate
  • Поточні вбудовані провайдери в покритті:
    • openai
    • google
  • Необов’язкове звуження:
    • OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="openai,google"
    • OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-1,google/gemini-3.1-flash-image-preview"
    • OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit"
  • Необов’язкова поведінка автентифікації:
    • OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1, щоб примусово використовувати автентифікацію profile store і ігнорувати перевизначення лише через 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
  • Область:
    • Перевіряє спільний шлях вбудованого провайдера генерації музики
    • Наразі охоплює Google і MiniMax
    • Завантажує env-змінні провайдерів із вашого login shell (~/.profile) перед probe
    • За замовчуванням використовує live/env API-ключі раніше за збережені профілі автентифікації, щоб застарілі тестові ключі в 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, щоб примусово використовувати автентифікацію profile store і ігнорувати перевизначення лише через 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
  • Область:
    • Перевіряє спільний шлях вбудованого провайдера генерації відео
    • Завантажує env-змінні провайдерів із вашого login shell (~/.profile) перед probe
    • За замовчуванням використовує live/env API-ключі раніше за збережені профілі автентифікації, щоб застарілі тестові ключі в auth-profiles.json не маскували реальні shell-облікові дані
    • Пропускає провайдерів без придатної автентифікації/профілю/моделі
    • Запускає обидва оголошені runtime-режими, коли вони доступні:
      • generate із вхідними даними лише у вигляді prompt
      • imageToVideo, коли провайдер оголошує capabilities.imageToVideo.enabled і вибраний провайдер/модель приймає локальне введення зображення на основі buffer у спільній розгортці
      • videoToVideo, коли провайдер оголошує capabilities.videoToVideo.enabled і вибраний провайдер/модель приймає локальне введення відео на основі buffer у спільній розгортці
    • Поточні провайдери imageToVideo, оголошені, але пропущені у спільній розгортці:
      • vydra, оскільки вбудований veo3 є лише текстовим, а вбудований kling вимагає віддалений 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, яка типово використовує фікстуру з віддаленим URL зображення
    • Поточне live-покриття videoToVideo:
      • лише runway, коли вибрана модель — runway/gen4_aleph
    • Поточні провайдери videoToVideo, оголошені, але пропущені у спільній розгортці:
      • alibaba, qwen, xai, оскільки ці шляхи наразі вимагають віддалені reference URL http(s) / MP4
      • google, оскільки поточна спільна лінія Gemini/Veo використовує локальне введення на основі buffer, а цей шлях не приймається у спільній розгортці
      • openai, оскільки поточна спільна лінія не гарантує доступ до org-specific 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_REQUIRE_PROFILE_KEYS=1, щоб примусово використовувати автентифікацію profile store і ігнорувати перевизначення лише через env

Harness live для медіа

  • Команда: pnpm test:live:media
  • Призначення:
    • Запускає спільні live-набори для зображень, музики й відео через один рідний для репозиторію 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-моделей: test:docker:live-models і test:docker:live-gateway запускають лише відповідний їм profile-key live-файл усередині Docker-образу репозиторію (src/agents/models.profiles.live.test.ts і src/gateway/gateway-models.profiles.live.test.ts), монтують ваш локальний каталог config і workspace (та використовують ~/.profile, якщо його змонтовано). Відповідні локальні entrypoint-и: test:live:models-profiles і test:live:gateway-profiles.
  • Docker-раннери live типово використовують менший smoke-ліміт, щоб повна 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.
  • Раннери container smoke: test:docker:openwebui, test:docker:onboard, test:docker:gateway-network, test:docker:mcp-channels і test:docker:plugins піднімають один або кілька реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня.
Docker-раннери live-моделей також bind-mount-ять лише потрібні домівки автентифікації CLI (або всі підтримувані, якщо запуск не звужено), а потім копіюють їх у домашній каталог контейнера перед запуском, щоб OAuth зовнішніх CLI міг оновлювати токени без змін у host auth store:
  • Direct models: pnpm test:docker:live-models (скрипт: scripts/test-live-models-docker.sh)
  • Smoke прив’язки ACP: pnpm test:docker:live-acp-bind (скрипт: scripts/test-live-acp-bind-docker.sh)
  • Smoke backend CLI: pnpm test:docker:live-cli-backend (скрипт: scripts/test-live-cli-backend-docker.sh)
  • Smoke 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)
  • Live smoke Open WebUI: pnpm test:docker:openwebui (скрипт: scripts/e2e/openwebui-docker.sh)
  • Wizard onboarding (TTY, повна scaffolding): pnpm test:docker:onboard (скрипт: scripts/e2e/onboard-docker.sh)
  • Мережева взаємодія Gateway (два контейнери, WS auth + health): pnpm test:docker:gateway-network (скрипт: scripts/e2e/gateway-network-docker.sh)
  • Міст каналу MCP (ініціалізований Gateway + міст stdio + raw smoke notification-frame Claude): pnpm test:docker:mcp-channels (скрипт: scripts/e2e/mcp-channels-docker.sh)
  • Plugins (smoke встановлення + аліас /plugin + семантика перезапуску Claude-bundle): pnpm test:docker:plugins (скрипт: scripts/e2e/plugins-docker.sh)
Docker-раннери live-моделей також bind-mount-ять поточний checkout лише для читання і підготовлюють його в тимчасовий workdir усередині контейнера. Це зберігає runtime- образ компактним, але все одно дозволяє запускати Vitest точно по вашому локальному source/config. Крок підготовки пропускає великі локальні кеші й результати збірки застосунків, такі як .pnpm-store, .worktrees, __openclaw_vitest__ і локальні для застосунків каталоги .build або виводу Gradle, щоб live-запуски Docker не витрачали хвилини на копіювання машиноспецифічних артефактів. Вони також встановлюють 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 — це compatibility smoke вищого рівня: він запускає контейнер Gateway OpenClaw з увімкненими HTTP-endpoint-ами, сумісними з OpenAI, запускає прив’язаний контейнер Open WebUI проти цього gateway, входить через Open WebUI, перевіряє, що /api/models показує openclaw/default, а потім надсилає реальний chat-запит через проксі Open WebUI /api/chat/completions. Перший запуск може бути помітно повільнішим, оскільки Docker може потребувати завантаження образу Open WebUI, а Open WebUI — завершення власного cold-start setup. Ця лінія очікує придатний ключ live-моделі, а OPENCLAW_PROFILE_FILE (типово ~/.profile) є основним способом надати його в Docker-запусках. Успішні запуски виводять невеликий JSON payload на кшталт { "ok": true, "model": "openclaw/default", ... }. test:docker:mcp-channels навмисно детермінований і не потребує реального облікового запису Telegram, Discord чи iMessage. Він піднімає ініціалізований контейнер Gateway, запускає другий контейнер, який стартує openclaw mcp serve, а потім перевіряє виявлення conversation через маршрутизацію, читання transcript, метадані вкладень, поведінку черги live-подій, маршрутизацію outbound send і сповіщення у стилі Claude про канал + дозволи через реальний міст stdio MCP. Перевірка сповіщень напряму аналізує raw stdio MCP frames, тож smoke перевіряє те, що міст справді випромінює, а не лише те, що випадково показує конкретний SDK клієнта. Ручний smoke plain-language thread ACP (не CI):
  • bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...
  • Залишайте цей скрипт для workflow регресії/налагодження. Він може знову знадобитися для перевірки маршрутизації тредів ACP, тож не видаляйте його.
Корисні 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_CLI_TOOLS_DIR=... (типово: ~/.cache/openclaw/docker-cli-tools) монтується в /home/node/.npm-global для кешованих встановлень CLI всередині Docker
  • Зовнішні каталоги/файли автентифікації 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, щоб гарантувати, що облікові дані беруться з profile store (а не з env)
  • OPENCLAW_OPENWEBUI_MODEL=..., щоб вибрати модель, яку gateway показує для smoke Open WebUI
  • OPENCLAW_OPENWEBUI_PROMPT=..., щоб перевизначити prompt перевірки nonce, який використовує smoke Open WebUI
  • OPENWEBUI_IMAGE=..., щоб перевизначити зафіксований тег образу Open WebUI

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

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

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

Це регресії «реального конвеєра» без реальних провайдерів:
  • Виклик інструментів Gateway (mock OpenAI, реальний цикл gateway + agent): src/gateway/gateway.test.ts (випадок: “runs a mock OpenAI tool call end-to-end via gateway agent loop”)
  • Wizard Gateway (WS wizard.start/wizard.next, запис config + примусова auth): src/gateway/gateway.test.ts (випадок: “runs wizard over ws and writes auth token config”)

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

У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності агентів»:
  • Mock-виклик інструментів через реальний цикл gateway + agent (src/gateway/gateway.test.ts).
  • Наскрізні потоки wizard, які перевіряють wiring сесій і ефекти конфігурації (src/gateway/gateway.test.ts).
Чого ще бракує для Skills (див. Skills):
  • Прийняття рішень: коли Skills перелічені в prompt, чи вибирає агент правильний Skill (або уникає нерелевантних)?
  • Відповідність: чи читає агент SKILL.md перед використанням і виконує обов’язкові кроки/аргументи?
  • Контракти workflow: багатокрокові сценарії, які перевіряють порядок інструментів, перенесення історії сесії та межі sandbox.
Майбутні eval-оцінювання мають насамперед залишатися детермінованими:
  • Раннер сценаріїв, що використовує mock-провайдери для перевірки викликів інструментів + порядку, читання файлів Skill і wiring сесій.
  • Невеликий набір сценаріїв, сфокусованих на Skills (використовувати чи уникати, гейтінг, prompt injection).
  • Необов’язкові live-оцінювання (за згодою, з env-gating) лише після того, як безпечний для CI набір уже існуватиме.

Контрактні тести (форма Plugin і каналу)

Контрактні тести перевіряють, що кожен зареєстрований Plugin і канал відповідає контракту свого інтерфейсу. Вони ітеруються по всіх виявлених Plugin і запускають набір перевірок форми та поведінки. Типова unit-лінія pnpm test навмисно пропускає ці shared seam і smoke-файли; запускайте контрактні команди явно, коли зачіпаєте спільні поверхні каналу або провайдера.

Команди

  • Усі контракти: pnpm test:contracts
  • Лише контракти каналів: pnpm test:contracts:channels
  • Лише контракти провайдерів: pnpm test:contracts:plugins

Контракти каналів

Розташовані в src/channels/plugins/contracts/*.contract.test.ts:
  • plugin - Базова форма Plugin (id, name, capabilities)
  • setup - Контракт wizard налаштування
  • session-binding - Поведінка прив’язки сесії
  • outbound-payload - Структура payload повідомлення
  • inbound - Обробка вхідних повідомлень
  • actions - Обробники дій каналу
  • threading - Обробка ID тредів
  • directory - API каталогу/складу
  • group-policy - Забезпечення group policy

Контракти статусу провайдера

Розташовані в src/plugins/contracts/*.contract.test.ts.
  • status - Status probe каналу
  • registry - Форма реєстру Plugin

Контракти провайдерів

Розташовані в src/plugins/contracts/*.contract.test.ts:
  • auth - Контракт потоку auth
  • auth-choice - Вибір/селекція auth
  • catalog - API каталогу моделей
  • discovery - Виявлення Plugin
  • loader - Завантаження Plugin
  • runtime - Runtime провайдера
  • shape - Форма/інтерфейс Plugin
  • wizard - Wizard налаштування

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

  • Після зміни export-ів або subpath-ів plugin-sdk
  • Після додавання або зміни каналу чи Plugin провайдера
  • Після рефакторингу реєстрації або виявлення Plugin
Контрактні тести запускаються в CI і не потребують реальних API-ключів.

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

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