메인 콘텐츠로 건너뛰기

테스트

OpenClaw에는 세 가지 Vitest 스위트(unit/integration, e2e, live)와 소수의 Docker 러너가 있습니다. 이 문서는 “우리가 테스트하는 방법” 가이드입니다.
  • 각 스위트가 무엇을 다루는지(그리고 의도적으로 무엇을 다루지 않는지)
  • 일반적인 워크플로(로컬, 푸시 전, 디버깅)에서 어떤 명령을 실행해야 하는지
  • live 테스트가 자격 증명을 어떻게 찾고 모델/Provider를 어떻게 선택하는지
  • 실제 모델/Provider 이슈에 대한 회귀 테스트를 추가하는 방법

빠른 시작

대부분의 날에는:
  • 전체 게이트(푸시 전 기대되는 항목): pnpm build && pnpm check && pnpm test
  • 여유 있는 머신에서 더 빠른 로컬 전체 스위트 실행: pnpm test:max
  • 직접 Vitest watch 루프 실행: pnpm test:watch
  • 이제 직접 파일 지정 시 extension/channel 경로도 라우팅됩니다: pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts
  • 단일 실패를 반복적으로 수정하는 중이라면 먼저 범위를 좁힌 실행을 선호하세요.
  • Docker 기반 QA 사이트: pnpm qa:lab:up
  • Linux VM 기반 QA 레인: pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline
테스트를 건드렸거나 추가 확신이 필요할 때:
  • 커버리지 게이트: pnpm test:coverage
  • E2E 스위트: pnpm test:e2e
실제 Provider/모델을 디버깅할 때(실제 자격 증명 필요):
  • live 스위트(모델 + Gateway tool/image 프로브): pnpm test:live
  • 하나의 live 파일만 조용히 타깃팅: pnpm test:live -- src/agents/models.profiles.live.test.ts
팁: 실패한 케이스 하나만 필요하다면, 아래에 설명된 allowlist 환경 변수로 live 테스트 범위를 좁히는 방식을 선호하세요.

QA 전용 러너

이 명령들은 QA-lab 수준의 현실성이 필요할 때 메인 테스트 스위트와 함께 사용합니다.
  • pnpm openclaw qa suite
    • 호스트에서 리포지토리 기반 QA 시나리오를 직접 실행합니다.
    • 기본적으로 격리된 Gateway 워커와 함께 여러 선택된 시나리오를 병렬 실행하며, 최대 64개 워커 또는 선택한 시나리오 수까지 사용합니다. 워커 수를 조정하려면 --concurrency <count>를, 이전 직렬 레인을 사용하려면 --concurrency 1을 사용하세요.
  • pnpm openclaw qa suite --runner multipass
    • 동일한 QA 스위트를 일회용 Multipass Linux VM 내부에서 실행합니다.
    • 호스트의 qa suite와 동일한 시나리오 선택 동작을 유지합니다.
    • qa suite와 동일한 Provider/모델 선택 플래그를 재사용합니다.
    • live 실행은 게스트에서 실용적으로 전달 가능한 지원 QA 인증 입력을 포워딩합니다: env 기반 Provider 키, QA live Provider config 경로, 그리고 존재할 경우 CODEX_HOME.
    • 출력 디렉터리는 게스트가 마운트된 워크스페이스를 통해 결과를 다시 쓸 수 있도록 리포지토리 루트 아래에 있어야 합니다.
    • 일반 QA 보고서 + 요약과 함께 Multipass 로그를 .artifacts/qa-e2e/... 아래에 기록합니다.
  • pnpm qa:lab:up
    • 운영자 스타일 QA 작업을 위한 Docker 기반 QA 사이트를 시작합니다.
  • pnpm openclaw qa matrix
    • 일회용 Docker 기반 Tuwunel homeserver를 상대로 Matrix live QA 레인을 실행합니다.
    • 임시 Matrix 사용자 세 명(driver, sut, observer)과 하나의 비공개 room을 프로비저닝한 뒤, 실제 Matrix Plugin을 SUT transport로 사용하는 QA Gateway 자식을 시작합니다.
    • 기본적으로 고정된 stable Tuwunel 이미지 ghcr.io/matrix-construct/tuwunel:v1.5.1를 사용합니다. 다른 이미지를 테스트해야 할 때는 OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE로 재정의하세요.
    • Matrix는 현재 레인이 로컬에서 일회용 사용자를 프로비저닝하므로 --credential-source env만 지원합니다.
    • Matrix QA 보고서, 요약, observed-events artifact를 .artifacts/qa-e2e/... 아래에 기록합니다.
  • pnpm openclaw qa telegram
    • env의 driver 및 SUT bot 토큰을 사용해 실제 비공개 그룹을 상대로 Telegram live QA 레인을 실행합니다.
    • OPENCLAW_QA_TELEGRAM_GROUP_ID, OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN, OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN가 필요합니다. group id는 숫자형 Telegram chat id여야 합니다.
    • 공유된 풀 자격 증명을 위해 --credential-source convex를 지원합니다. 기본적으로는 env 모드를 사용하거나, 풀 임대를 사용하려면 OPENCLAW_QA_CREDENTIAL_SOURCE=convex를 설정하세요.
    • 동일한 비공개 그룹 안에 있는 서로 다른 두 bot이 필요하며, SUT bot은 Telegram username을 노출해야 합니다.
    • 안정적인 bot 간 관찰을 위해 @BotFather에서 두 bot 모두에 대해 Bot-to-Bot Communication Mode를 활성화하고, driver bot이 그룹 내 bot 트래픽을 관찰할 수 있도록 하세요.
    • Telegram QA 보고서, 요약, observed-messages artifact를 .artifacts/qa-e2e/... 아래에 기록합니다.
live transport 레인은 새 transport가 드리프트하지 않도록 하나의 표준 계약을 공유합니다. qa-channel은 여전히 광범위한 synthetic QA 스위트이며 live transport 커버리지 매트릭스의 일부는 아닙니다.
레인Canary멘션 게이팅Allowlist 차단최상위 답글재시작 복구스레드 후속 응답스레드 격리반응 관찰도움말 명령
Matrixxxxxxxxx
Telegramxx

Convex를 통한 공유 Telegram 자격 증명 (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)
  • 선택한 역할에 대한 secret 하나:
    • maintainer의 경우 OPENCLAW_QA_CONVEX_SECRET_MAINTAINER
    • ci의 경우 OPENCLAW_QA_CONVEX_SECRET_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:// Convex URL을 허용합니다.
일반적인 운영에서는 OPENCLAW_QA_CONVEX_SITE_URLhttps://를 사용해야 합니다. Maintainer 관리자 명령(풀 추가/제거/목록)은 구체적으로 OPENCLAW_QA_CONVEX_SECRET_MAINTAINER가 필요합니다. maintainer용 CLI helper:
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>
스크립트와 CI 유틸리티에서 기계가 읽을 수 있는 출력을 원하면 --json을 사용하세요. 기본 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 secret 전용)
    • 요청: { kind, actorId, payload, note?, status? }
    • 성공: { status: "ok", credential }
  • POST /admin/remove (maintainer secret 전용)
    • 요청: { credentialId, actorId }
    • 성공: { status: "ok", changed, credential }
    • 활성 임대 보호: { status: "error", code: "LEASE_ACTIVE", ... }
  • POST /admin/list (maintainer secret 전용)
    • 요청: { kind?, status?, includePayload?, limit? }
    • 성공: { status: "ok", credentials, count }
Telegram kind용 payload 형태:
  • { groupId: string, driverToken: string, sutToken: string }
  • groupId는 숫자형 Telegram chat id 문자열이어야 합니다.
  • admin/addkind: "telegram"에 대해 이 형태를 검증하고 잘못된 payload를 거부합니다.

QA에 채널 추가하기

markdown QA 시스템에 채널을 추가하려면 정확히 두 가지가 필요합니다.
  1. 해당 채널용 transport adapter
  2. 채널 계약을 검증하는 scenario pack
공유 qa-lab 러너가 흐름을 소유할 수 있는 경우 채널 전용 QA 러너를 추가하지 마세요. qa-lab은 공유 메커니즘을 소유합니다.
  • 스위트 시작 및 종료
  • 워커 동시성
  • artifact 기록
  • 보고서 생성
  • 시나리오 실행
  • 이전 qa-channel 시나리오를 위한 호환성 alias
채널 adapter는 transport 계약을 소유합니다.
  • 해당 transport에 대해 Gateway가 어떻게 구성되는지
  • readiness를 어떻게 확인하는지
  • inbound event를 어떻게 주입하는지
  • outbound 메시지를 어떻게 관찰하는지
  • transcript와 정규화된 transport 상태를 어떻게 노출하는지
  • transport 기반 작업을 어떻게 실행하는지
  • transport별 reset 또는 cleanup을 어떻게 처리하는지
새 채널에 대한 최소 도입 기준은 다음과 같습니다.
  1. 공유 qa-lab seam에 transport adapter를 구현합니다.
  2. transport registry에 adapter를 등록합니다.
  3. transport별 메커니즘은 adapter 또는 채널 harness 내부에 유지합니다.
  4. qa/scenarios/ 아래에 markdown 시나리오를 작성하거나 조정합니다.
  5. 새 시나리오에는 generic scenario helper를 사용합니다.
  6. 리포지토리가 의도적인 마이그레이션을 수행 중인 경우가 아니라면 기존 호환성 alias가 계속 동작하게 유지합니다.
판단 규칙은 엄격합니다.
  • 동작을 qa-lab에서 한 번만 표현할 수 있다면, qa-lab에 넣으세요.
  • 동작이 하나의 채널 transport에 의존한다면, 해당 adapter 또는 Plugin harness에 유지하세요.
  • 시나리오에 둘 이상의 채널이 사용할 수 있는 새 capability가 필요하다면, suite.ts에 채널별 분기를 추가하는 대신 generic helper를 추가하세요.
  • 동작이 오직 하나의 transport에만 의미가 있다면, 해당 시나리오를 transport 전용으로 유지하고 시나리오 계약에서 이를 명시하세요.
새 시나리오에 권장되는 generic helper 이름은 다음과 같습니다.
  • waitForTransportReady
  • waitForChannelReady
  • injectInboundMessage
  • injectOutboundMessage
  • waitForTransportOutboundMessage
  • waitForChannelOutboundMessage
  • waitForNoTransportOutbound
  • getTransportSnapshot
  • readTransportMessage
  • readTransportTranscript
  • formatTransportTranscript
  • resetTransport
기존 시나리오를 위해 다음을 포함한 호환성 alias도 계속 사용할 수 있습니다.
  • waitForQaChannelReady
  • waitForOutboundMessage
  • waitForNoOutbound
  • formatConversationTranscript
  • resetBus
새 채널 작업에서는 generic helper 이름을 사용해야 합니다. 호환성 alias는 하루아침에 마이그레이션을 강제하지 않기 위해 존재하는 것이지, 새 시나리오 작성의 모델이 아닙니다.

테스트 스위트(무엇이 어디서 실행되는가)

스위트를 “현실성이 점점 증가하는 단계”라고 생각하세요(그리고 불안정성/비용도 함께 증가합니다).

Unit / integration (기본값)

  • 명령: pnpm test
  • 구성: 기존 범위별 Vitest 프로젝트 전반에 걸친 10개의 순차 샤드 실행(vitest.full-*.config.ts)
  • 파일: src/**/*.test.ts, packages/**/*.test.ts, test/**/*.test.ts 아래의 core/unit 인벤토리와 vitest.unit.config.ts에서 다루는 허용된 ui node 테스트
  • 범위:
    • 순수 unit 테스트
    • 프로세스 내부 integration 테스트(Gateway 인증, 라우팅, tooling, 파싱, config)
    • 알려진 버그에 대한 결정적 회귀 테스트
  • 기대사항:
    • CI에서 실행됨
    • 실제 키 불필요
    • 빠르고 안정적이어야 함
  • 프로젝트 참고:
    • 이제 타깃을 지정하지 않은 pnpm test는 하나의 거대한 native 루트 프로젝트 프로세스 대신 11개의 더 작은 샤드 구성(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)을 실행합니다. 이렇게 하면 부하가 있는 머신에서 피크 RSS를 줄이고 auto-reply/extension 작업이 관련 없는 스위트를 잠식하는 것을 방지할 수 있습니다.
    • pnpm test --watch는 다중 샤드 watch 루프가 실용적이지 않기 때문에 여전히 native 루트 vitest.config.ts 프로젝트 그래프를 사용합니다.
    • pnpm test, pnpm test:watch, pnpm test:perf:imports는 명시적인 파일/디렉터리 타깃을 먼저 범위별 레인으로 라우팅하므로, pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts는 전체 루트 프로젝트 시작 비용을 치르지 않아도 됩니다.
    • pnpm test:changed는 변경 diff가 라우팅 가능한 소스/테스트 파일만 건드릴 경우 변경된 git 경로를 동일한 범위별 레인으로 확장합니다. config/setup 편집은 여전히 더 넓은 루트 프로젝트 재실행으로 폴백됩니다.
    • agents, commands, plugins, auto-reply helper, plugin-sdk 및 유사한 순수 유틸리티 영역의 import가 가벼운 unit 테스트는 test/setup-openclaw-runtime.ts를 건너뛰는 unit-fast 레인으로 라우팅됩니다. 상태가 있거나 runtime이 무거운 파일은 기존 레인에 남습니다.
    • 선택된 plugin-sdkcommands helper 소스 파일도 changed 모드 실행을 이러한 가벼운 레인의 명시적인 형제 테스트로 매핑하므로, helper 편집 시 해당 디렉터리의 전체 무거운 스위트를 다시 실행하지 않아도 됩니다.
    • auto-reply는 이제 세 개의 전용 버킷을 가집니다: 최상위 core helper, 최상위 reply.* integration 테스트, 그리고 src/auto-reply/reply/** 하위 트리. 이렇게 하면 가장 무거운 reply harness 작업이 가벼운 status/chunk/token 테스트에 영향을 주지 않습니다.
  • 내장 러너 참고:
    • 메시지 tool discovery 입력 또는 Compaction runtime context를 변경할 때는 두 수준의 커버리지를 모두 유지하세요.
    • 순수 라우팅/정규화 경계에 대해 집중된 helper 회귀 테스트를 추가하세요.
    • 또한 내장 러너 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.
    • 이 스위트들은 범위가 지정된 id와 Compaction 동작이 실제 run.ts / compact.ts 경로를 통해 계속 흐르는지 검증합니다. helper 전용 테스트만으로는 이러한 integration 경로를 충분히 대체할 수 없습니다.
  • 풀 참고:
    • 기본 Vitest 구성은 이제 기본값으로 threads를 사용합니다.
    • 공유 Vitest 구성은 또한 isolate: false를 고정하고 루트 프로젝트, e2e, live 구성 전반에서 비격리 러너를 사용합니다.
    • 루트 UI 레인은 jsdom setup 및 optimizer를 유지하지만, 이제 공유 비격리 러너에서도 실행됩니다.
    • pnpm test 샤드는 공유 Vitest 구성에서 동일한 threads + isolate: false 기본값을 상속받습니다.
    • 공유 scripts/run-vitest.mjs 런처는 큰 로컬 실행 중 V8 컴파일 churn을 줄이기 위해 기본적으로 Vitest 자식 Node 프로세스에 --no-maglev도 추가합니다. 기본 V8 동작과 비교해야 한다면 OPENCLAW_VITEST_ENABLE_MAGLEV=1을 설정하세요.
  • 빠른 로컬 반복 참고:
    • pnpm test:changed는 변경 경로가 더 작은 스위트에 깔끔하게 매핑될 때 범위별 레인을 통해 라우팅됩니다.
    • pnpm test:maxpnpm test:changed:max는 같은 라우팅 동작을 유지하되, 더 높은 워커 상한을 사용합니다.
    • 로컬 워커 자동 스케일링은 이제 의도적으로 더 보수적이며, 호스트 load average가 이미 높을 때도 물러나므로 여러 개의 동시 Vitest 실행이 기본적으로 덜 큰 피해를 주게 됩니다.
    • 기본 Vitest 구성은 프로젝트/config 파일을 forceRerunTriggers로 표시하여 테스트 wiring이 변경될 때 changed 모드 재실행이 정확하게 유지되도록 합니다.
    • 구성은 지원되는 호스트에서 OPENCLAW_VITEST_FS_MODULE_CACHE를 계속 활성화합니다. 직접 프로파일링을 위한 명시적 캐시 위치 하나를 원하면 OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path를 설정하세요.
  • 성능 디버그 참고:
    • pnpm test:perf:imports는 Vitest import-duration 보고와 import-breakdown 출력을 활성화합니다.
    • pnpm test:perf:imports:changed는 동일한 프로파일링 보기를 origin/main 이후 변경된 파일로 범위를 좁힙니다.
  • pnpm test:perf:changed:bench -- --ref <git-ref>는 해당 커밋 diff에 대해 라우팅된 test:changed와 native 루트 프로젝트 경로를 비교하고 wall time과 macOS max RSS를 출력합니다.
  • pnpm test:perf:changed:bench -- --worktree는 변경된 파일 목록을 scripts/test-projects.mjs와 루트 Vitest 구성으로 라우팅해 현재 dirty tree를 벤치마크합니다.
    • pnpm test:perf:profile:main은 Vitest/Vite 시작 및 transform 오버헤드에 대한 메인 스레드 CPU 프로파일을 기록합니다.
    • pnpm test:perf:profile:runner는 파일 병렬화를 비활성화한 unit 스위트에 대해 러너 CPU+heap 프로파일을 기록합니다.

E2E (Gateway 스모크)

  • 명령: pnpm test:e2e
  • 구성: vitest.e2e.config.ts
  • 파일: src/**/*.e2e.test.ts, test/**/*.e2e.test.ts
  • runtime 기본값:
    • 리포지토리의 나머지와 동일하게 Vitest threadsisolate: false를 사용합니다.
    • 적응형 워커를 사용합니다(CI: 최대 2, 로컬: 기본값 1).
    • 콘솔 I/O 오버헤드를 줄이기 위해 기본적으로 silent 모드로 실행됩니다.
  • 유용한 재정의:
    • 워커 수를 강제하려면 OPENCLAW_E2E_WORKERS=<n>(상한 16)
    • 자세한 콘솔 출력을 다시 활성화하려면 OPENCLAW_E2E_VERBOSE=1
  • 범위:
    • 다중 인스턴스 Gateway 엔드투엔드 동작
    • WebSocket/HTTP 표면, Node 페어링, 더 무거운 네트워킹
  • 기대사항:
    • CI에서 실행됨(파이프라인에서 활성화된 경우)
    • 실제 키 불필요
    • unit 테스트보다 더 많은 가변 요소가 있음(더 느릴 수 있음)

E2E: OpenShell 백엔드 스모크

  • 명령: pnpm test:e2e:openshell
  • 파일: test/openshell-sandbox.e2e.test.ts
  • 범위:
    • Docker를 통해 호스트에서 격리된 OpenShell Gateway를 시작합니다.
    • 임시 로컬 Dockerfile에서 sandbox를 생성합니다.
    • 실제 sandbox ssh-config + SSH exec를 통해 OpenClaw의 OpenShell 백엔드를 실행합니다.
    • sandbox fs bridge를 통해 원격 canonical filesystem 동작을 검증합니다.
  • 기대사항:
    • 옵트인 전용이며 기본 pnpm test:e2e 실행의 일부가 아닙니다.
    • 로컬 openshell CLI와 정상 동작하는 Docker 데몬이 필요합니다.
    • 격리된 HOME / XDG_CONFIG_HOME을 사용한 뒤 테스트 Gateway와 sandbox를 제거합니다.
  • 유용한 재정의:
    • 더 넓은 e2e 스위트를 수동으로 실행할 때 테스트를 활성화하려면 OPENCLAW_E2E_OPENSHELL=1
    • 기본이 아닌 CLI 바이너리 또는 wrapper 스크립트를 지정하려면 OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell

Live (실제 Provider + 실제 모델)

  • 명령: pnpm test:live
  • 구성: vitest.live.config.ts
  • 파일: src/**/*.live.test.ts
  • 기본값: pnpm test:live에 의해 활성화됨(OPENCLAW_LIVE_TEST=1 설정)
  • 범위:
    • “이 Provider/모델이 오늘 실제 자격 증명으로 정말 동작하는가?”
    • Provider 포맷 변경, tool-calling 특이사항, 인증 문제, rate limit 동작 포착
  • 기대사항:
    • 설계상 CI에서 안정적이지 않음(실제 네트워크, 실제 Provider 정책, quota, 장애)
    • 비용이 들고 / rate limit을 사용함
    • “전부”보다는 범위를 좁힌 하위 집합 실행을 선호
  • live 실행은 누락된 API 키를 가져오기 위해 ~/.profile을 소스합니다.
  • 기본적으로 live 실행은 여전히 HOME을 격리하고 config/auth 자료를 임시 테스트 홈에 복사하므로 unit fixture가 실제 ~/.openclaw를 변경할 수 없습니다.
  • live 테스트가 실제 홈 디렉터리를 사용하도록 의도적으로 해야 할 때만 OPENCLAW_LIVE_USE_REAL_HOME=1을 설정하세요.
  • 이제 pnpm test:live는 기본적으로 더 조용한 모드입니다. [live] ... 진행 출력은 유지하지만, 추가 ~/.profile 알림을 숨기고 Gateway bootstrap 로그/Bonjour chatter를 음소거합니다. 전체 시작 로그가 다시 필요하면 OPENCLAW_LIVE_TEST_QUIET=0을 설정하세요.
  • API 키 로테이션(Provider별): 쉼표/세미콜론 형식의 *_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 콘솔 캡처가 조용한 경우에도 긴 Provider 호출이 눈에 보이게 활성 상태로 표시됩니다.
    • vitest.live.config.ts는 Vitest 콘솔 가로채기를 비활성화하여 Provider/Gateway 진행 줄이 live 실행 중 즉시 스트리밍되도록 합니다.
    • 직접 모델 Heartbeat는 OPENCLAW_LIVE_HEARTBEAT_MS로 조정합니다.
    • Gateway/프로브 Heartbeat는 OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS로 조정합니다.

어떤 스위트를 실행해야 하나요?

다음 결정 표를 사용하세요.
  • 로직/테스트를 수정 중: pnpm test 실행(많이 변경했다면 pnpm test:coverage도)
  • Gateway 네트워킹 / WS 프로토콜 / 페어링을 건드림: pnpm test:e2e 추가
  • “내 봇이 다운되었어요” / Provider별 실패 / tool calling 디버깅: 범위를 좁힌 pnpm test:live 실행

Live: Android Node capability 스윕

  • 테스트: src/gateway/android-node.capabilities.live.test.ts
  • 스크립트: pnpm android:test:integration
  • 목표: 연결된 Android Node가 현재 광고하는 모든 명령을 호출하고 명령 계약 동작을 검증합니다.
  • 범위:
    • 사전 조건이 갖춰진 수동 setup(이 스위트는 앱을 설치/실행/페어링하지 않음)
    • 선택된 Android Node에 대한 명령별 Gateway node.invoke 검증
  • 필요한 사전 setup:
    • Android 앱이 이미 Gateway에 연결되고 페어링되어 있어야 함
    • 앱이 포그라운드에 유지되어야 함
    • 통과를 기대하는 capability에 대해 권한/캡처 동의가 부여되어야 함
  • 선택적 타깃 재정의:
    • OPENCLAW_ANDROID_NODE_ID 또는 OPENCLAW_ANDROID_NODE_NAME
    • OPENCLAW_ANDROID_GATEWAY_URL / OPENCLAW_ANDROID_GATEWAY_TOKEN / OPENCLAW_ANDROID_GATEWAY_PASSWORD
  • 전체 Android setup 세부사항: Android 앱

Live: 모델 스모크(프로필 키)

live 테스트는 실패를 분리할 수 있도록 두 계층으로 나뉩니다.
  • “직접 모델”은 해당 Provider/모델이 주어진 키로 최소한 응답할 수 있는지를 알려줍니다.
  • “Gateway 스모크”는 해당 모델에 대해 전체 Gateway+에이전트 파이프라인(세션, 히스토리, tools, sandbox 정책 등)이 동작하는지를 알려줍니다.

계층 1: 직접 모델 completion(Gateway 없음)

  • 테스트: src/agents/models.profiles.live.test.ts
  • 목표:
    • 발견된 모델을 나열
    • getApiKeyForModel을 사용해 자격 증명이 있는 모델 선택
    • 모델별로 작은 completion 실행(그리고 필요한 경우 타깃 회귀 테스트)
  • 활성화 방법:
    • pnpm test:live(또는 Vitest를 직접 호출하는 경우 OPENCLAW_LIVE_TEST=1)
  • 이 스위트를 실제로 실행하려면 OPENCLAW_LIVE_MODELS=modern(또는 all, modern의 alias)을 설정하세요. 그렇지 않으면 pnpm test:live가 Gateway 스모크에 집중되도록 이 스위트는 건너뜁니다.
  • 모델 선택 방법:
    • 최신 allowlist를 실행하려면 OPENCLAW_LIVE_MODELS=modern(Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4)
    • OPENCLAW_LIVE_MODELS=all은 최신 allowlist의 alias
    • 또는 OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."(쉼표로 구분한 allowlist)
    • modern/all 스윕은 기본적으로 큐레이션된 높은 신호 상한을 사용합니다. exhaustive modern 스윕을 원하면 OPENCLAW_LIVE_MAX_MODELS=0을, 더 작은 상한을 원하면 양수를 설정하세요.
  • Provider 선택 방법:
    • OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"(쉼표로 구분한 allowlist)
  • 키 출처:
    • 기본값: 프로필 저장소와 env 폴백
    • 프로필 저장소만 강제하려면 OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1 설정
  • 이 계층이 존재하는 이유:
    • “Provider API가 깨졌음 / 키가 유효하지 않음”과 “Gateway 에이전트 파이프라인이 깨졌음”을 분리합니다.
    • 작고 격리된 회귀 테스트를 담습니다(예: OpenAI Responses/Codex Responses reasoning replay + tool-call 흐름)

계층 2: Gateway + dev agent 스모크(@openclaw가 실제로 하는 일)

  • 테스트: src/gateway/gateway-models.profiles.live.test.ts
  • 목표:
    • 프로세스 내부 Gateway를 띄웁니다.
    • agent:dev:* 세션을 생성/패치합니다(실행별 모델 재정의).
    • 키가 있는 모델들을 순회하며 다음을 검증합니다:
      • “의미 있는” 응답(tools 없음)
      • 실제 tool 호출이 동작함(read 프로브)
      • 선택적 추가 tool 프로브(exec+read 프로브)
      • OpenAI 회귀 경로(tool-call-only → 후속 응답)가 계속 동작함
  • 프로브 세부사항(실패를 빠르게 설명할 수 있도록):
    • read 프로브: 테스트가 워크스페이스에 nonce 파일을 쓰고, 에이전트에게 이를 read한 뒤 nonce를 다시 echo하도록 요청합니다.
    • exec+read 프로브: 테스트가 에이전트에게 exec로 임시 파일에 nonce를 쓰게 한 다음, 이를 다시 read하도록 요청합니다.
    • image 프로브: 테스트가 생성된 PNG(고양이 + 무작위 코드)를 첨부하고, 모델이 cat <CODE>를 반환할 것으로 기대합니다.
    • 구현 참조: src/gateway/gateway-models.profiles.live.test.tssrc/gateway/live-image-probe.ts.
  • 활성화 방법:
    • pnpm test:live(또는 Vitest를 직접 호출하는 경우 OPENCLAW_LIVE_TEST=1)
  • 모델 선택 방법:
    • 기본값: 최신 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의 alias입니다.
    • 또는 범위를 좁히기 위해 OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"(또는 쉼표 목록)을 설정하세요.
    • modern/all Gateway 스윕은 기본적으로 큐레이션된 높은 신호 상한을 사용합니다. exhaustive modern 스윕을 원하면 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0을, 더 작은 상한을 원하면 양수를 설정하세요.
  • Provider 선택 방법(“OpenRouter 전부” 피하기):
    • OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"(쉼표 allowlist)
  • 이 live 테스트에서는 tool + image 프로브가 항상 활성화됩니다:
    • read 프로브 + exec+read 프로브(tool 스트레스)
    • 모델이 image 입력 지원을 광고하는 경우 image 프로브 실행
    • 흐름(상위 수준):
      • 테스트가 “CAT” + 무작위 코드가 들어간 작은 PNG를 생성합니다(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)
      • 내장 에이전트가 multimodal 사용자 메시지를 모델로 전달합니다
      • 검증: 응답에 cat + 코드가 포함됨(OCR 허용 오차: 사소한 실수 허용)
팁: 현재 머신에서 무엇을 테스트할 수 있는지(그리고 정확한 provider/model id)를 보려면 다음을 실행하세요.
openclaw models list
openclaw models list --json

Live: CLI 백엔드 스모크(Claude, Codex, Gemini 또는 기타 로컬 CLI)

  • 테스트: src/gateway/gateway-cli-backend.live.test.ts
  • 목표: 기본 config를 건드리지 않고 로컬 CLI 백엔드를 사용해 Gateway + 에이전트 파이프라인을 검증합니다.
  • 백엔드별 스모크 기본값은 해당 extension의 cli-backend.ts 정의에 있습니다.
  • 활성화:
    • pnpm test:live(또는 Vitest를 직접 호출하는 경우 OPENCLAW_LIVE_TEST=1)
    • OPENCLAW_LIVE_CLI_BACKEND=1
  • 기본값:
    • 기본 Provider/모델: claude-cli/claude-sonnet-4-6
    • 명령/args/image 동작은 해당 CLI 백엔드 Plugin 메타데이터에서 가져옵니다.
  • 재정의(선택 사항):
    • 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"]'
    • 실제 image 첨부를 전송하려면 OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1(경로는 프롬프트에 주입됨)
    • 프롬프트 주입 대신 image 파일 경로를 CLI 인자로 전달하려면 OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"
    • IMAGE_ARG가 설정된 경우 image 인자 전달 방식을 제어하려면 OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"(또는 "list")
    • 두 번째 턴을 보내고 resume 흐름을 검증하려면 OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1
    • 기본 Claude Sonnet -> Opus 동일 세션 연속성 프로브를 비활성화하려면 OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0(선택한 모델이 전환 타깃을 지원할 때 강제로 켜려면 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
단일 Provider 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에 있습니다.
  • 리포지토리 Docker 이미지 안에서 비루트 node 사용자로 live CLI 백엔드 스모크를 실행합니다.
  • 해당 extension에서 CLI 스모크 메타데이터를 확인한 뒤, 캐시 가능한 쓰기 가능한 prefix OPENCLAW_DOCKER_CLI_TOOLS_DIR(기본값: ~/.cache/openclaw/docker-cli-tools)에 일치하는 Linux CLI 패키지(@anthropic-ai/claude-code, @openai/codex, @google/gemini-cli)를 설치합니다.
  • pnpm test:docker:live-cli-backend:claude-subscription~/.claude/.credentials.jsonclaudeAiOauth.subscriptionType 또는 claude setup-tokenCLAUDE_CODE_OAUTH_TOKEN을 통한 portable Claude Code subscription OAuth가 필요합니다. 먼저 Docker에서 직접 claude -p를 증명한 다음, Anthropic API 키 env var를 보존하지 않고 두 번의 Gateway CLI 백엔드 턴을 실행합니다. 이 subscription 레인은 현재 Claude가 일반 subscription 플랜 제한 대신 추가 사용량 과금을 통해 서드파티 앱 사용을 라우팅하므로 기본적으로 Claude MCP/tool 및 image 프로브를 비활성화합니다.
  • live CLI 백엔드 스모크는 이제 Claude, Codex, Gemini에 대해 동일한 엔드투엔드 흐름을 실행합니다: 텍스트 턴, image 분류 턴, 그다음 Gateway CLI를 통해 검증되는 MCP cron tool 호출.
  • Claude의 기본 스모크는 또한 세션을 Sonnet에서 Opus로 패치하고, 재개된 세션이 이전 메모를 여전히 기억하는지도 검증합니다.

Live: ACP 바인드 스모크(/acp spawn ... --bind here)

  • 테스트: src/gateway/gateway-acp-bind.live.test.ts
  • 목표: live ACP 에이전트로 실제 ACP 대화 바인드 흐름을 검증합니다:
    • /acp spawn <agent> --bind here 전송
    • synthetic message-channel 대화를 그 자리에서 바인드
    • 같은 대화에서 일반 후속 메시지 전송
    • 후속 메시지가 바인드된 ACP 세션 transcript에 기록되는지 검증
  • 활성화:
    • pnpm test:live src/gateway/gateway-acp-bind.live.test.ts
    • OPENCLAW_LIVE_ACP_BIND=1
  • 기본값:
    • Docker 내 ACP 에이전트: claude,codex,gemini
    • 직접 pnpm test:live ...용 ACP 에이전트: claude
    • synthetic 채널: Slack DM 스타일 대화 컨텍스트
    • 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>'
  • 참고:
    • 이 레인은 admin 전용 synthetic originating-route 필드가 있는 Gateway chat.send 표면을 사용하므로, 테스트가 외부 전달을 가장하지 않고도 message-channel 컨텍스트를 붙일 수 있습니다.
    • OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND가 설정되지 않으면, 테스트는 선택한 ACP harness 에이전트에 대해 내장 acpx Plugin의 기본 agent registry를 사용합니다.
예시:
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에 있습니다.
  • 기본적으로 지원되는 모든 live CLI 에이전트(claude, codex, gemini)에 대해 ACP 바인드 스모크를 순서대로 실행합니다.
  • 매트릭스 범위를 좁히려면 OPENCLAW_LIVE_ACP_BIND_AGENTS=claude, OPENCLAW_LIVE_ACP_BIND_AGENTS=codex, 또는 OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini를 사용하세요.
  • ~/.profile을 소스하고, 일치하는 CLI 인증 자료를 컨테이너에 스테이징하며, 쓰기 가능한 npm prefix에 acpx를 설치한 다음, 요청된 live CLI(@anthropic-ai/claude-code, @openai/codex, @google/gemini-cli)가 없으면 설치합니다.
  • Docker 내부에서는 러너가 OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx를 설정하여, 소스된 profile의 Provider env var가 자식 harness CLI에서도 계속 사용 가능하도록 합니다.

Live: Codex app-server harness 스모크

  • 목표: 일반 Gateway agent 메서드를 통해 Plugin 소유 Codex harness를 검증합니다:
    • 번들된 codex Plugin 로드
    • OPENCLAW_AGENT_RUNTIME=codex 선택
    • 첫 번째 Gateway agent 턴을 codex/gpt-5.4로 전송
    • 동일한 OpenClaw 세션에 두 번째 턴을 전송하고 app-server thread가 재개될 수 있는지 검증
    • 동일한 Gateway 명령 경로를 통해 /codex status/codex models 실행
  • 테스트: src/gateway/gateway-codex-harness.live.test.ts
  • 활성화: OPENCLAW_LIVE_CODEX_HARNESS=1
  • 기본 모델: codex/gpt-5.4
  • 선택적 image 프로브: OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1
  • 선택적 MCP/tool 프로브: OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1
  • 이 스모크는 OPENCLAW_AGENT_HARNESS_FALLBACK=none을 설정하므로, 깨진 Codex harness가 PI로 조용히 폴백해서 통과할 수 없습니다.
  • 인증: 셸/profile의 OPENAI_API_KEY와 선택적으로 복사된 ~/.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를 전달하며, Codex CLI 인증 파일이 있으면 복사하고, 쓰기 가능한 마운트된 npm prefix에 @openai/codex를 설치한 뒤, 소스 트리를 스테이징하고, Codex-harness live 테스트만 실행합니다.
  • Docker는 기본적으로 image 및 MCP/tool 프로브를 활성화합니다. 더 좁은 디버그 실행이 필요하면 OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 또는 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0을 설정하세요.
  • Docker는 또한 OPENCLAW_AGENT_HARNESS_FALLBACK=none을 export하여 live 테스트 구성과 일치시킵니다. 따라서 openai-codex/* 또는 PI 폴백이 Codex harness 회귀를 숨길 수 없습니다.

권장 live 레시피

범위가 좁고 명시적인 allowlist가 가장 빠르고 가장 덜 불안정합니다.
  • 단일 모델, 직접 실행(Gateway 없음):
    • OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts
  • 단일 모델, Gateway 스모크:
    • OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
  • 여러 Provider에 걸친 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 키 + Antigravity):
    • Gemini(API 키): OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
    • Antigravity(OAuth): OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts
참고:
  • google/...는 Gemini API(API 키)를 사용합니다.
  • google-antigravity/...는 Antigravity OAuth 브리지(Cloud Code Assist 스타일 agent endpoint)를 사용합니다.
  • google-gemini-cli/...는 로컬 머신의 Gemini CLI를 사용합니다(별도 인증 + tooling 특이사항).
  • Gemini API와 Gemini CLI의 차이:
    • API: OpenClaw가 Google의 호스팅된 Gemini API를 HTTP로 호출합니다(API 키 / 프로필 인증). 대부분의 사용자가 “Gemini”라고 말할 때 의미하는 것이 이것입니다.
    • CLI: OpenClaw가 로컬 gemini 바이너리를 셸 실행합니다. 자체 인증이 있으며 동작이 다를 수 있습니다(스트리밍/tool 지원/버전 불일치).

Live: 모델 매트릭스(무엇을 커버하는가)

고정된 “CI 모델 목록”은 없습니다(live는 옵트인). 하지만 개발 머신에서 키를 가지고 정기적으로 커버하기를 권장하는 모델은 다음과 같습니다.

최신 스모크 세트(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-previewgoogle/gemini-3-flash-preview (구형 Gemini 2.x 모델은 피하세요)
  • Google (Antigravity): google-antigravity/claude-opus-4-6-thinkinggoogle-antigravity/gemini-3-flash
  • Z.AI (GLM): zai/glm-4.7
  • MiniMax: minimax/MiniMax-M2.7
tools + image와 함께 Gateway 스모크 실행: 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)

Provider 계열마다 최소 하나는 선택하세요.
  • 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 모드에 따라 달라짐)

비전: image 전송(attachment → multimodal 메시지)

image 프로브를 실행하려면 OPENCLAW_LIVE_GATEWAY_MODELS에 image 지원 모델(Claude/Gemini/OpenAI 비전 지원 변형 등) 최소 하나를 포함하세요.

Aggregator / 대체 Gateway

키가 활성화되어 있다면 다음을 통한 테스트도 지원합니다.
  • OpenRouter: openrouter/... (수백 개 모델; tool+image 지원 후보를 찾으려면 openclaw models scan 사용)
  • OpenCode: Zen용 opencode/..., Go용 opencode-go/... (OPENCODE_API_KEY / OPENCODE_ZEN_API_KEY로 인증)
live 매트릭스에 포함할 수 있는 더 많은 Provider(자격 증명/config가 있는 경우):
  • 내장: openai, openai-codex, anthropic, google, google-vertex, google-antigravity, google-gemini-cli, zai, openrouter, opencode, opencode-go, xai, groq, cerebras, mistral, github-copilot
  • models.providers를 통해(custom endpoint): minimax(cloud/API), 그리고 모든 OpenAI/Anthropic 호환 프록시(LM Studio, vLLM, LiteLLM 등)
팁: 문서에 “모든 모델”을 하드코딩하려고 하지 마세요. 권위 있는 목록은 현재 머신에서 discoverModels(...)가 반환하는 것과 사용 가능한 키 조합입니다.

자격 증명(절대 커밋 금지)

live 테스트는 CLI와 같은 방식으로 자격 증명을 찾습니다. 실질적인 의미는 다음과 같습니다.
  • CLI가 동작하면, live 테스트도 같은 키를 찾아야 합니다.
  • live 테스트가 “자격 증명 없음”이라고 하면, openclaw models list / 모델 선택을 디버깅하듯이 똑같이 디버깅하세요.
  • 에이전트별 인증 프로필: ~/.openclaw/agents/<agentId>/agent/auth-profiles.json(live 테스트에서 “프로필 키”라고 하는 것이 이것입니다)
  • config: ~/.openclaw/openclaw.json(또는 OPENCLAW_CONFIG_PATH)
  • 레거시 상태 디렉터리: ~/.openclaw/credentials/(존재할 경우 staging된 live 홈으로 복사되지만, 메인 프로필 키 저장소는 아님)
  • 로컬 live 실행은 기본적으로 활성 config, 에이전트별 auth-profiles.json 파일, 레거시 credentials/, 지원되는 외부 CLI 인증 디렉터리를 임시 테스트 홈으로 복사합니다. staging된 live 홈은 workspace/sandboxes/를 건너뛰며, agents.*.workspace / agentDir 경로 재정의도 제거되어 프로브가 실제 호스트 워크스페이스를 건드리지 않도록 합니다.
env 키(예: ~/.profile에서 export됨)에 의존하려면, 로컬 테스트를 source ~/.profile 후에 실행하거나, 아래 Docker 러너를 사용하세요(이들은 ~/.profile을 컨테이너에 마운트할 수 있습니다).

Deepgram live(오디오 전사)

  • 테스트: 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

BytePlus coding plan live

  • 테스트: 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

ComfyUI workflow media live

  • 테스트: extensions/comfy/comfy.live.test.ts
  • 활성화: OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts
  • 범위:
    • 번들된 comfy image, video, music_generate 경로를 실행합니다.
    • models.providers.comfy.<capability>가 구성되지 않은 capability는 각각 건너뜁니다.
    • comfy workflow 제출, 폴링, 다운로드 또는 Plugin 등록을 변경한 뒤 유용합니다.

이미지 생성 live

  • 테스트: src/image-generation/runtime.live.test.ts
  • 명령: pnpm test:live src/image-generation/runtime.live.test.ts
  • 하니스: pnpm test:live:media image
  • 범위:
    • 등록된 모든 이미지 생성 Provider Plugin을 열거합니다.
    • 프로브 전에 로그인 셸(~/.profile)에서 누락된 Provider env var를 불러옵니다.
    • 기본적으로 저장된 인증 프로필보다 live/env API 키를 우선 사용하므로, auth-profiles.json의 오래된 테스트 키가 실제 셸 자격 증명을 가리지 않습니다.
    • 사용 가능한 인증/프로필/모델이 없는 Provider는 건너뜁니다.
    • 공유 runtime capability를 통해 기본 이미지 생성 변형을 실행합니다:
      • google:flash-generate
      • google:pro-generate
      • google:pro-edit
      • openai:default-generate
  • 현재 커버되는 번들 Provider:
    • 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"
  • 선택적 인증 동작:
    • 프로필 저장소 인증을 강제하고 env 전용 재정의를 무시하려면 OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1

음악 생성 live

  • 테스트: extensions/music-generation-providers.live.test.ts
  • 활성화: OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts
  • 하니스: pnpm test:live:media music
  • 범위:
    • 공유 번들 음악 생성 Provider 경로를 실행합니다.
    • 현재 Google과 MiniMax를 커버합니다.
    • 프로브 전에 로그인 셸(~/.profile)에서 Provider env var를 불러옵니다.
    • 기본적으로 저장된 인증 프로필보다 live/env API 키를 우선 사용하므로, auth-profiles.json의 오래된 테스트 키가 실제 셸 자격 증명을 가리지 않습니다.
    • 사용 가능한 인증/프로필/모델이 없는 Provider는 건너뜁니다.
    • 가능한 경우 선언된 두 runtime 모드를 모두 실행합니다:
      • 프롬프트 전용 입력을 사용하는 generate
      • Provider가 capabilities.edit.enabled를 선언하면 edit
    • 현재 공유 레인 커버리지:
      • google: generate, edit
      • minimax: generate
      • comfy: 별도 Comfy live 파일에서 다루며, 이 공유 스윕에서는 다루지 않음
  • 선택적 범위 축소:
    • OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"
    • OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"
  • 선택적 인증 동작:
    • 프로필 저장소 인증을 강제하고 env 전용 재정의를 무시하려면 OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1

비디오 생성 live

  • 테스트: extensions/video-generation-providers.live.test.ts
  • 활성화: OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts
  • 하니스: pnpm test:live:media video
  • 범위:
    • 공유 번들 비디오 생성 Provider 경로를 실행합니다.
    • 프로브 전에 로그인 셸(~/.profile)에서 Provider env var를 불러옵니다.
    • 기본적으로 저장된 인증 프로필보다 live/env API 키를 우선 사용하므로, auth-profiles.json의 오래된 테스트 키가 실제 셸 자격 증명을 가리지 않습니다.
    • 사용 가능한 인증/프로필/모델이 없는 Provider는 건너뜁니다.
    • 가능한 경우 선언된 두 runtime 모드를 모두 실행합니다:
      • 프롬프트 전용 입력을 사용하는 generate
      • Provider가 capabilities.imageToVideo.enabled를 선언하고 선택된 Provider/모델이 공유 스윕에서 buffer 기반 로컬 image 입력을 허용하면 imageToVideo
      • Provider가 capabilities.videoToVideo.enabled를 선언하고 선택된 Provider/모델이 공유 스윕에서 buffer 기반 로컬 video 입력을 허용하면 videoToVideo
    • 공유 스윕에서 현재 선언되었지만 건너뛰는 imageToVideo Provider:
      • vydra: 번들 veo3는 텍스트 전용이고 번들 kling은 원격 image URL이 필요하기 때문
    • Provider별 Vydra 커버리지:
      • OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts
      • 이 파일은 기본적으로 원격 image URL fixture를 사용하는 kling 레인과 함께 veo3 text-to-video를 실행합니다.
    • 현재 videoToVideo live 커버리지:
      • 선택된 모델이 runway/gen4_aleph일 때만 runway
    • 공유 스윕에서 현재 선언되었지만 건너뛰는 videoToVideo Provider:
      • alibaba, qwen, xai: 이 경로들은 현재 원격 http(s) / MP4 참조 URL이 필요하기 때문
      • google: 현재 공유 Gemini/Veo 레인은 로컬 buffer 기반 입력을 사용하고, 이 경로는 공유 스윕에서 허용되지 않기 때문
      • openai: 현재 공유 레인에는 org별 비디오 인페인트/리믹스 접근 보장이 없기 때문
  • 선택적 범위 축소:
    • 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"
  • 선택적 인증 동작:
    • 프로필 저장소 인증을 강제하고 env 전용 재정의를 무시하려면 OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1

미디어 live 하니스

  • 명령: pnpm test:live:media
  • 목적:
    • 공유 image, music, video live 스위트를 하나의 리포지토리 기본 진입점으로 실행합니다.
    • ~/.profile에서 누락된 Provider env var를 자동으로 불러옵니다.
    • 기본적으로 현재 사용 가능한 인증이 있는 Provider로 각 스위트를 자동 축소합니다.
    • scripts/test-live.mjs를 재사용하므로 Heartbeat와 quiet 모드 동작이 일관되게 유지됩니다.
  • 예시:
    • 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-modelstest:docker:live-gateway는 리포지토리 Docker 이미지 안에서 해당 프로필 키 live 파일만 실행합니다(src/agents/models.profiles.live.test.tssrc/gateway/gateway-models.profiles.live.test.ts). 이때 로컬 config 디렉터리와 워크스페이스를 마운트하고(마운트된 경우 ~/.profile도 소스함), 대응하는 로컬 진입점은 test:live:models-profilestest:live:gateway-profiles입니다.
  • Docker live 러너는 전체 Docker 스윕이 실용적이도록 기본적으로 더 작은 스모크 상한을 사용합니다: test:docker:live-models는 기본적으로 OPENCLAW_LIVE_MAX_MODELS=12를 사용하고, test:docker:live-gateway는 기본적으로 OPENCLAW_LIVE_GATEWAY_SMOKE=1, OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8, OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000, 그리고 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000를 사용합니다. 더 큰 exhaustive 스캔이 필요할 때는 이 env var들을 명시적으로 재정의하세요.
  • test:docker:all은 먼저 test:docker:live-build를 통해 live Docker 이미지를 한 번 빌드한 다음, 두 개의 live Docker 레인에서 이를 재사용합니다.
  • 컨테이너 스모크 러너: test:docker:openwebui, test:docker:onboard, test:docker:gateway-network, test:docker:mcp-channels, test:docker:plugins는 하나 이상의 실제 컨테이너를 부팅하고 더 높은 수준의 integration 경로를 검증합니다.
live 모델 Docker 러너는 또한 필요한 CLI 인증 홈만 바인드 마운트하고(실행 범위가 좁혀지지 않은 경우에는 지원되는 모든 항목), 실행 전에 이를 컨테이너 홈으로 복사하므로 외부 CLI OAuth가 호스트 인증 저장소를 변경하지 않고도 토큰을 갱신할 수 있습니다.
  • 직접 모델: pnpm test:docker:live-models (스크립트: scripts/test-live-models-docker.sh)
  • ACP 바인드 스모크: pnpm test:docker:live-acp-bind (스크립트: scripts/test-live-acp-bind-docker.sh)
  • CLI 백엔드 스모크: pnpm test:docker:live-cli-backend (스크립트: scripts/test-live-cli-backend-docker.sh)
  • Codex app-server harness 스모크: pnpm test:docker:live-codex-harness (스크립트: scripts/test-live-codex-harness-docker.sh)
  • Gateway + dev 에이전트: pnpm test:docker:live-gateway (스크립트: scripts/test-live-gateway-models-docker.sh)
  • Open WebUI live 스모크: pnpm test:docker:openwebui (스크립트: scripts/e2e/openwebui-docker.sh)
  • 온보딩 wizard(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 채널 브리지(seed된 Gateway + stdio 브리지 + 원시 Claude notification-frame 스모크): pnpm test:docker:mcp-channels (스크립트: scripts/e2e/mcp-channels-docker.sh)
  • Plugins(설치 스모크 + /plugin alias + Claude 번들 재시작 semantics): pnpm test:docker:plugins (스크립트: scripts/e2e/plugins-docker.sh)
live 모델 Docker 러너는 또한 현재 체크아웃을 읽기 전용으로 바인드 마운트하고 컨테이너 내부의 임시 workdir에 스테이징합니다. 이렇게 하면 runtime 이미지를 슬림하게 유지하면서도 정확히 현재 로컬 소스/config에 대해 Vitest를 실행할 수 있습니다. 스테이징 단계는 .pnpm-store, .worktrees, __openclaw_vitest__, app 로컬 .build, Gradle 출력 디렉터리 같은 큰 로컬 전용 캐시와 앱 빌드 출력을 건너뛰므로 Docker live 실행이 머신별 artifact를 복사하느라 몇 분씩 소비하지 않습니다. 또한 OPENCLAW_SKIP_CHANNELS=1을 설정하므로 Gateway live 프로브가 컨테이너 내부에서 실제 Telegram/Discord 등의 채널 워커를 시작하지 않습니다. test:docker:live-models는 여전히 pnpm test:live를 실행하므로, 해당 Docker 레인에서 Gateway live 커버리지를 좁히거나 제외해야 할 때는 OPENCLAW_LIVE_GATEWAY_*도 함께 전달하세요. test:docker:openwebui는 더 높은 수준의 호환성 스모크입니다. 이 레인은 OpenAI 호환 HTTP endpoint가 활성화된 OpenClaw Gateway 컨테이너를 시작하고, 해당 Gateway를 대상으로 고정된 Open WebUI 컨테이너를 시작한 뒤, Open WebUI를 통해 로그인하고, /api/modelsopenclaw/default를 노출하는지 확인한 다음, Open WebUI의 /api/chat/completions 프록시를 통해 실제 chat 요청을 전송합니다. 첫 실행은 Docker가 Open WebUI 이미지를 pull해야 하거나 Open WebUI가 자체 cold-start setup을 마쳐야 할 수 있으므로 눈에 띄게 더 느릴 수 있습니다. 이 레인은 사용 가능한 live 모델 키를 기대하며, OPENCLAW_PROFILE_FILE(~/.profile이 기본값)이 Dockerized 실행에서 이를 제공하는 기본 방식입니다. 성공적으로 실행되면 { "ok": true, "model": "openclaw/default", ... }와 같은 작은 JSON payload가 출력됩니다. test:docker:mcp-channels는 의도적으로 결정적이며 실제 Telegram, Discord 또는 iMessage 계정이 필요하지 않습니다. 이 레인은 seed된 Gateway 컨테이너를 부팅하고, openclaw mcp serve를 spawn하는 두 번째 컨테이너를 시작한 뒤, 실제 stdio MCP 브리지를 통해 라우팅된 대화 검색, transcript 읽기, attachment 메타데이터, live event queue 동작, outbound 전송 라우팅, Claude 스타일 채널 + 권한 알림을 검증합니다. notification 검사는 원시 stdio MCP 프레임을 직접 검사하므로, 이 스모크는 특정 client SDK가 우연히 표면화하는 내용이 아니라 브리지가 실제로 방출하는 것을 검증합니다. 수동 ACP plain-language 스레드 스모크(CI 아님):
  • bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...
  • 이 스크립트는 회귀/디버그 워크플로를 위해 유지하세요. ACP 스레드 라우팅 검증에 다시 필요할 수 있으므로 삭제하지 마세요.
유용한 env var:
  • 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에 마운트하여 Docker 내부 CLI 설치 캐시로 사용
  • $HOME 아래의 외부 CLI 인증 디렉터리/파일은 /host-auth... 아래에 읽기 전용으로 마운트된 다음, 테스트 시작 전에 /home/node/...로 복사됩니다
    • 기본 디렉터리: .minimax
    • 기본 파일: ~/.codex/auth.json, ~/.codex/config.toml, .claude.json, ~/.claude/.credentials.json, ~/.claude/settings.json, ~/.claude/settings.local.json
    • 범위를 좁힌 Provider 실행은 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=...
  • 컨테이너 내부 Provider 필터링을 위해 OPENCLAW_LIVE_GATEWAY_PROVIDERS=... / OPENCLAW_LIVE_PROVIDERS=...
  • 재빌드가 필요 없는 재실행에서 기존 openclaw:local-live 이미지를 재사용하려면 OPENCLAW_SKIP_DOCKER_BUILD=1
  • 자격 증명이 프로필 저장소에서 오도록 보장하려면(환경 변수 아님) OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1
  • Open WebUI 스모크를 위해 Gateway가 노출할 모델을 선택하려면 OPENCLAW_OPENWEBUI_MODEL=...
  • Open WebUI 스모크에서 사용하는 nonce 확인 프롬프트를 재정의하려면 OPENCLAW_OPENWEBUI_PROMPT=...
  • 고정된 Open WebUI 이미지 태그를 재정의하려면 OPENWEBUI_IMAGE=...

문서 sanity 확인

문서를 수정한 뒤에는 docs 검사를 실행하세요: pnpm check:docs. 페이지 내 heading 검사도 필요할 때는 전체 Mintlify anchor 검증을 실행하세요: pnpm docs:check-links:anchors.

오프라인 회귀(CI 안전)

이들은 실제 Provider 없이 “실제 파이프라인” 회귀를 검증합니다.
  • Gateway tool calling(mock OpenAI, 실제 Gateway + 에이전트 루프): src/gateway/gateway.test.ts (케이스: “runs a mock OpenAI tool call end-to-end via gateway agent loop”)
  • Gateway wizard(WS wizard.start/wizard.next, config + auth 강제 기록): src/gateway/gateway.test.ts (케이스: “runs wizard over ws and writes auth token config”)

에이전트 신뢰성 평가(Skills)

이미 “에이전트 신뢰성 평가”처럼 동작하는 몇 가지 CI 안전 테스트가 있습니다.
  • 실제 Gateway + 에이전트 루프를 통한 mock tool-calling(src/gateway/gateway.test.ts)
  • 세션 wiring과 config 효과를 검증하는 엔드투엔드 wizard 흐름(src/gateway/gateway.test.ts)
Skills에 대해 아직 부족한 것(Skills 참고):
  • 의사결정: 프롬프트에 Skills가 나열되었을 때, 에이전트가 올바른 skill을 선택하는가(또는 관련 없는 skill을 피하는가)?
  • 준수: 에이전트가 사용 전에 SKILL.md를 읽고 필수 단계/인자를 따르는가?
  • 워크플로 계약: tool 순서, 세션 히스토리 유지, sandbox 경계를 검증하는 다중 턴 시나리오.
향후 평가는 먼저 결정적으로 유지되어야 합니다.
  • mock Provider를 사용해 tool 호출 + 순서, skill 파일 읽기, 세션 wiring을 검증하는 시나리오 러너
  • skill 중심 시나리오의 소규모 스위트(사용 vs 회피, 게이팅, 프롬프트 인젝션)
  • CI 안전 스위트가 마련된 뒤에만 선택적으로 live 평가(옵트인, env 게이트)

계약 테스트(Plugin 및 채널 형태)

계약 테스트는 등록된 모든 Plugin과 채널이 해당 인터페이스 계약을 준수하는지 검증합니다. 이 테스트들은 발견된 모든 Plugin을 순회하며 형태 및 동작 검증 스위트를 실행합니다. 기본 pnpm test unit 레인은 의도적으로 이러한 공유 seam 및 스모크 파일을 건너뛰므로, 공유 채널 또는 Provider 표면을 건드렸다면 계약 명령을 명시적으로 실행하세요.

명령

  • 모든 계약: pnpm test:contracts
  • 채널 계약만: pnpm test:contracts:channels
  • Provider 계약만: pnpm test:contracts:plugins

채널 계약

src/channels/plugins/contracts/*.contract.test.ts에 위치:
  • plugin - 기본 Plugin 형태(id, name, capability)
  • setup - setup wizard 계약
  • session-binding - 세션 바인딩 동작
  • outbound-payload - 메시지 payload 구조
  • inbound - inbound 메시지 처리
  • actions - 채널 action 핸들러
  • threading - 스레드 ID 처리
  • directory - 디렉터리/roster API
  • group-policy - 그룹 정책 강제

Provider 상태 계약

src/plugins/contracts/*.contract.test.ts에 위치합니다.
  • status - 채널 상태 프로브
  • registry - Plugin registry 형태

Provider 계약

src/plugins/contracts/*.contract.test.ts에 위치:
  • auth - 인증 흐름 계약
  • auth-choice - 인증 선택/선정
  • catalog - 모델 catalog API
  • discovery - Plugin 검색
  • loader - Plugin 로딩
  • runtime - Provider runtime
  • shape - Plugin 형태/인터페이스
  • wizard - setup wizard

실행 시점

  • Plugin SDK export 또는 subpath를 변경한 후
  • 채널 또는 Provider Plugin을 추가하거나 수정한 후
  • Plugin 등록 또는 검색을 리팩터링한 후
계약 테스트는 CI에서 실행되며 실제 API 키가 필요하지 않습니다.

회귀 테스트 추가하기(가이드)

live에서 발견된 Provider/모델 이슈를 수정할 때:
  • 가능하다면 CI 안전 회귀 테스트를 추가하세요(mock/stub Provider 또는 정확한 요청 형태 변환 캡처)
  • 본질적으로 live 전용인 경우(rate limit, 인증 정책), live 테스트를 좁게 유지하고 env var로 옵트인되게 하세요
  • 버그를 포착하는 가장 작은 계층을 타깃팅하는 것을 선호하세요:
    • Provider 요청 변환/리플레이 버그 → 직접 모델 테스트
    • Gateway 세션/히스토리/tool 파이프라인 버그 → Gateway live 스모크 또는 CI 안전 Gateway mock 테스트
  • SecretRef 순회 가드레일:
    • src/secrets/exec-secret-ref-id-parity.test.ts는 registry 메타데이터(listSecretTargetRegistryEntries())에서 SecretRef 클래스별 샘플 타깃 하나를 도출한 뒤, 순회 세그먼트 exec id가 거부되는지 검증합니다.
    • src/secrets/target-registry-data.ts에 새 includeInPlan SecretRef 타깃 계열을 추가한다면, 해당 테스트의 classifyTargetClass를 업데이트하세요. 이 테스트는 분류되지 않은 타깃 id에서 의도적으로 실패하므로 새 클래스가 조용히 건너뛰어질 수 없습니다.