Fundamentals
ภาพรวม QA
สแต็ก QA แบบส่วนตัวมีไว้เพื่อทดสอบ OpenClaw ในรูปแบบที่สมจริงกว่าและมีลักษณะเป็น channel มากกว่าที่ unit test เดี่ยวจะทำได้
ส่วนประกอบปัจจุบัน:
extensions/qa-channel: channel ข้อความสังเคราะห์ที่มีพื้นผิว DM, channel, thread, reaction, edit และ deleteextensions/qa-lab: UI ดีบักเกอร์และบัส QA สำหรับสังเกต transcript, ฉีดข้อความขาเข้า และส่งออกรายงาน Markdownextensions/qa-matrix, Plugin runner ในอนาคต: อะแดปเตอร์ live-transport ที่ ขับ channel จริงภายใน Gateway QA ลูกqa/: แอสเซ็ต seed ที่อิง repo สำหรับงานเริ่มต้นและสถานการณ์ QA baseline- Mantis: การตรวจสอบสดก่อนและหลังสำหรับบั๊กที่ ต้องใช้ transport จริง, ภาพหน้าจอเบราว์เซอร์, สถานะ VM และหลักฐาน PR
พื้นผิวคำสั่ง
ทุก flow ของ QA รันภายใต้ pnpm openclaw qa <subcommand> หลายรายการมี alias สคริปต์ pnpm qa:*;
รองรับทั้งสองรูปแบบ
| คำสั่ง | วัตถุประสงค์ |
|---|---|
qa run |
self-check QA ที่ bundle มาโดยไม่มี --qa-profile; runner โปรไฟล์ maturity ที่อิง taxonomy ด้วย --qa-profile smoke-ci, --qa-profile release หรือ --qa-profile all |
qa suite |
รันสถานการณ์ที่อิง repo กับเลน Gateway QA Alias: pnpm openclaw qa suite --runner multipass สำหรับ VM Linux แบบใช้แล้วทิ้ง |
qa coverage |
พิมพ์ inventory ความครอบคลุมสถานการณ์ YAML (--json สำหรับเอาต์พุตเครื่อง) |
qa parity-report |
เปรียบเทียบไฟล์ qa-suite-summary.json สองไฟล์และเขียนรายงาน parity แบบ agentic หรือใช้ --runtime-axis --token-efficiency เพื่อเขียนรายงาน parity runtime Codex-vs-OpenClaw และรายงานประสิทธิภาพ token จาก summary คู่ runtime เดียว |
qa character-eval |
รันสถานการณ์ QA ด้าน character ข้าม live model หลายตัวพร้อมรายงานที่ผ่านการตัดสิน ดู การรายงาน |
qa manual |
รัน prompt แบบครั้งเดียวกับเลน provider/model ที่เลือก |
qa ui |
เริ่ม UI ดีบักเกอร์ QA และบัส QA ในเครื่อง (alias: pnpm qa:lab:ui) |
qa docker-build-image |
สร้างอิมเมจ Docker QA ที่เตรียมไว้ล่วงหน้า |
qa docker-scaffold |
เขียน scaffold docker-compose สำหรับ dashboard QA + เลน Gateway |
qa up |
สร้างไซต์ QA, เริ่มสแต็กที่อิง Docker, พิมพ์ URL (alias: pnpm qa:lab:up; ตัวแปร :fast เพิ่ม --use-prebuilt-image --bind-ui-dist --skip-ui-build) |
qa aimock |
เริ่มเฉพาะเซิร์ฟเวอร์ provider AIMock |
qa mock-openai |
เริ่มเฉพาะเซิร์ฟเวอร์ provider mock-openai ที่รับรู้สถานการณ์ |
qa credentials doctor / add / list / remove |
จัดการพูลข้อมูลประจำตัว Convex ที่ใช้ร่วมกัน |
qa matrix |
เลน live transport กับ homeserver Tuwunel แบบใช้แล้วทิ้ง ดู Matrix QA |
qa telegram |
เลน live transport กับกลุ่ม Telegram ส่วนตัวจริง |
qa discord |
เลน live transport กับ channel ใน guild Discord ส่วนตัวจริง |
qa slack |
เลน live transport กับ channel Slack ส่วนตัวจริง |
qa whatsapp |
เลน live transport กับบัญชี WhatsApp Web จริง |
qa mantis |
runner ตรวจสอบก่อนและหลังสำหรับบั๊ก live transport พร้อมหลักฐาน status-reaction ของ Discord, smoke เดสก์ท็อป/เบราว์เซอร์ Crabbox และ smoke Slack-in-VNC ดู Mantis และ Runbook Mantis Slack Desktop |
qa run ที่อิงโปรไฟล์อ่านสมาชิกจาก taxonomy.yaml จากนั้น dispatch
สถานการณ์ที่ resolve แล้วผ่าน qa suite --surface และ
--category กรองโปรไฟล์ที่เลือกแทนการกำหนดเลนแยก
qa-evidence.json ที่ได้จะมี summary scorecard ของโปรไฟล์พร้อม
จำนวนหมวดหมู่ที่เลือกและ ID ความครอบคลุมที่ขาดไป; รายการหลักฐานรายตัว
ยังคงเป็นแหล่งความจริงสำหรับการทดสอบ บทบาทความครอบคลุม และผลลัพธ์
ID ความครอบคลุมฟีเจอร์ taxonomy เป็นเป้าหมายหลักฐานที่ตรงตัว ไม่ใช่ alias ความครอบคลุม
สถานการณ์หลักเติมเต็ม ID ที่ตรงกัน; ความครอบคลุมรองยังเป็นเพียงคำแนะนำ
ID ความครอบคลุมใช้รูปแบบ dotted namespace.behavior โดยมี segment
ตัวอักษรและตัวเลขตัวพิมพ์เล็ก/ขีดกลาง; ID โปรไฟล์, surface และ category ยังอาจใช้
ID taxonomy แบบขีดกลางหรือ dotted ที่มีอยู่ได้
หลักฐานแบบ slim ละเว้น execution รายรายการและตั้งค่า evidenceMode: "slim";
smoke-ci ตั้งค่าเริ่มต้นเป็น slim และ --evidence-mode full คืนค่ารายการเต็ม:
pnpm openclaw qa run \ --qa-profile smoke-ci \ --category channel-framework.conversation-routing-and-delivery \ --provider-mode mock-openai \ --output-dir .artifacts/qa-e2e/smoke-ci-profile-dispatchใช้ smoke-ci สำหรับหลักฐานโปรไฟล์แบบ deterministic ด้วย provider โมเดล mock และ
เซิร์ฟเวอร์ provider ปลอม Crabline ใช้ release สำหรับหลักฐาน Stable/LTS กับ live
channels ใช้ all เฉพาะสำหรับการรันหลักฐาน taxonomy เต็มแบบชัดเจนเท่านั้น; มันเลือก
ทุกหมวด maturity ที่ active และสามารถ dispatch ผ่าน workflow QA Profile Evidence ด้วย qa_profile=all เมื่อคำสั่งต้องใช้โปรไฟล์ root ของ OpenClaw ด้วย
ให้วางโปรไฟล์ root ก่อนคำสั่ง QA:
pnpm openclaw --profile work qa run --qa-profile smoke-ciFlow ของ operator
flow ของ operator QA ปัจจุบันเป็นไซต์ QA แบบสอง pane:
- ซ้าย: dashboard Gateway (Control UI) พร้อม agent
- ขวา: QA Lab ที่แสดง transcript แบบ Slack และแผนสถานการณ์
รันด้วย:
pnpm qa:lab:upคำสั่งนั้นสร้างไซต์ QA, เริ่มเลน Gateway ที่อิง Docker และเปิดเผย หน้า QA Lab ที่ operator หรือ loop automation สามารถมอบภารกิจ QA ให้ agent, สังเกตพฤติกรรม channel จริง และบันทึกว่าสิ่งใดทำงาน ล้มเหลว หรือ ยังถูกบล็อกอยู่
สำหรับการ iterate UI ของ QA Lab ในเครื่องให้เร็วขึ้นโดยไม่ต้อง rebuild อิมเมจ Docker ทุกครั้ง ให้เริ่มสแต็กด้วย bundle QA Lab แบบ bind-mounted:
pnpm openclaw qa docker-build-imagepnpm qa:lab:buildpnpm qa:lab:up:fastpnpm qa:lab:watchqa:lab:up:fast คงบริการ Docker ไว้บนอิมเมจที่สร้างไว้ล่วงหน้าและ bind-mount
extensions/qa-lab/web/dist เข้าไปในคอนเทนเนอร์ qa-lab qa:lab:watch
rebuild bundle นั้นเมื่อมีการเปลี่ยนแปลง และเบราว์เซอร์จะ reload อัตโนมัติเมื่อ hash แอสเซ็ต QA Lab
เปลี่ยน
สำหรับ smoke สัญญาณ OpenTelemetry ในเครื่อง ให้รัน:
pnpm qa:otel:smokeสคริปต์นั้นเริ่มตัวรับ OTLP/HTTP ในเครื่อง, รันสถานการณ์ QA otel-trace-smoke
โดยเปิดใช้ Plugin diagnostics-otel จากนั้น assert ว่า trace,
metric และ log ถูกส่งออก มัน decode span trace protobuf ที่ส่งออก
และตรวจรูปทรงที่สำคัญต่อ release:
openclaw.run, openclaw.harness.run, span การเรียกโมเดลตาม semantic-convention
GenAI ล่าสุด, openclaw.context.assembled และ openclaw.message.delivery
ต้องมีอยู่ smoke บังคับใช้
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental ดังนั้น span การเรียกโมเดล
ต้องใช้ชื่อ {gen_ai.operation.name} {gen_ai.request.model};
การเรียกโมเดลต้องไม่ส่งออก StreamAbandoned ใน turn ที่สำเร็จ; ID diagnostic ดิบและ
แอตทริบิวต์ openclaw.content.* ต้องไม่อยู่ใน trace payload OTLP ดิบ
ต้องไม่มี sentinel ของ prompt, sentinel ของ response หรือคีย์ session QA
มันเขียน otel-smoke-summary.json ถัดจาก artifact ของ QA suite
สำหรับ smoke OpenTelemetry ที่มี collector รองรับ ให้รัน:
pnpm qa:otel:collector-smokeเลนนั้นวางคอนเทนเนอร์ Docker OpenTelemetry Collector จริงไว้ด้านหน้า ตัวรับในเครื่องตัวเดียวกัน ใช้เมื่อเปลี่ยน endpoint wiring, ความเข้ากันได้กับ collector หรือพฤติกรรม export OTLP ที่ตัวรับใน process อาจปิดบังได้
สำหรับ smoke scrape Prometheus ที่ป้องกันไว้ ให้รัน:
pnpm qa:prometheus:smokeนามแฝงนั้นรันสถานการณ์ QA docker-prometheus-smoke โดยเปิดใช้
diagnostics-prometheus ตรวจสอบว่าการ scrape แบบไม่ผ่านการยืนยันตัวตนถูกปฏิเสธ
จากนั้นตรวจสอบว่า scrape ที่ผ่านการยืนยันตัวตนมีชุดเมตริกสำคัญต่อรีลีส
โดยไม่มีเนื้อหา prompt, เนื้อหา response, ตัวระบุการวินิจฉัยดิบ, โทเค็น auth
หรือพาธภายในเครื่อง
หากต้องการรัน smoke ด้าน observability ทั้งสองรายการต่อเนื่องกัน ให้ใช้:
pnpm qa:observability:smokeสำหรับเลน OpenTelemetry ที่มี collector รองรับ พร้อมกับ smoke การ scrape Prometheus ที่มีการป้องกัน ให้ใช้:
pnpm qa:observability:collector-smokeQA ด้าน observability ยังคงใช้ได้เฉพาะ source checkout เท่านั้น npm tarball
จงใจไม่รวม QA Lab ดังนั้นเลนรีลีสแพ็กเกจ Docker จะไม่รันคำสั่ง qa ใช้
pnpm qa:otel:smoke, pnpm qa:prometheus:smoke หรือ
pnpm qa:observability:smoke จาก source checkout ที่ build แล้วเมื่อเปลี่ยน
เครื่องมือวัด diagnostics
สำหรับเลน smoke Matrix ที่ใช้ transport จริงและไม่ต้องใช้ข้อมูลรับรองของ model-provider ให้รันโปรไฟล์แบบเร็วด้วย provider OpenAI จำลองที่กำหนดผลแน่นอน:
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000 \ pnpm openclaw qa matrix --provider-mode mock-openai --profile fast --fail-fastสำหรับเลน provider live-frontier ให้ระบุข้อมูลรับรองที่เข้ากันได้กับ OpenAI อย่างชัดเจน:
OPENCLAW_LIVE_OPENAI_KEY="${OPENAI_API_KEY}" \OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000 \ pnpm openclaw qa matrix --provider-mode live-frontier --profile fast --fail-fastเอกสารอ้างอิง CLI ฉบับเต็ม แค็ตตาล็อกโปรไฟล์/สถานการณ์ env vars และผัง artifact สำหรับเลนนี้อยู่ใน Matrix QA โดยสรุปคือ เลนนี้จัดเตรียม Tuwunel homeserver แบบใช้แล้วทิ้งใน Docker ลงทะเบียนผู้ใช้ driver/SUT/observer ชั่วคราว รัน Plugin Matrix จริงภายใน Gateway QA ลูกที่จำกัดขอบเขตเฉพาะ transport นั้น (ไม่มี qa-channel) จากนั้นเขียนรายงาน Markdown สรุป JSON artifact เหตุการณ์ที่สังเกตได้ และ log output รวมไว้ใต้ .artifacts/qa-e2e/matrix-<timestamp>/
สถานการณ์ครอบคลุมพฤติกรรม transport ที่ unit test ไม่สามารถพิสูจน์แบบครบวงจรได้ ได้แก่ mention gating, นโยบาย allow-bot, allowlist, การตอบกลับระดับบนสุดและแบบ thread, การกำหนดเส้นทาง DM, การจัดการ reaction, การระงับ inbound edit, การ dedupe replay หลัง restart, การกู้คืนจาก homeserver interruption, การส่ง metadata approval, การจัดการ media และ flow การ bootstrap/recovery/verification ของ Matrix E2EE โปรไฟล์ CLI ของ E2EE ยังขับคำสั่ง openclaw matrix encryption setup และคำสั่ง verification ผ่าน homeserver แบบใช้แล้วทิ้งเดียวกันก่อนตรวจสอบการตอบกลับของ Gateway
Discord ยังมีสถานการณ์ opt-in เฉพาะ Mantis สำหรับการทำซ้ำ bug ใช้
--scenario discord-status-reactions-tool-only สำหรับ timeline ของ status reaction
แบบชัดเจน หรือ --scenario discord-thread-reply-filepath-attachment เพื่อสร้าง
thread Discord จริงและตรวจสอบว่า message.thread-reply เก็บรักษาไฟล์แนบ
filePath สถานการณ์เหล่านี้ไม่อยู่ในเลน Discord live เริ่มต้น
เพราะเป็น probe ทำซ้ำก่อน/หลังมากกว่าความครอบคลุม smoke แบบกว้าง
workflow Mantis สำหรับ thread-attachment ยังสามารถเพิ่มวิดีโอพยานจาก Discord Web
ที่ล็อกอินแล้วได้เมื่อกำหนดค่า MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR หรือ
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64 ในสภาพแวดล้อม QA
โปรไฟล์ viewer นั้นใช้สำหรับจับภาพเท่านั้น การตัดสิน pass/fail
ยังมาจาก oracle ของ Discord REST
CI ใช้พื้นผิวคำสั่งเดียวกันใน .github/workflows/qa-live-transports-convex.yml
การรันตามตารางเวลาและการรันด้วยมือแบบเริ่มต้นจะรันโปรไฟล์ Matrix แบบเร็วด้วย
ข้อมูลรับรอง live-frontier ที่ QA จัดเตรียมไว้, --fast และ
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000 การรันด้วยมือที่ matrix_profile=all
จะแยกออกเป็น shard โปรไฟล์ห้ารายการ
สำหรับเลน smoke Telegram, Discord, Slack และ WhatsApp ที่ใช้ transport จริง:
pnpm openclaw qa telegrampnpm openclaw qa discordpnpm openclaw qa slackpnpm openclaw qa whatsappเลนเหล่านี้ชี้ไปยัง channel จริงที่มีอยู่แล้วพร้อม bot หรือ account สองตัว (driver + SUT) env vars ที่จำเป็น รายการสถานการณ์ output artifacts และ pool ข้อมูลรับรอง Convex มีเอกสารใน เอกสารอ้างอิง QA สำหรับ Telegram, Discord, Slack และ WhatsApp ด้านล่าง
สำหรับการรัน Slack desktop VM แบบเต็มพร้อม VNC rescue ให้รัน:
pnpm openclaw qa mantis slack-desktop-smoke \ --gateway-setup \ --scenario slack-canary \ --keep-leaseคำสั่งนั้นเช่าเครื่อง desktop/browser ของ Crabbox รันเลน Slack live
ภายใน VM เปิด Slack Web ใน browser ของ VNC จับภาพ desktop และคัดลอก
slack-qa/, slack-desktop-smoke.png และ slack-desktop-smoke.mp4
เมื่อมีการจับวิดีโอกลับไปยังไดเรกทอรี artifact ของ Mantis lease แบบ
desktop/browser ของ Crabbox มีเครื่องมือจับภาพและแพ็กเกจช่วย browser/native-build
ให้ล่วงหน้า ดังนั้นสถานการณ์ควรติดตั้ง fallback เฉพาะบน lease รุ่นเก่าเท่านั้น
Mantis รายงานเวลาโดยรวมและราย phase ใน
mantis-slack-desktop-smoke-report.md เพื่อให้การรันที่ช้าแสดงได้ว่าเวลาเสียไปกับ
lease warmup, การรับข้อมูลรับรอง, remote setup หรือการคัดลอก artifact
ใช้ --lease-id <cbx_...> ซ้ำหลังจากล็อกอินเข้า Slack Web ด้วยตนเองผ่าน VNC
lease ที่ใช้ซ้ำยังคงทำให้ cache pnpm store ของ Crabbox อุ่นอยู่ ค่าเริ่มต้น
--hydrate-mode source ตรวจสอบจาก source checkout และรัน install/build
ภายใน VM ใช้ --hydrate-mode prehydrated เฉพาะเมื่อ workspace ระยะไกลที่ใช้ซ้ำ
มี node_modules และ dist/ ที่ build แล้วอยู่แล้ว โหมดนั้นข้ามขั้นตอน
install/build ที่มีต้นทุนสูงและ fail closed เมื่อ workspace ยังไม่พร้อม
เมื่อมี --gateway-setup Mantis จะคง Gateway Slack ของ OpenClaw ที่ทำงานต่อเนื่อง
ไว้ภายใน VM บนพอร์ต 38973; หากไม่มี คำสั่งจะรันเลน QA Slack แบบ bot-to-bot
ปกติและออกหลังจากจับ artifact
เพื่อพิสูจน์ UI approval ของ Slack แบบ native พร้อมหลักฐาน desktop ให้รันโหมด approval checkpoint ของ Mantis:
pnpm openclaw qa mantis slack-desktop-smoke \ --approval-checkpoints \ --credential-source convex \ --credential-role maintainerโหมดนี้ใช้ร่วมกับ --gateway-setup ไม่ได้ โหมดนี้รันสถานการณ์ approval ของ Slack
ปฏิเสธ scenario ids ที่ไม่ใช่ approval รอในแต่ละสถานะ approval ที่ pending และ
resolved render ข้อความ Slack API ที่สังเกตได้เป็น
approval-checkpoints/<scenario>-pending.png และ
approval-checkpoints/<scenario>-resolved.png จากนั้นล้มเหลวหาก checkpoint,
หลักฐานข้อความ, acknowledgement หรือ screenshot ที่ render ใดหายไปหรือว่างเปล่า
lease CI แบบ cold อาจยังแสดงหน้า sign-in ของ Slack ใน slack-desktop-smoke.png;
รูปภาพ approval checkpoint คือหลักฐานภาพสำหรับเลนนี้
checklist สำหรับ operator, คำสั่ง GitHub workflow dispatch, contract ของ evidence-comment, ตารางตัดสินใจ hydrate-mode, การตีความ timing และขั้นตอนจัดการ failure อยู่ใน Runbook Mantis Slack Desktop
สำหรับงาน desktop แบบ agent/CV ให้รัน:
pnpm openclaw qa mantis visual-task \ --browser-url https://example.net \ --expect-text "Example Domain" \ --vision-model openai/gpt-5.5visual-task เช่าหรือใช้เครื่อง desktop/browser ของ Crabbox ซ้ำ เริ่ม
crabbox record --while ขับ browser ที่มองเห็นได้ผ่าน visual-driver ซ้อน
จับ visual-task.png รัน openclaw infer image describe
กับ screenshot เมื่อเลือก --vision-mode image-describe และเขียน
visual-task.mp4, mantis-visual-task-summary.json,
mantis-visual-task-driver-result.json และ mantis-visual-task-report.md
เมื่อกำหนด --expect-text prompt ของ vision จะขอ verdict แบบ JSON ที่มีโครงสร้าง
และจะผ่านเฉพาะเมื่อ model รายงานหลักฐานที่มองเห็นได้เชิงบวกเท่านั้น response
เชิงลบที่เพียง quote ข้อความเป้าหมายจะทำให้ assertion ล้มเหลว
ใช้ --vision-mode metadata สำหรับ smoke แบบไม่ใช้ model ที่พิสูจน์ plumbing ของ
desktop, browser, screenshot และ video โดยไม่เรียก provider ด้าน image-understanding
การบันทึกเป็น artifact ที่จำเป็นสำหรับ visual-task; หาก Crabbox ไม่บันทึก
visual-task.mp4 ที่ไม่ว่าง งานจะล้มเหลวแม้ visual driver จะผ่านแล้วก็ตาม
เมื่อ failure Mantis จะเก็บ lease ไว้สำหรับ VNC เว้นแต่งานจะผ่านแล้วและไม่ได้ตั้ง
--keep-lease
ก่อนใช้ข้อมูลรับรอง live แบบ pooled ให้รัน:
pnpm openclaw qa credentials doctordoctor ตรวจสอบ env ของ broker Convex ตรวจสอบ endpoint settings และตรวจสอบการเข้าถึง admin/list เมื่อมี maintainer secret โดยรายงานเฉพาะสถานะ set/missing ของ secrets
ความครอบคลุม transport live
เลน transport live ใช้ contract เดียวกัน แทนที่แต่ละเลนจะคิดรูปแบบรายการสถานการณ์ของตนเอง qa-channel คือชุดทดสอบ product-behavior แบบสังเคราะห์ที่กว้าง และไม่ได้เป็นส่วนหนึ่งของ matrix ความครอบคลุม transport live
runner ของ transport live ควร import scenario ids ที่ใช้ร่วมกัน
helper coverage baseline และ helper สำหรับเลือกสถานการณ์จาก
openclaw/plugin-sdk/qa-live-transport-scenarios
| เลน | Canary | Mention gating | Bot-to-bot | Allowlist block | Top-level reply | Quote reply | Restart resume | Thread follow-up | Thread isolation | Reaction observation | Help command | Native command registration |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Matrix | x | x | x | x | x | x | x | x | x | |||
| Telegram | x | x | x | x | ||||||||
| Discord | x | x | x | x | ||||||||
| Slack | x | x | x | x | x | x | x | x | ||||
| x | x | x | x | x | x | x | x |
สิ่งนี้คง qa-channel ไว้เป็นชุดทดสอบ product-behavior แบบกว้าง ขณะที่ Matrix,
Telegram และ transport live อื่น ๆ ใช้ checklist transport-contract ที่ชัดเจนชุดเดียวกัน
สำหรับเลน Linux VM แบบใช้แล้วทิ้งโดยไม่ต้องนำ Docker เข้ามาในพาธ QA ให้รัน:
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baselineคำสั่งนี้ boot guest Multipass ใหม่ ติดตั้ง dependencies build OpenClaw
ภายใน guest รัน qa suite จากนั้นคัดลอกรายงาน QA และสรุปปกติ
กลับไปยัง .artifacts/qa-e2e/... บน host
คำสั่งนี้ใช้พฤติกรรมการเลือกสถานการณ์เดียวกันกับ qa suite บน host
การรัน suite บน host และ Multipass จะรันสถานการณ์ที่เลือกหลายรายการแบบ parallel
โดยใช้ worker ของ Gateway ที่แยกกันเป็นค่าเริ่มต้น qa-channel มีค่า concurrency
เริ่มต้นเป็น 4 และถูกจำกัดด้วยจำนวนสถานการณ์ที่เลือก ใช้ --concurrency <count> เพื่อปรับจำนวน
worker หรือ --concurrency 1 สำหรับการรันแบบ serial
ใช้ --pack personal-agent เพื่อรัน benchmark pack ของ personal assistant
ตัวเลือก pack เป็นแบบ additive ร่วมกับ flag --scenario ที่ระบุซ้ำได้:
สถานการณ์ที่ระบุโดยตรงจะรันก่อน จากนั้นสถานการณ์ใน pack จะรันตามลำดับ pack
พร้อมลบรายการซ้ำ
ใช้ --pack observability เมื่อ runner QA แบบกำหนดเองจัดเตรียมการตั้งค่า
OpenTelemetry collector อยู่แล้วและต้องการเลือกสถานการณ์ smoke ของ diagnostics
OpenTelemetry และ Prometheus ร่วมกัน
คำสั่งจะออกด้วย non-zero เมื่อสถานการณ์ใดล้มเหลว ใช้ --allow-failures เมื่อ
ต้องการ artifact โดยไม่ให้ exit code ล้มเหลว
การรัน live จะ forward input auth ของ QA ที่รองรับและใช้ได้จริงสำหรับ guest:
provider keys ผ่าน env, พาธ config ของ provider live สำหรับ QA และ
CODEX_HOME เมื่อมีอยู่ เก็บ --output-dir ไว้ใต้ repo root เพื่อให้ guest
เขียนกลับผ่าน workspace ที่ mount ไว้ได้
ข้อมูลอ้างอิง QA สำหรับ Telegram, Discord, Slack และ WhatsApp
Matrix มีหน้าเฉพาะ เนื่องจากมีจำนวนสถานการณ์มากและมีการจัดเตรียม homeserver ที่รองรับด้วย Docker ส่วน Telegram, Discord, Slack และ WhatsApp ทำงานกับระบบขนส่งจริงที่มีอยู่แล้ว ดังนั้นข้อมูลอ้างอิงของระบบเหล่านี้จึงอยู่ที่นี่
แฟล็ก CLI ที่ใช้ร่วมกัน
เลนเหล่านี้ลงทะเบียนผ่าน extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts และรับแฟล็กเดียวกัน:
| แฟล็ก | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|
--scenario <id> |
- | รันเฉพาะสถานการณ์นี้ ทำซ้ำได้ |
--output-dir <path> |
<repo>/.artifacts/qa-e2e/<transport>-<timestamp> |
ตำแหน่งที่เขียนรายงาน สรุป หลักฐาน อาร์ติแฟกต์เฉพาะระบบขนส่ง และบันทึกเอาต์พุต พาธสัมพัทธ์จะ resolve เทียบกับ --repo-root |
--repo-root <path> |
process.cwd() |
รากของรีโพสิทอรีเมื่อเรียกใช้จาก cwd ที่เป็นกลาง |
--sut-account <id> |
sut |
id บัญชีชั่วคราวภายใน config ของ QA gateway |
--provider-mode <mode> |
live-frontier |
mock-openai หรือ live-frontier (live-openai แบบ legacy ยังใช้งานได้) |
--model <ref> / --alt-model <ref> |
ค่าเริ่มต้นของ provider | refs ของโมเดลหลัก/สำรอง |
--fast |
ปิด | โหมดเร็วของ provider เมื่อรองรับ |
--credential-source <env|convex> |
env |
ดู พูลข้อมูลประจำตัว Convex |
--credential-role <maintainer|ci> |
ci ใน CI, มิฉะนั้นเป็น maintainer |
บทบาทที่ใช้เมื่อ --credential-source convex |
แต่ละเลนจะออกด้วยค่าที่ไม่ใช่ศูนย์เมื่อมีสถานการณ์ใดล้มเหลว --allow-failures จะเขียนอาร์ติแฟกต์โดยไม่ตั้งรหัสออกเป็นล้มเหลว
QA สำหรับ Telegram
pnpm openclaw qa telegramกำหนดเป้าหมายไปที่กลุ่ม Telegram ส่วนตัวจริงหนึ่งกลุ่มที่มีบอตสองตัวแยกกัน (driver + SUT) บอต SUT ต้องมีชื่อผู้ใช้ Telegram; การสังเกตแบบบอตต่อบอตทำงานได้ดีที่สุดเมื่อบอตทั้งสองเปิดใช้ โหมดการสื่อสารแบบบอตต่อบอต ใน @BotFather
env ที่จำเป็นเมื่อใช้ --credential-source env:
OPENCLAW_QA_TELEGRAM_GROUP_ID- id แชตตัวเลข (สตริง)OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKENOPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN
สถานการณ์ (extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts):
telegram-canarytelegram-mention-gatingtelegram-mentioned-message-replytelegram-help-commandtelegram-commands-commandtelegram-tools-compact-commandtelegram-whoami-commandtelegram-status-commandtelegram-repeated-command-authorizationtelegram-other-bot-command-gatingtelegram-context-commandtelegram-current-session-status-tooltelegram-reply-chain-exact-markertelegram-stream-final-single-messagetelegram-long-final-reuses-previewtelegram-long-final-three-chunks
ชุดค่าเริ่มต้นโดยนัยจะครอบคลุม canary, mention gating, การตอบกลับคำสั่ง native, การระบุที่อยู่คำสั่ง และการตอบกลับในกลุ่มแบบบอตต่อบอตเสมอ ค่าเริ่มต้นของ mock-openai ยังรวมการตรวจสอบ reply-chain แบบกำหนดได้และการสตรีม final-message ด้วย telegram-current-session-status-tool ยังคงเป็นแบบ opt-in เพราะเสถียรเฉพาะเมื่อถูกร้อยต่อโดยตรงหลัง canary ไม่ใช่หลังการตอบกลับคำสั่ง native ใดๆ ใช้ pnpm openclaw qa telegram --list-scenarios --provider-mode mock-openai เพื่อพิมพ์การแบ่งค่าเริ่มต้น/ตัวเลือกปัจจุบันพร้อม refs ของ regression
อาร์ติแฟกต์เอาต์พุต:
telegram-qa-report.mdqa-evidence.json- รายการหลักฐานสำหรับการตรวจสอบระบบขนส่งแบบ live รวมถึงฟิลด์ profile, coverage, provider, channel, artifacts, result และ RTT
การรัน Telegram ของแพ็กเกจใช้สัญญาข้อมูลประจำตัว Telegram เดียวกัน การวัด RTT ซ้ำเป็นส่วนหนึ่งของเลน live Telegram ของแพ็กเกจตามปกติ; การกระจาย RTT จะถูกรวมไว้ใน qa-evidence.json ภายใต้ result.timing สำหรับการตรวจสอบ RTT ที่เลือก
OPENCLAW_QA_CREDENTIAL_SOURCE=convex \pnpm test:docker:npm-telegram-liveเมื่อกำหนด OPENCLAW_QA_CREDENTIAL_SOURCE=convex wrapper live ของแพ็กเกจจะเช่าข้อมูลประจำตัว kind: "telegram" ส่งออก env ของกลุ่ม/driver/บอต SUT ที่เช่าไปยังการรันแพ็กเกจที่ติดตั้งแล้ว ทำ Heartbeat กับสัญญาเช่า และปล่อยสัญญาเช่าเมื่อ shutdown wrapper ของแพ็กเกจมีค่าเริ่มต้นเป็นการตรวจสอบ RTT 20 ครั้งของ telegram-mentioned-message-reply, timeout RTT 30 วินาที และบทบาท Convex เป็น maintainer นอก CI เมื่อเลือก Convex ปรับ OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES, OPENCLAW_NPM_TELEGRAM_RTT_TIMEOUT_MS หรือ OPENCLAW_NPM_TELEGRAM_RTT_MAX_FAILURES เพื่อปรับการวัด RTT โดยไม่ต้องสร้างคำสั่ง RTT แยกต่างหากหรือรูปแบบสรุปเฉพาะ Telegram
QA สำหรับ Discord
pnpm openclaw qa discordกำหนดเป้าหมายไปที่ช่อง guild ส่วนตัวจริงของ Discord หนึ่งช่องที่มีบอตสองตัว: บอต driver ที่ควบคุมโดย harness และบอต SUT ที่เริ่มโดย Gateway ย่อยของ OpenClaw ผ่าน Plugin Discord ที่ bundle มา ตรวจสอบการจัดการการ mention ในช่อง ว่าบอต SUT ได้ลงทะเบียนคำสั่ง native /help กับ Discord แล้ว และสถานการณ์หลักฐาน Mantis แบบ opt-in
env ที่จำเป็นเมื่อใช้ --credential-source env:
OPENCLAW_QA_DISCORD_GUILD_IDOPENCLAW_QA_DISCORD_CHANNEL_IDOPENCLAW_QA_DISCORD_DRIVER_BOT_TOKENOPENCLAW_QA_DISCORD_SUT_BOT_TOKENOPENCLAW_QA_DISCORD_SUT_APPLICATION_ID- ต้องตรงกับ id ผู้ใช้ของบอต SUT ที่ Discord ส่งคืน (มิฉะนั้นเลนจะล้มเหลวอย่างรวดเร็ว)
ตัวเลือก:
OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1เก็บเนื้อหาข้อความไว้ในอาร์ติแฟกต์ observed-messageOPENCLAW_QA_DISCORD_VOICE_CHANNEL_IDเลือกช่อง voice/stage สำหรับdiscord-voice-autojoin; หากไม่มี สถานการณ์จะเลือกช่อง voice/stage แรกที่มองเห็นได้สำหรับบอต SUT
สถานการณ์ (extensions/qa-lab/src/live-transports/discord/discord-live.runtime.ts:36):
discord-canarydiscord-mention-gatingdiscord-native-help-command-registrationdiscord-voice-autojoin- สถานการณ์เสียงแบบ opt-in รันแยกเดี่ยว เปิดใช้channels.discord.voice.autoJoinและตรวจสอบว่าสถานะเสียง Discord ปัจจุบันของบอต SUT คือช่อง voice/stage เป้าหมาย ข้อมูลประจำตัว Discord ของ Convex อาจรวมvoiceChannelIdที่เป็นตัวเลือก; มิฉะนั้น runner จะค้นหาช่อง voice/stage แรกที่มองเห็นได้ใน guilddiscord-status-reactions-tool-only- สถานการณ์ Mantis แบบ opt-in รันแยกเดี่ยวเพราะเปลี่ยน SUT ให้เป็นการตอบกลับ guild แบบ always-on และ tool-only ด้วยmessages.statusReactions.enabled=trueจากนั้นจับ timeline ของ reaction ผ่าน REST พร้อมอาร์ติแฟกต์ภาพ HTML/PNG รายงาน Mantis before/after ยังเก็บอาร์ติแฟกต์ MP4 ที่สถานการณ์ให้มาเป็นbaseline.mp4และcandidate.mp4
รันสถานการณ์ Discord voice auto-join โดยระบุชัดเจน:
pnpm openclaw qa discord \ --scenario discord-voice-autojoin \ --provider-mode mock-openaiรันสถานการณ์ Mantis status-reaction โดยระบุชัดเจน:
pnpm openclaw qa discord \ --scenario discord-status-reactions-tool-only \ --provider-mode live-frontier \ --model openai/gpt-5.5 \ --alt-model openai/gpt-5.5 \ --fastอาร์ติแฟกต์เอาต์พุต:
discord-qa-report.mdqa-evidence.json- รายการหลักฐานสำหรับการตรวจสอบระบบขนส่งแบบ livediscord-qa-observed-messages.json- เนื้อหาจะถูก redact เว้นแต่OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1discord-qa-reaction-timelines.jsonและdiscord-status-reactions-tool-only-timeline.pngเมื่อรันสถานการณ์ status-reaction
QA สำหรับ Slack
pnpm openclaw qa slackกำหนดเป้าหมายไปที่ช่อง Slack ส่วนตัวจริงหนึ่งช่องที่มีบอตสองตัวแยกกัน: บอต driver ที่ควบคุมโดย harness และบอต SUT ที่เริ่มโดย Gateway ย่อยของ OpenClaw ผ่าน Plugin Slack ที่ bundle มา
env ที่จำเป็นเมื่อใช้ --credential-source env:
OPENCLAW_QA_SLACK_CHANNEL_IDOPENCLAW_QA_SLACK_DRIVER_BOT_TOKENOPENCLAW_QA_SLACK_SUT_BOT_TOKENOPENCLAW_QA_SLACK_SUT_APP_TOKEN
ตัวเลือก:
OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1เก็บเนื้อหาข้อความไว้ในอาร์ติแฟกต์ observed-messageOPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIRเปิดใช้ checkpoint การอนุมัติแบบภาพสำหรับ Mantis runner จะเขียน<scenario>.pending.jsonและ<scenario>.resolved.jsonจากนั้นรอไฟล์.ack.jsonที่ตรงกันOPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_TIMEOUT_MSoverride timeout การ acknowledgement ของ checkpoint ค่าเริ่มต้นคือ120000
สถานการณ์ (extensions/qa-lab/src/live-transports/slack/slack-live.runtime.ts):
slack-canaryslack-mention-gatingslack-allowlist-blockslack-top-level-reply-shapeslack-restart-resumeslack-thread-follow-upslack-thread-isolationslack-approval-exec-native- สถานการณ์การอนุมัติ exec native ของ Slack แบบ opt-in ขอการอนุมัติ exec ผ่าน Gateway ตรวจสอบว่าข้อความ Slack มีปุ่มอนุมัติ native แก้ไขสถานะ แล้วตรวจสอบการอัปเดต Slack ที่แก้ไขแล้วslack-approval-plugin-native- สถานการณ์การอนุมัติ Plugin native ของ Slack แบบ opt-in เปิดใช้การส่งต่อการอนุมัติ exec และ Plugin พร้อมกันเพื่อไม่ให้เหตุการณ์ Plugin ถูกระงับโดยการ routing การอนุมัติ exec จากนั้นตรวจสอบเส้นทาง UI ของ Slack native แบบ pending/resolved เดียวกัน
อาร์ติแฟกต์เอาต์พุต:
slack-qa-report.mdqa-evidence.json- รายการหลักฐานสำหรับการตรวจสอบระบบขนส่งแบบ liveslack-qa-observed-messages.json- เนื้อหาจะถูก redact เว้นแต่OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1approval-checkpoints/- เฉพาะเมื่อ Mantis ตั้งค่าOPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIR; มี JSON ของ checkpoint, JSON ของ acknowledgement และภาพหน้าจอ pending/resolved
การตั้งค่า workspace ของ Slack
เลนนี้ต้องมีแอป Slack สองแอปแยกกันใน workspace เดียว พร้อมช่องที่บอตทั้งสองเป็นสมาชิก:
channelId- idCxxxxxxxxxxของช่องที่บอตทั้งสองได้รับเชิญ ใช้ช่องเฉพาะ; เลนจะโพสต์ทุกครั้งที่รันdriverBotToken- โทเค็นบอต (xoxb-...) ของแอป DriversutBotToken- โทเค็นบอต (xoxb-...) ของแอป SUT ซึ่งต้องเป็นแอป Slack แยกจาก driver เพื่อให้ id ผู้ใช้บอตไม่ซ้ำกันsutAppToken- โทเค็นระดับแอป (xapp-...) ของแอป SUT ที่มีconnections:writeใช้โดย Socket Mode เพื่อให้แอป SUT รับเหตุการณ์ได้
ควรใช้ workspace ของ Slack ที่จัดไว้สำหรับ QA โดยเฉพาะแทนการใช้ workspace production ซ้ำ
manifest ของ SUT ด้านล่างจงใจจำกัดการติดตั้ง production ของ Plugin Slack ที่ bundle มา (extensions/slack/src/setup-shared.ts:10) ให้เหลือ permissions และ events ที่ครอบคลุมโดยชุด QA แบบ live ของ Slack สำหรับการตั้งค่าช่อง production ตามที่ผู้ใช้เห็น ดู การตั้งค่าด่วนช่อง Slack; คู่ QA Driver/SUT ถูกแยกไว้โดยตั้งใจเพราะเลนต้องใช้ id ผู้ใช้บอตสองตัวที่แตกต่างกันใน workspace เดียว
1. สร้างแอป Driver
ไปที่ api.slack.com/apps → Create New App → From a manifest → เลือกเวิร์กสเปซ QA วาง manifest ต่อไปนี้ แล้วกด Install to Workspace:
{ "display_information": { "name": "OpenClaw QA Driver", "description": "Test driver bot for OpenClaw QA Slack live lane" }, "features": { "bot_user": { "display_name": "OpenClaw QA Driver", "always_online": true } }, "oauth_config": { "scopes": { "bot": ["chat:write", "channels:history", "groups:history", "users:read"] } }, "settings": { "socket_mode_enabled": false }}คัดลอก Bot User OAuth Token (xoxb-...) - ค่านี้จะเป็น driverBotToken Driver ต้องใช้เพียงการโพสต์ข้อความและระบุตัวตนของตัวเองเท่านั้น ไม่ต้องมี events และไม่ต้องใช้ Socket Mode
2. สร้างแอป SUT
ทำ Create New App → From a manifest ซ้ำในเวิร์กสเปซเดียวกัน แอป QA นี้ตั้งใจใช้ manifest สำหรับโปรดักชันของ Slack plugin ที่บันเดิลมาในเวอร์ชันที่แคบกว่า (extensions/slack/src/setup-shared.ts:10): ละเว้น reaction scopes และ events เพราะชุดทดสอบ Slack QA แบบ live ยังไม่ครอบคลุมการจัดการ reaction
{ "display_information": { "name": "OpenClaw QA SUT", "description": "OpenClaw QA SUT connector for OpenClaw" }, "features": { "bot_user": { "display_name": "OpenClaw QA SUT", "always_online": true }, "app_home": { "home_tab_enabled": true, "messages_tab_enabled": true, "messages_tab_read_only_enabled": false } }, "oauth_config": { "scopes": { "bot": [ "app_mentions:read", "assistant:write", "channels:history", "channels:read", "chat:write", "commands", "emoji:read", "files:read", "files:write", "groups:history", "groups:read", "im:history", "im:read", "im:write", "mpim:history", "mpim:read", "mpim:write", "pins:read", "pins:write", "usergroups:read", "users:read" ] } }, "settings": { "socket_mode_enabled": true, "event_subscriptions": { "bot_events": [ "app_home_opened", "app_mention", "channel_rename", "member_joined_channel", "member_left_channel", "message.channels", "message.groups", "message.im", "message.mpim", "pin_added", "pin_removed" ] } }}หลังจาก Slack สร้างแอปแล้ว ให้ทำสองอย่างในหน้าการตั้งค่าของแอป:
- Install to Workspace → คัดลอก Bot User OAuth Token → ค่านี้จะเป็น
sutBotToken - Basic Information → App-Level Tokens → Generate Token and Scopes → เพิ่ม scope
connections:write→ บันทึก → คัดลอกค่าxapp-...→ ค่านี้จะเป็นsutAppToken
ตรวจสอบว่า bot ทั้งสองมี user id แยกกันโดยเรียก auth.test กับแต่ละ token Runtime แยก driver และ SUT ด้วย user id; การใช้แอปเดียวซ้ำสำหรับทั้งสองอย่างจะทำให้ mention-gating ล้มเหลวทันที
3. สร้างช่อง
ในเวิร์กสเปซ QA ให้สร้างช่องหนึ่งช่อง (เช่น #openclaw-qa) และเชิญ bot ทั้งสองจากภายในช่อง:
/invite @OpenClaw QA Driver/invite @OpenClaw QA SUTคัดลอก id Cxxxxxxxxxx จาก channel info → About → Channel ID - ค่านี้จะเป็น channelId ช่องสาธารณะใช้ได้ หากคุณใช้ช่องส่วนตัว ทั้งสองแอปมี groups:history อยู่แล้ว ดังนั้นการอ่าน history ของ harness จะยังสำเร็จ
4. ลงทะเบียนข้อมูลประจำตัว
มีสองตัวเลือก ใช้ env vars สำหรับการดีบักบนเครื่องเดียว (ตั้งค่าตัวแปร OPENCLAW_QA_SLACK_* ทั้งสี่ตัวและส่ง --credential-source env) หรือ seed shared Convex pool เพื่อให้ CI และผู้ดูแลรายอื่น lease ได้
สำหรับ Convex pool ให้เขียนฟิลด์ทั้งสี่ลงในไฟล์ JSON:
{ "channelId": "Cxxxxxxxxxx", "driverBotToken": "xoxb-...", "sutBotToken": "xoxb-...", "sutAppToken": "xapp-..."}เมื่อ export OPENCLAW_QA_CONVEX_SITE_URL และ OPENCLAW_QA_CONVEX_SECRET_MAINTAINER ใน shell แล้ว ให้ลงทะเบียนและตรวจสอบ:
pnpm openclaw qa credentials add \ --kind slack \ --payload-file slack-creds.json \ --note "QA Slack pool seed" pnpm openclaw qa credentials list --kind slack --status all --jsonคาดหวัง count: 1, status: "active" และไม่มีฟิลด์ lease
5. ตรวจสอบแบบ end to end
รัน lane ในเครื่องเพื่อยืนยันว่า bot ทั้งสองคุยกันผ่าน broker ได้:
pnpm openclaw qa slack \ --credential-source convex \ --credential-role maintainer \ --output-dir .artifacts/qa-e2e/slack-localการรันที่ผ่านจะเสร็จภายในไม่ถึง 30 วินาที และ slack-qa-report.md จะแสดงทั้ง slack-canary และ slack-mention-gating เป็นสถานะ pass หาก lane ค้างประมาณ 90 วินาทีแล้วออกด้วย Convex credential pool exhausted for kind "slack" แปลว่า pool ว่างหรือทุกแถวถูก lease อยู่ - qa credentials list --kind slack --status all --json จะบอกได้ว่าเป็นกรณีใด
WhatsApp QA
pnpm openclaw qa whatsappกำหนดเป้าหมายไปยังบัญชี WhatsApp Web เฉพาะสองบัญชี: บัญชี driver ที่ควบคุมโดย harness และบัญชี SUT ที่เริ่มโดย Gateway ลูกของ OpenClaw ผ่าน WhatsApp plugin ที่บันเดิลมา
env ที่จำเป็นเมื่อใช้ --credential-source env:
OPENCLAW_QA_WHATSAPP_DRIVER_PHONE_E164OPENCLAW_QA_WHATSAPP_SUT_PHONE_E164OPENCLAW_QA_WHATSAPP_DRIVER_AUTH_ARCHIVE_BASE64OPENCLAW_QA_WHATSAPP_SUT_AUTH_ARCHIVE_BASE64
ตัวเลือกเพิ่มเติม:
OPENCLAW_QA_WHATSAPP_GROUP_JIDเปิดใช้งานสถานการณ์กลุ่ม เช่นwhatsapp-mention-gatingและwhatsapp-group-allowlist-blockOPENCLAW_QA_WHATSAPP_CAPTURE_CONTENT=1เก็บเนื้อหาข้อความไว้ใน artifacts ของ observed-message
แคตตาล็อกสถานการณ์ (extensions/qa-lab/src/live-transports/whatsapp/whatsapp-live.runtime.ts):
- Baseline และ group gating:
whatsapp-canary,whatsapp-pairing-block,whatsapp-mention-gating,whatsapp-top-level-reply-shape,whatsapp-restart-resume,whatsapp-group-allowlist-block. - คำสั่ง native:
whatsapp-help-command,whatsapp-status-command,whatsapp-commands-command,whatsapp-tools-compact-command,whatsapp-whoami-command,whatsapp-context-command,whatsapp-native-new-command. - พฤติกรรม reply และ final-output:
whatsapp-tool-only-usage-footer,whatsapp-reply-to-message,whatsapp-group-reply-to-message,whatsapp-reply-context-isolation,whatsapp-reply-delivery-shape,whatsapp-stream-final-message-accounting. - สื่อขาเข้าและข้อความแบบมีโครงสร้าง:
whatsapp-inbound-image-caption,whatsapp-audio-preflight,whatsapp-inbound-structured-messages,whatsapp-group-audio-gating. รายการเหล่านี้ส่งเหตุการณ์รูปภาพ เสียง เอกสาร ตำแหน่งที่ตั้ง รายชื่อผู้ติดต่อ และสติกเกอร์ของ WhatsApp จริงผ่าน driver - ความครอบคลุมของ Gateway ขาออกและ message action:
whatsapp-outbound-media-matrix,whatsapp-outbound-document-preserves-filename,whatsapp-outbound-poll,whatsapp-message-actions. - ความครอบคลุมของ access-control:
whatsapp-access-control-dm-open,whatsapp-access-control-dm-disabled,whatsapp-access-control-group-open,whatsapp-access-control-group-disabled,whatsapp-group-allowlist-block. - การอนุมัติ native:
whatsapp-approval-exec-deny-native,whatsapp-approval-exec-native,whatsapp-approval-exec-reaction-native,whatsapp-approval-plugin-native. - Status reactions:
whatsapp-status-reactions.
ปัจจุบันแคตตาล็อกมี 36 สถานการณ์ lane เริ่มต้น live-frontier ถูกจำกัดให้เล็กที่ 10 สถานการณ์เพื่อให้มี smoke coverage ที่รวดเร็ว lane เริ่มต้น mock-openai รันสถานการณ์แบบ deterministic 31 รายการผ่าน WhatsApp transport จริง โดย mock เฉพาะผลลัพธ์ของ model สถานการณ์ approval และการตรวจสอบที่หนักกว่าหรืออาจบล็อกบางรายการยังคงต้องระบุ scenario id อย่างชัดเจน
WhatsApp QA driver สังเกตการณ์ live events แบบมีโครงสร้าง (text, media,
location, reaction และ poll) และสามารถส่งสื่อ โพล รายชื่อผู้ติดต่อ ตำแหน่งที่ตั้ง และสติกเกอร์ได้โดยตรง QA Lab นำเข้า driver นั้นผ่านพื้นผิวแพ็กเกจ @openclaw/whatsapp/api.js แทนการเข้าถึงไฟล์ runtime ส่วนตัวของ WhatsApp โดยตรง เนื้อหาข้อความจะถูก redact ตามค่าเริ่มต้น ความครอบคลุมของ poll ขาออกและ upload-file รันผ่านการเรียก Gateway poll และ message.action แบบ deterministic แทนการเรียกใช้เครื่องมือด้วย model prompt อย่างเดียว
Artifacts เอาต์พุต:
whatsapp-qa-report.mdqa-evidence.json- รายการหลักฐานสำหรับการตรวจสอบ live transportwhatsapp-qa-observed-messages.json- เนื้อหาจะถูก redact เว้นแต่ตั้งค่าOPENCLAW_QA_WHATSAPP_CAPTURE_CONTENT=1
Convex credential pool
lane ของ Telegram, Discord, Slack และ WhatsApp สามารถ lease ข้อมูลประจำตัวจาก shared Convex pool แทนการอ่าน env vars ด้านบนได้ ส่ง --credential-source convex (หรือตั้งค่า OPENCLAW_QA_CREDENTIAL_SOURCE=convex); QA Lab จะขอ lease แบบ exclusive, ส่ง Heartbeat ตลอดระยะเวลาการรัน และ release เมื่อ shutdown ชนิดของ pool คือ "telegram", "discord", "slack" และ "whatsapp"
รูปทรง payload ที่ broker ตรวจสอบบน admin/add:
- Telegram (
kind: "telegram"):{ groupId: string, driverToken: string, sutToken: string }-groupIdต้องเป็นสตริง chat-id แบบตัวเลข - ผู้ใช้จริงของ Telegram (
kind: "telegram-user"):{ groupId: string, sutToken: string, testerUserId: string, testerUsername: string, telegramApiId: string, telegramApiHash: string, tdlibDatabaseEncryptionKey: string, tdlibArchiveBase64: string, tdlibArchiveSha256: string, desktopTdataArchiveBase64: string, desktopTdataArchiveSha256: string }- สำหรับ Mantis Telegram Desktop proof เท่านั้น lane ทั่วไปของ QA Lab ต้องไม่ acquire ชนิดนี้ - Discord (
kind: "discord"):{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }. - WhatsApp (
kind: "whatsapp"):{ driverPhoneE164: string, sutPhoneE164: string, driverAuthArchiveBase64: string, sutAuthArchiveBase64: string, groupJid?: string }- หมายเลขโทรศัพท์ต้องเป็นสตริง E.164 ที่แตกต่างกัน
เวิร์กโฟลว์ Mantis Telegram Desktop proof ถือ lease telegram-user ของ Convex แบบ exclusive หนึ่งรายการสำหรับทั้ง TDLib CLI driver และ Telegram Desktop witness จากนั้นจึง release หลังเผยแพร่ proof
เมื่อ PR ต้องใช้ visual diff แบบ deterministic Mantis สามารถใช้คำตอบ mock model เดียวกันบน main และบน PR head ขณะที่ formatter หรือ delivery layer ของ Telegram เปลี่ยนแปลง ค่าเริ่มต้นของ capture ถูกปรับให้เหมาะกับ PR comments: คลาส Crabbox มาตรฐาน, การบันทึกเดสก์ท็อป 24fps, motion GIF 24fps และความกว้าง preview 1920px ความคิดเห็น before/after ควรเผยแพร่ bundle ที่สะอาดซึ่งมีเฉพาะ GIF ที่ตั้งใจไว้เท่านั้น
Slack lanes สามารถใช้ pool ได้เช่นกัน การตรวจสอบรูปทรง payload ของ Slack ปัจจุบันอยู่ใน Slack QA runner แทน broker; ใช้ { channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string } พร้อม Slack channel id เช่น Cxxxxxxxxxx ดู การตั้งค่าเวิร์กสเปซ Slack สำหรับการเตรียมแอปและ scope
env vars สำหรับการปฏิบัติงานและ contract ของ Convex broker endpoint อยู่ใน การทดสอบ → ข้อมูลประจำตัว Telegram ที่ใช้ร่วมกันผ่าน Convex (ชื่อส่วนนี้มีมาก่อน multi-channel pool; semantics ของ lease ใช้ร่วมกันทุกชนิด)
Seeds ที่อิง repo
Seed assets อยู่ใน qa/:
qa/scenarios/index.yamlqa/scenarios/<theme>/*.yaml
ไฟล์เหล่านี้ตั้งใจเก็บไว้ใน git เพื่อให้แผน QA มองเห็นได้ทั้งสำหรับมนุษย์และ agent
qa-lab ควรคงเป็นตัวรันสถานการณ์ YAML แบบทั่วไป ไฟล์ YAML ของแต่ละสถานการณ์คือแหล่งข้อมูลจริงสำหรับการรันทดสอบหนึ่งครั้ง และควรกำหนด:
titleระดับบนสุด- metadata
scenario - metadata หมวดหมู่ capability, lane และ risk แบบไม่บังคับใน
scenario - refs ของ docs และ code ใน
scenario - ข้อกำหนด Plugin แบบไม่บังคับใน
scenario - patch การกำหนดค่า Gateway แบบไม่บังคับใน
scenario flowระดับบนสุดที่ execute ได้สำหรับสถานการณ์ flow หรือscenario.execution.kind/scenario.execution.pathสำหรับสถานการณ์ Vitest และ Playwright
พื้นผิวรันไทม์ที่ใช้ซ้ำได้ซึ่งรองรับ flow ได้รับอนุญาตให้คงความเป็นแบบทั่วไป
และครอบคลุมหลายส่วนได้ ตัวอย่างเช่น สถานการณ์ YAML สามารถผสานตัวช่วยฝั่งทรานสปอร์ต
กับตัวช่วยฝั่งเบราว์เซอร์ที่ขับเคลื่อน Control UI แบบฝังผ่านรอยต่อ
Gateway browser.request โดยไม่ต้องเพิ่มรันเนอร์กรณีพิเศษ
ไฟล์สถานการณ์ควรถูกจัดกลุ่มตามความสามารถของผลิตภัณฑ์แทนที่จะเป็นโฟลเดอร์
ในซอร์สทรี รักษา ID ของสถานการณ์ให้คงที่เมื่อย้ายไฟล์; ใช้ docsRefs และ codeRefs
เพื่อการสืบย้อนกลับไปยังการนำไปใช้
รายการพื้นฐานควรกว้างพอที่จะครอบคลุม:
- แชต DM และช่องทาง
- พฤติกรรมเธรด
- วงจรชีวิตของการกระทำกับข้อความ
- การเรียกกลับ cron
- การเรียกคืนหน่วยความจำ
- การสลับโมเดล
- การส่งต่อไปยังเอเจนต์ย่อย
- การอ่านรีโพและการอ่านเอกสาร
- งานบิลด์ขนาดเล็กหนึ่งงาน เช่น Lobster Invaders
เลน mock ของผู้ให้บริการ
qa suite มีเลน mock ผู้ให้บริการภายในเครื่องสองเลน:
mock-openaiคือ mock ของ OpenClaw ที่รับรู้สถานการณ์ เลนนี้ยังคงเป็นเลน mock แบบกำหนดแน่นอนเริ่มต้นสำหรับ QA ที่มีรีโพรองรับและเกตความเท่าเทียมaimockเริ่มเซิร์ฟเวอร์ผู้ให้บริการที่รองรับด้วย AIMock สำหรับความครอบคลุมด้านโปรโตคอล ฟิกซ์เจอร์ การบันทึก/เล่นซ้ำ และ chaos แบบทดลอง เป็นส่วนเสริมและไม่ได้แทนที่ ตัวแจกจ่ายสถานการณ์mock-openai
การนำเลนผู้ให้บริการไปใช้อยู่ภายใต้ extensions/qa-lab/src/providers/
ผู้ให้บริการแต่ละรายเป็นเจ้าของค่าเริ่มต้น การเริ่มเซิร์ฟเวอร์ภายในเครื่อง การกำหนดค่าโมเดล Gateway
ความต้องการเตรียม auth-profile และแฟล็กความสามารถ live/mock ของตน โค้ด suite และ
gateway ที่ใช้ร่วมกันควรเส้นทางผ่าน registry ผู้ให้บริการแทนการแตกแขนงตาม
ชื่อผู้ให้บริการ
อะแดปเตอร์ทรานสปอร์ต
qa-lab เป็นเจ้าของรอยต่อทรานสปอร์ตทั่วไปสำหรับสถานการณ์ QA แบบ YAML qa-channel คือ
ค่าเริ่มต้นสังเคราะห์ crabline เริ่มเซิร์ฟเวอร์ภายในเครื่องที่มีรูปทรงเหมือนผู้ให้บริการและรัน
Plugin ช่องทางปกติของ OpenClaw กับเซิร์ฟเวอร์เหล่านั้น live สงวนไว้สำหรับ
ข้อมูลรับรองผู้ให้บริการจริงและช่องทางภายนอก
ในระดับสถาปัตยกรรม การแบ่งเป็นดังนี้:
qa-labเป็นเจ้าของการดำเนินสถานการณ์ทั่วไป การทำงานพร้อมกันของ worker การเขียน artifact และการรายงาน- อะแดปเตอร์ทรานสปอร์ตเป็นเจ้าของการกำหนดค่า gateway, readiness, การสังเกต inbound และ outbound, การกระทำทรานสปอร์ต และสถานะทรานสปอร์ตที่ถูกทำให้เป็นมาตรฐาน
- ไฟล์สถานการณ์ YAML ภายใต้
qa/scenarios/กำหนดการรันทดสอบ;qa-labจัดเตรียมพื้นผิวรันไทม์ที่ใช้ซ้ำได้ซึ่งดำเนินการไฟล์เหล่านั้น
การเพิ่มช่องทาง
การเพิ่มช่องทางเข้าสู่ระบบ QA แบบ YAML ต้องมีการนำช่องทางไปใช้พร้อม
ชุดสถานการณ์ที่ทดสอบสัญญาของช่องทาง สำหรับความครอบคลุม CI แบบ smoke ให้เพิ่ม
เซิร์ฟเวอร์ผู้ให้บริการปลอม Crabline ที่ตรงกันและเปิดให้ใช้ผ่านไดรเวอร์ crabline
อย่าเพิ่มรูทคำสั่ง QA ระดับบนสุดใหม่เมื่อโฮสต์ qa-lab ที่ใช้ร่วมกันสามารถเป็นเจ้าของ flow ได้
qa-lab เป็นเจ้าของกลไกโฮสต์ที่ใช้ร่วมกัน:
- รูทคำสั่ง
openclaw qa - การเริ่มต้นและการปิด suite
- การทำงานพร้อมกันของ worker
- การเขียน artifact
- การสร้างรายงาน
- การดำเนินสถานการณ์
- alias ความเข้ากันได้สำหรับสถานการณ์
qa-channelรุ่นเก่า
Plugin รันเนอร์เป็นเจ้าของสัญญาทรานสปอร์ต:
- วิธีติดตั้ง
openclaw qa <runner>ใต้รูทqaที่ใช้ร่วมกัน - วิธีตั้งค่า gateway สำหรับทรานสปอร์ตนั้น
- วิธีตรวจสอบ readiness
- วิธีฉีดเหตุการณ์ inbound
- วิธีสังเกตข้อความ outbound
- วิธีเปิดเผย transcript และสถานะทรานสปอร์ตที่ถูกทำให้เป็นมาตรฐาน
- วิธีดำเนินการกระทำที่มีทรานสปอร์ตรองรับ
- วิธีจัดการการรีเซ็ตหรือการล้างข้อมูลเฉพาะทรานสปอร์ต
เกณฑ์ขั้นต่ำสำหรับการรับช่องทางใหม่:
- ให้
qa-labเป็นเจ้าของรูทqaที่ใช้ร่วมกันต่อไป - นำรันเนอร์ทรานสปอร์ตไปใช้บนรอยต่อโฮสต์
qa-labที่ใช้ร่วมกัน - เก็บกลไกเฉพาะทรานสปอร์ตไว้ภายใน Plugin รันเนอร์หรือ harness ช่องทาง
- ติดตั้งรันเนอร์เป็น
openclaw qa <runner>แทนการลงทะเบียนคำสั่งรูทที่แข่งขันกัน Plugin รันเนอร์ควรประกาศqaRunnersในopenclaw.plugin.jsonและส่งออกอาร์เรย์qaRunnerCliRegistrationsที่ตรงกันจากruntime-api.tsรักษาruntime-api.tsให้เบา; CLI แบบ lazy และการดำเนินรันเนอร์ควรอยู่หลัง entrypoint แยกต่างหาก - เขียนหรือปรับสถานการณ์ YAML ภายใต้ไดเรกทอรี
qa/scenarios/ตามธีม - ใช้ตัวช่วยสถานการณ์ทั่วไปสำหรับสถานการณ์ใหม่
- รักษา alias ความเข้ากันได้ที่มีอยู่ให้ทำงานต่อไป เว้นแต่รีโพกำลังทำ migration โดยตั้งใจ
กฎการตัดสินใจเข้มงวด:
- หากพฤติกรรมสามารถแสดงครั้งเดียวใน
qa-labได้ ให้วางไว้ในqa-lab - หากพฤติกรรมขึ้นกับทรานสปอร์ตช่องทางเดียว ให้เก็บไว้ใน Plugin รันเนอร์หรือ harness Plugin นั้น
- หากสถานการณ์ต้องการความสามารถใหม่ที่มากกว่าหนึ่งช่องทางสามารถใช้ได้ ให้เพิ่มตัวช่วยทั่วไปแทนการแตกแขนงเฉพาะช่องทางใน
suite.ts - หากพฤติกรรมมีความหมายเฉพาะสำหรับทรานสปอร์ตเดียว ให้รักษาสถานการณ์ให้เฉพาะทรานสปอร์ตและทำให้ชัดเจนในสัญญาสถานการณ์
ชื่อตัวช่วยสถานการณ์
ตัวช่วยทั่วไปที่แนะนำสำหรับสถานการณ์ใหม่:
waitForTransportReadywaitForChannelReadyinjectInboundMessageinjectOutboundMessagewaitForTransportOutboundMessagewaitForChannelOutboundMessagewaitForNoTransportOutboundgetTransportSnapshotreadTransportMessagereadTransportTranscriptformatTransportTranscriptresetTransport
alias ความเข้ากันได้ยังคงมีให้สำหรับสถานการณ์ที่มีอยู่ - waitForQaChannelReady, waitForOutboundMessage, waitForNoOutbound, formatConversationTranscript, resetBus - แต่การเขียนสถานการณ์ใหม่ควรใช้ชื่อทั่วไป alias มีอยู่เพื่อหลีกเลี่ยง migration วันเดียวทั้งระบบ ไม่ใช่เพื่อเป็นรูปแบบต่อไปในอนาคต
การรายงาน
qa-lab ส่งออกรายงานโปรโตคอล Markdown จากไทม์ไลน์บัสที่สังเกตได้
รายงานควรตอบว่า:
- สิ่งใดทำงาน
- สิ่งใดล้มเหลว
- สิ่งใดยังคงถูกบล็อก
- สถานการณ์ติดตามผลใดที่ควรเพิ่ม
สำหรับ inventory ของสถานการณ์ที่มีให้ใช้ - มีประโยชน์เมื่อประเมินขนาดงานติดตามผลหรือเชื่อมทรานสปอร์ตใหม่ - ให้รัน pnpm openclaw qa coverage (เพิ่ม --json สำหรับเอาต์พุตที่เครื่องอ่านได้)
เมื่อเลือกหลักฐานเฉพาะจุดสำหรับพฤติกรรมหรือพาธไฟล์ที่ถูกแตะ ให้รัน pnpm openclaw qa coverage --match <query>
รายงาน match จะค้นหา metadata ของสถานการณ์, refs เอกสาร, refs โค้ด, ID ความครอบคลุม, Plugin และข้อกำหนดผู้ให้บริการ จากนั้นพิมพ์เป้าหมาย qa suite --scenario ... ที่ตรงกัน
การรัน qa suite ทุกครั้งจะเขียน artifact ระดับบนสุด qa-evidence.json,
qa-suite-summary.json และ qa-suite-report.md สำหรับชุดสถานการณ์ที่เลือก
สถานการณ์ที่ประกาศ execution.kind: vitest หรือ
execution.kind: playwright จะรันพาธทดสอบที่ตรงกันและเขียน
ล็อกต่อสถานการณ์ด้วย สถานการณ์ที่ประกาศ execution.kind: script จะรัน
ผู้ผลิตหลักฐานที่ execution.path ผ่าน node --import tsx (โดยขยาย
${outputDir} และ ${scenarioId} ใน execution.args); ผู้ผลิตจะเขียน
qa-evidence.json ของตนเอง ซึ่งรายการของมันจะถูกนำเข้าไปยังเอาต์พุต suite
และพาธ artifact ของมันจะถูก resolve โดยสัมพันธ์กับ
qa-evidence.json ของผู้ผลิตนั้น เมื่อเข้าถึง qa suite ผ่าน
qa run --qa-profile ไฟล์ qa-evidence.json เดียวกันจะรวมสรุป scorecard
ของโปรไฟล์สำหรับหมวด taxonomy ที่เลือกด้วย
ให้ถือเป็นตัวช่วยค้นพบ ไม่ใช่ตัวแทนเกต; สถานการณ์ที่เลือกยังต้องใช้โหมดผู้ให้บริการ live transport, Multipass, Testbox หรือเลน release ที่เหมาะสมสำหรับพฤติกรรมที่ทดสอบ
สำหรับบริบท scorecard โปรดดู scorecard วุฒิภาวะ
สำหรับการตรวจสอบอักขระและสไตล์ ให้รันสถานการณ์เดียวกันข้าม ref โมเดล live หลายรายการ และเขียนรายงาน Markdown ที่ผ่านการตัดสิน:
pnpm openclaw qa character-eval \ --model openai/gpt-5.5,thinking=medium,fast \ --model openai/gpt-5.2,thinking=xhigh \ --model openai/gpt-5,thinking=xhigh \ --model anthropic/claude-opus-4-8,thinking=high \ --model anthropic/claude-sonnet-4-6,thinking=high \ --model zai/glm-5.1,thinking=high \ --model moonshot/kimi-k2.5,thinking=high \ --model google/gemini-3.1-pro-preview,thinking=high \ --judge-model openai/gpt-5.5,thinking=xhigh,fast \ --judge-model anthropic/claude-opus-4-8,thinking=high \ --blind-judge-models \ --concurrency 16 \ --judge-concurrency 16คำสั่งนี้รันกระบวนการลูก QA gateway ภายในเครื่อง ไม่ใช่ Docker สถานการณ์ character eval
ควรตั้ง persona ผ่าน SOUL.md แล้วรัน turn ผู้ใช้ปกติ
เช่น แชต ความช่วยเหลือใน workspace และงานไฟล์ขนาดเล็ก ไม่ควรบอกโมเดลผู้สมัคร
ว่ากำลังถูกประเมิน คำสั่งจะเก็บ transcript เต็มแต่ละรายการ
บันทึกสถิติการรันพื้นฐาน จากนั้นถามโมเดลผู้ตัดสินในโหมด fast พร้อม
การให้เหตุผล xhigh เมื่อรองรับ เพื่อจัดอันดับการรันตามความเป็นธรรมชาติ บรรยากาศ และอารมณ์ขัน
ใช้ --blind-judge-models เมื่อเปรียบเทียบผู้ให้บริการ: prompt ผู้ตัดสินยังได้รับ
transcript และสถานะการรันทุกอย่าง แต่ ref ผู้สมัครจะถูกแทนที่ด้วย
ป้ายกำกับเป็นกลาง เช่น candidate-01; รายงานจะ map อันดับกลับไปยัง ref จริงหลัง
การ parse
การรันผู้สมัครตั้งค่าเริ่มต้นเป็น thinking high โดยใช้ medium สำหรับ GPT-5.5 และ xhigh
สำหรับ ref eval ของ OpenAI รุ่นเก่าที่รองรับ Override ผู้สมัครเฉพาะรายแบบ inline ด้วย
--model provider/model,thinking=<level> --thinking <level> ยังคงตั้งค่า
fallback ทั่วโลก และรูปแบบเก่า --model-thinking <provider/model=level> ถูก
เก็บไว้เพื่อความเข้ากันได้
ref ผู้สมัคร OpenAI ตั้งค่าเริ่มต้นเป็นโหมด fast เพื่อให้ใช้ priority processing ในที่ที่
ผู้ให้บริการรองรับ เพิ่ม ,fast, ,no-fast หรือ ,fast=false แบบ inline เมื่อ
ผู้สมัครหรือผู้ตัดสินรายเดียวต้องการ override ส่ง --fast เฉพาะเมื่อคุณต้องการ
บังคับเปิดโหมด fast สำหรับโมเดลผู้สมัครทุกตัว ระยะเวลาของผู้สมัครและผู้ตัดสินจะ
ถูกบันทึกในรายงานเพื่อการวิเคราะห์ benchmark แต่ prompt ผู้ตัดสินระบุอย่างชัดเจน
ว่าอย่าจัดอันดับตามความเร็ว
การรันโมเดลผู้สมัครและผู้ตัดสินต่างมีค่าเริ่มต้น concurrency เป็น 16 ลด
--concurrency หรือ --judge-concurrency เมื่อขีดจำกัดผู้ให้บริการหรือแรงกดดัน
gateway ภายในเครื่องทำให้การรันมีสัญญาณรบกวนมากเกินไป
เมื่อไม่ได้ส่ง --model ผู้สมัคร character eval จะตั้งค่าเริ่มต้นเป็น
openai/gpt-5.5, openai/gpt-5.2, openai/gpt-5, anthropic/claude-opus-4-8,
anthropic/claude-sonnet-4-6, zai/glm-5.1,
moonshot/kimi-k2.5 และ
google/gemini-3.1-pro-preview เมื่อไม่ได้ส่ง --model
เมื่อไม่ได้ส่ง --judge-model ผู้ตัดสินจะตั้งค่าเริ่มต้นเป็น
openai/gpt-5.5,thinking=xhigh,fast และ
anthropic/claude-opus-4-8,thinking=high