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

Тестування

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

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

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

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

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

Unit / integration (типово)

  • Команда: pnpm test
  • Конфігурація: рідні Vitest projects через vitest.config.ts
  • Файли: core/unit inventories у src/**/*.test.ts, packages/**/*.test.ts, test/**/*.test.ts та дозволені node-тести ui, які покриває vitest.unit.config.ts
  • Обсяг:
    • Чисті unit-тести
    • Внутрішньопроцесні integration-тести (gateway auth, routing, tooling, parsing, config)
    • Детерміновані регресії для відомих помилок
  • Очікування:
    • Запускається в CI
    • Не потребує реальних ключів
    • Має бути швидким і стабільним
  • Примітка щодо проєктів:
    • pnpm test, pnpm test:watch і pnpm test:changed тепер усі використовують ту саму рідну кореневу конфігурацію Vitest projects.
    • Прямі фільтри файлів рідно маршрутизуються через граф кореневого проєкту, тому pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts працює без спеціальної обгортки.
  • Примітка щодо вбудованого раннера:
    • Коли ви змінюєте входи виявлення message-tool або контекст runtime compaction, зберігайте обидва рівні покриття.
    • Додавайте сфокусовані helper-регресії для чистих меж routing/normalization.
    • Також підтримуйте в здоровому стані integration-набори вбудованого раннера: 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 і використовує неізольований раннер у кореневих проєктах, e2e та live-конфігураціях.
    • Кореневий lane UI зберігає своє налаштування jsdom та optimizer, але тепер також працює на спільному неізольованому раннері.
    • pnpm test успадковує ті самі типові значення threads + isolate: false із конфігурації проєктів у кореневому vitest.config.ts.
    • Спільний launcher scripts/run-vitest.mjs тепер також типово додає --no-maglev для дочірніх Node-процесів Vitest, щоб зменшити churn компіляції V8 під час великих локальних запусків. Установіть OPENCLAW_VITEST_ENABLE_MAGLEV=1, якщо потрібно порівняти зі стандартною поведінкою V8.
  • Примітка щодо швидкої локальної ітерації:
    • pnpm test:changed запускає рідну конфігурацію проєктів із --changed origin/main.
    • pnpm test:max і pnpm test:changed:max зберігають ту саму рідну конфігурацію проєктів, лише з вищою межею workers.
    • Автомасштабування локальних workers тепер навмисно консервативне й також зменшується, коли середнє навантаження хоста вже високе, тому кілька паралельних запусків Vitest типово завдають менше шкоди.
    • Базова конфігурація Vitest позначає файли projects/config як forceRerunTriggers, щоб повторні запуски в changed-режимі залишалися коректними, коли змінюється тестова обв’язка.
    • Конфігурація зберігає 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:profile:main записує CPU-профіль головного потоку для накладних витрат запуску та transform у Vitest/Vite.
    • pnpm test:perf:profile:runner записує CPU+heap профілі раннера для unit-набору з вимкненим файловим паралелізмом.

E2E (gateway smoke)

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

E2E: OpenShell backend smoke

  • Команда: pnpm test:e2e:openshell
  • Файл: test/openshell-sandbox.e2e.test.ts
  • Обсяг:
    • Запускає ізольований OpenShell gateway на хості через Docker
    • Створює sandbox з тимчасового локального Dockerfile
    • Перевіряє OpenShell backend OpenClaw через реальні sandbox ssh-config + SSH exec
    • Перевіряє remote-canonical поведінку файлової системи через sandbox fs bridge
  • Очікування:
    • Лише opt-in; не входить до типового запуску pnpm test:e2e
    • Потрібен локальний CLI openshell і працездатний Docker daemon
    • Використовує ізольовані HOME / XDG_CONFIG_HOME, після чого знищує тестовий 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
  • Типово: увімкнено через pnpm test:live (встановлює OPENCLAW_LIVE_TEST=1)
  • Обсяг:
    • «Чи справді цей провайдер/модель працює сьогодні з реальними обліковими даними?»
    • Виявлення змін формату провайдера, особливостей tool-calling, проблем auth і поведінки rate limit
  • Очікування:
    • Навмисно нестабільне для CI (реальні мережі, реальні політики провайдерів, квоти, збої)
    • Коштує грошей / використовує rate limits
    • Краще запускати звужені підмножини, а не «все»
  • Live-запуски джерелять ~/.profile, щоб підхопити відсутні API-ключі.
  • Типово live-запуски все ще ізолюють HOME і копіюють config/auth-матеріали у тимчасовий тестовий 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 testpnpm test:coverage, якщо змінили багато)
  • Торкаєтеся gateway networking / WS protocol / pairing: додайте pnpm test:e2e
  • Налагоджуєте «мій бот не працює» / специфічні збої провайдера / tool calling: запускайте звужений pnpm test:live

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

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

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

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

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

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

Рівень 2: Gateway + smoke dev agent (що насправді робить “@openclaw”)

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

Live: smoke 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
    • прив’язати synthetic message-channel conversation на місці
    • надіслати звичайний follow-up у тій самій conversation
    • перевірити, що follow-up потрапляє в transcript прив’язаної ACP session
  • Увімкнення:
    • pnpm test:live src/gateway/gateway-acp-bind.live.test.ts
    • OPENCLAW_LIVE_ACP_BIND=1
  • Типові значення:
    • ACP agent: claude
    • Synthetic channel: контекст conversation у стилі Slack DM
    • ACP backend: acpx
  • Перевизначення:
    • OPENCLAW_LIVE_ACP_BIND_AGENT=claude
    • OPENCLAW_LIVE_ACP_BIND_AGENT=codex
    • OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@<version>'
  • Примітки:
    • Цей lane використовує поверхню gateway chat.send з admin-only synthetic originating-route полями, щоб тести могли прикріплювати контекст message-channel без удавання зовнішньої доставки.
    • Коли OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND не встановлено, тест використовує вбудований реєстр агентів плагіна 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:
  • Docker-ранер розташований у scripts/test-live-acp-bind-docker.sh.
  • Він джерелить ~/.profile, переносить відповідні CLI auth-матеріали в контейнер, встановлює acpx у записуваний npm prefix, а потім встановлює потрібний live CLI (@anthropic-ai/claude-code або @openai/codex), якщо його немає.
  • Усередині Docker раннер встановлює OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx, щоб acpx зберігав змінні середовища провайдера, отримані з джереленого профілю, доступними для дочірнього harness CLI.

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

Вузькі, явні allowlist — найшвидші й найменш крихкі:
  • Одна модель, напряму (без 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
  • Tool calling через кількох провайдерів:
    • 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 (Gemini API key + Antigravity):
    • Gemini (API key): 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 key).
  • google-antigravity/... використовує OAuth-міст Antigravity (кінцева точка агента у стилі Cloud Code Assist).

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

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

Сучасний smoke-набір (tool calling + image)

Це запуск «поширених моделей», який ми очікуємо підтримувати в робочому стані:
  • 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 з tools + image: 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

Базовий набір: tool calling (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/… (локально; tool calling залежить від режиму API)

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

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

Aggregators / альтернативні gateway

Якщо у вас увімкнені ключі, ми також підтримуємо тестування через:
  • OpenRouter: openrouter/... (сотні моделей; використовуйте openclaw models scan, щоб знайти кандидати з підтримкою tools+image)
  • OpenCode: opencode/... для Zen і opencode-go/... для Go (auth через OPENCODE_API_KEY / OPENCODE_ZEN_API_KEY)
Більше провайдерів, які можна включити в live-матрицю (якщо у вас є облікові дані/config):
  • Вбудовані: openai, openai-codex, anthropic, google, google-vertex, google-antigravity, zai, openrouter, opencode, opencode-go, xai, groq, cerebras, mistral, github-copilot
  • Через models.providers (власні endpoints): minimax (cloud/API), а також будь-який OpenAI/Anthropic-compatible proxy (LM Studio, vLLM, LiteLLM тощо)
Порада: не намагайтеся жорстко прописати в документації «усі моделі». Авторитетним списком є все, що повертає discoverModels(...) на вашій машині + усі доступні ключі.

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

Live-тести знаходять облікові дані так само, як це робить CLI. Практичні наслідки:
  • Якщо CLI працює, live-тести мають знаходити ті самі ключі.
  • Якщо live-тест каже «немає облікових даних», налагоджуйте це так само, як налагоджували б openclaw models list / вибір моделі.
  • Профілі auth для окремих агентів: ~/.openclaw/agents/<agentId>/agent/auth-profiles.json (саме це в live-тестах означає «ключі профілів»)
  • Config: ~/.openclaw/openclaw.json (або OPENCLAW_CONFIG_PATH)
  • Каталог застарілого стану: ~/.openclaw/credentials/ (копіюється в підготовлений live-home за наявності, але не є основним сховищем ключів профілів)
  • Локальні live-запуски типово копіюють активний config, файли auth-profiles.json для кожного агента, застарілий credentials/ і підтримувані зовнішні CLI auth-каталоги в тимчасовий тестовий home; перевизначення шляхів agents.*.workspace / agentDir прибираються з цього staged config, щоб 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 coding plan

  • Тест: 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 image generation

  • Тест: src/image-generation/runtime.live.test.ts
  • Команда: pnpm test:live src/image-generation/runtime.live.test.ts
  • Обсяг:
    • Перелічує кожен зареєстрований плагін провайдера image-generation
    • Завантажує відсутні env-змінні провайдера з вашого login shell (~/.profile) перед probe
    • Типово використовує live/env API keys раніше за збережені auth-профілі, щоб застарілі тестові ключі в auth-profiles.json не маскували реальні shell credentials
    • Пропускає провайдерів без придатного auth/profile/model
    • Проганяє стандартні варіанти image-generation через спільну runtime capability:
      • 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"
  • Необов’язкова поведінка auth:
    • OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1 щоб примусово використовувати auth зі сховища профілів і ігнорувати перевизначення лише з env

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

Ці Docker-ранери поділяються на дві категорії:
  • Live-model ранери: test:docker:live-models і test:docker:live-gateway запускають лише відповідний live-файл із ключами профілів усередині Docker-образу репозиторію (src/agents/models.profiles.live.test.ts і src/gateway/gateway-models.profiles.live.test.ts), монтують ваш локальний config directory і workspace (і джерелять ~/.profile, якщо він змонтований). Відповідні локальні entrypoints: 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 image один раз через test:docker:live-build, а потім повторно використовує його для двох Docker lane live.
  • Smoke-ранери контейнерів: test:docker:openwebui, test:docker:onboard, test:docker:gateway-network, test:docker:mcp-channels і test:docker:plugins піднімають один або кілька реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня.
Live-model Docker-ранери також bind-mount лише потрібні CLI auth homes (або всі підтримувані, коли запуск не звужено), а потім копіюють їх у home контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени без змінення auth-store хоста:
  • Прямі моделі: pnpm test:docker:live-models (скрипт: scripts/test-live-models-docker.sh)
  • ACP bind smoke: pnpm test:docker:live-acp-bind (скрипт: scripts/test-live-acp-bind-docker.sh)
  • Gateway + dev agent: pnpm test:docker:live-gateway (скрипт: scripts/test-live-gateway-models-docker.sh)
  • Open WebUI live smoke: pnpm test:docker:openwebui (скрипт: scripts/e2e/openwebui-docker.sh)
  • Майстер onboarding (TTY, повне scaffold-налаштування): 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 channel (seeded Gateway + stdio bridge + raw Claude notification-frame smoke): 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)
Live-model Docker-ранери також bind-mount поточний checkout лише для читання і поміщають його в тимчасовий workdir усередині контейнера. Це зберігає runtime image компактним, але все одно дає змогу запускати Vitest точно проти вашого локального source/config. Під час staging пропускаються великі локальні кеші й артефакти збирання застосунків, такі як .pnpm-store, .worktrees, __openclaw_vitest__, а також локальні для застосунків .build чи каталоги виводу Gradle, щоб Docker live-запуски не витрачали хвилини на копіювання артефактів, специфічних для машини. Вони також встановлюють OPENCLAW_SKIP_CHANNELS=1, щоб gateway live-probes не запускали реальні channel workers Telegram/Discord тощо всередині контейнера. test:docker:live-models усе ще запускає pnpm test:live, тому також передавайте OPENCLAW_LIVE_GATEWAY_*, коли потрібно звузити або виключити покриття gateway live із цього Docker lane. test:docker:openwebui — це compatibility smoke вищого рівня: він запускає контейнер gateway OpenClaw з увімкненими HTTP endpoints, сумісними з OpenAI, запускає прив’язаний контейнер Open WebUI проти цього gateway, входить через Open WebUI, перевіряє, що /api/models показує openclaw/default, а потім надсилає реальний chat request через проксі /api/chat/completions Open WebUI. Перший запуск може бути помітно повільнішим, оскільки Docker може потребувати завантаження image Open WebUI, а самому Open WebUI може знадобитися завершити власний cold-start setup. Цей lane очікує придатний ключ live-моделі, а OPENCLAW_PROFILE_FILE (~/.profile за замовчуванням) є основним способом надати його в Dockerized runs. Успішні запуски друкують невеликий JSON payload на кшталт { "ok": true, "model": "openclaw/default", ... }. test:docker:mcp-channels навмисно детермінований і не потребує реального облікового запису Telegram, Discord або iMessage. Він піднімає seeded Gateway container, запускає другий container, який стартує openclaw mcp serve, а потім перевіряє виявлення маршрутизованих conversation, читання transcript, attachment metadata, поведінку черги live events, outbound send routing, а також сповіщення каналу + дозволів у стилі Claude через реальний stdio MCP bridge. Перевірка сповіщень безпосередньо інспектує raw stdio MCP frames, тож smoke перевіряє те, що міст реально випромінює, а не лише те, що випадково надає певний client SDK. Ручний smoke plain-language thread ACP (не для CI):
  • bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...
  • Зберігайте цей скрипт для робочих процесів регресії/налагодження. Він може знову знадобитися для перевірки маршрутизації 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_CLI_TOOLS_DIR=... (типово: ~/.cache/openclaw/docker-cli-tools) монтується в /home/node/.npm-global для кешованих установок CLI усередині Docker
  • Зовнішні CLI auth-каталоги/файли під $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_LIVE_REQUIRE_PROFILE_KEYS=1 щоб гарантувати, що облікові дані надходять зі сховища профілів (а не з env)
  • OPENCLAW_OPENWEBUI_MODEL=... щоб вибрати модель, яку gateway показує для smoke Open WebUI
  • OPENCLAW_OPENWEBUI_PROMPT=... щоб перевизначити nonce-check prompt, який використовується у smoke Open WebUI
  • OPENWEBUI_IMAGE=... щоб перевизначити прив’язаний тег image Open WebUI

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

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

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

Це регресії «реального конвеєра» без реальних провайдерів:
  • Tool calling gateway (mock OpenAI, реальний gateway + agent loop): 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”)

Evals надійності агентів (Skills)

У нас уже є кілька безпечних для CI тестів, які поводяться як «evals надійності агентів»:
  • Mock tool-calling через реальний gateway + agent loop (src/gateway/gateway.test.ts).
  • Наскрізні потоки wizard, які перевіряють обв’язку session і ефекти config (src/gateway/gateway.test.ts).
Чого ще бракує для Skills (див. Skills):
  • Вибір рішень: коли Skills перелічено в prompt, чи обирає агент правильну skill (або уникає нерелевантних)?
  • Відповідність вимогам: чи читає агент SKILL.md перед використанням і чи дотримується потрібних кроків/аргументів?
  • Контракти робочих процесів: багатокрокові сценарії, які перевіряють порядок tools, перенесення history session і межі sandbox.
Майбутні evals спочатку мають залишатися детермінованими:
  • Ранер сценаріїв із mock-провайдерами для перевірки викликів tools + їх порядку, читання skill-файлів і обв’язки session.
  • Невеликий набір сценаріїв, орієнтованих на skills (використовувати чи уникати, gate-умови, prompt injection).
  • Необов’язкові live evals (opt-in, з керуванням через env) лише після появи безпечного для CI набору.

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

Контрактні тести перевіряють, що кожен зареєстрований plugin і channel відповідає своєму контракту інтерфейсу. Вони ітеруються по всіх виявлених plugins і запускають набір перевірок форми й поведінки. Типовий unit lane 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 - Поведінка прив’язки session
  • outbound-payload - Структура payload повідомлення
  • inbound - Обробка вхідних повідомлень
  • actions - Обробники дій channel
  • threading - Обробка thread ID
  • directory - API directory/roster
  • group-policy - Застосування group policy

Контракти status provider

Розташовані в src/plugins/contracts/*.contract.test.ts.
  • status - Перевірки status channel
  • registry - Форма реєстру plugin

Контракти provider

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

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

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

Додавання регресій (настанови)

Коли ви виправляєте проблему провайдера/моделі, виявлену в live:
  • Додайте безпечну для CI регресію, якщо це можливо (mock/stub провайдер, або зафіксуйте точне перетворення форми запиту)
  • Якщо це за своєю природою лише live-проблема (rate limits, політики auth), залишайте live-тест вузьким і opt-in через env-змінні
  • Намагайтеся націлюватися на найменший шар, який ловить помилку:
    • помилка перетворення/відтворення запиту провайдера → тест direct models
    • помилка конвеєра gateway session/history/tool → gateway live smoke або безпечний для CI mock-тест gateway
  • Захисне обмеження обходу 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, щоб нові класи не можна було тихо пропустити.