Fundamentals
نمای کلی QA
پشته خصوصی QA برای اجرای OpenClaw به شکلی واقعگرایانهتر و مشابه کانال طراحی شده است؛ فراتر از چیزی که یک آزمون واحد میتواند پوشش دهد.
اجزای فعلی:
extensions/qa-channel: کانال پیام مصنوعی با سطوح DM، کانال، رشته، واکنش، ویرایش و حذف.extensions/qa-lab: رابط کاربری اشکالزدایی و گذرگاه QA برای مشاهده رونوشت، تزریق پیامهای ورودی، و خروجی گرفتن گزارش Markdown.extensions/qa-matrix، Pluginهای اجراکننده آینده: آداپترهای انتقال زنده که یک کانال واقعی را داخل یک Gateway فرزند QA هدایت میکنند.qa/: داراییهای seed پشتیبانیشده توسط مخزن برای وظیفه آغازین و سناریوهای پایه QA.- Mantis: راستیآزمایی زنده پیش و پس از رفع باگهایی که به انتقالهای واقعی، نماگرفتهای مرورگر، وضعیت VM، و شواهد PR نیاز دارند.
سطح فرمان
هر جریان QA زیر pnpm openclaw qa <subcommand> اجرا میشود. بسیاری از آنها
نامهای مستعار اسکریپتی pnpm qa:* دارند؛ هر دو شکل پشتیبانی میشوند.
| فرمان | هدف |
|---|---|
qa run |
خودبررسی QA بستهبندیشده بدون --qa-profile؛ اجراکننده پروفایل بلوغ مبتنی بر taxonomy با --qa-profile smoke-ci، --qa-profile release، یا --qa-profile all. |
qa suite |
اجرای سناریوهای پشتیبانیشده توسط مخزن روی مسیر QA gateway. نامهای مستعار: pnpm openclaw qa suite --runner multipass برای یک VM یکبارمصرف Linux. |
qa coverage |
چاپ موجودی پوشش سناریوی YAML (--json برای خروجی ماشینی). |
qa parity-report |
مقایسه دو فایل qa-suite-summary.json و نوشتن گزارش برابری agentic، یا استفاده از --runtime-axis --token-efficiency برای نوشتن گزارشهای برابری runtime و بهرهوری توکن Codex-vs-OpenClaw از یک خلاصه جفت runtime. |
qa character-eval |
اجرای سناریوی QA شخصیت روی چند مدل زنده با گزارش داوریشده. گزارشدهی را ببینید. |
qa manual |
اجرای یک prompt تکموردی روی مسیر provider/model انتخابشده. |
qa ui |
راهاندازی رابط کاربری اشکالزدایی QA و گذرگاه محلی QA (نام مستعار: pnpm qa:lab:ui). |
qa docker-build-image |
ساخت image از پیش آماده Docker برای QA. |
qa docker-scaffold |
نوشتن اسکفلد docker-compose برای داشبورد QA + مسیر gateway. |
qa up |
ساخت سایت QA، راهاندازی پشته پشتیبانیشده با Docker، چاپ URL (نام مستعار: 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 |
مسیر انتقال زنده در برابر یک homeserver یکبارمصرف Tuwunel. Matrix QA را ببینید. |
qa telegram |
مسیر انتقال زنده در برابر یک گروه خصوصی واقعی Telegram. |
qa discord |
مسیر انتقال زنده در برابر یک کانال guild خصوصی واقعی Discord. |
qa slack |
مسیر انتقال زنده در برابر یک کانال خصوصی واقعی Slack. |
qa whatsapp |
مسیر انتقال زنده در برابر حسابهای واقعی WhatsApp Web. |
qa mantis |
اجراکننده راستیآزمایی پیش و پس از رفع برای باگهای انتقال زنده، همراه با شواهد واکنشهای وضعیت Discord، دودسنجی دسکتاپ/مرورگر Crabbox، و دودسنجی Slack-in-VNC. Mantis و راهنمای اجرای دسکتاپ Slack در Mantis را ببینید. |
qa run مبتنی بر پروفایل، عضویت را از taxonomy.yaml میخواند و سپس سناریوهای
حلشده را از طریق qa suite dispatch میکند. --surface و
--category بهجای تعریف مسیرهای جداگانه، پروفایل انتخابشده را فیلتر میکنند.
فایل حاصل qa-evidence.json یک خلاصه scorecard پروفایل با
شمارش دستههای انتخابشده و IDهای پوشش مفقود دارد؛ ورودیهای شواهد جداگانه
همچنان منبع حقیقت برای آزمونها، نقشهای پوشش، و نتایج هستند.
IDهای پوشش قابلیت taxonomy اهداف اثبات دقیق هستند، نه نام مستعار. پوشش
سناریوی اصلی IDهای منطبق را برآورده میکند؛ پوشش ثانویه مشورتی باقی میماند.
IDهای پوشش از فرم نقطهگذاریشده namespace.behavior با بخشهای حروفعددی/خطتیره
کوچک استفاده میکنند؛ IDهای پروفایل، سطح، و دسته همچنان ممکن است از IDهای
taxonomy خطتیرهدار یا نقطهگذاریشده موجود استفاده کنند.
شواهد سبک، execution هر ورودی را حذف میکند و evidenceMode: "slim" را تنظیم میکند؛
smoke-ci بهصورت پیشفرض سبک است، و --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 برای اثبات پروفایل قطعی با providerهای مدل mock و
سرورهای provider محلی Crabline استفاده کنید. از release برای اثبات پایدار/LTS در برابر
کانالهای زنده استفاده کنید. از all فقط برای اجرای صریح شواهد کامل taxonomy استفاده کنید؛ این گزینه
هر دسته بلوغ فعال را انتخاب میکند و میتواند از طریق workflow
QA Profile Evidence با qa_profile=all dispatch شود. وقتی یک فرمان به پروفایل root
OpenClaw هم نیاز دارد، پروفایل root را پیش از فرمان QA قرار دهید:
pnpm openclaw --profile work qa run --qa-profile smoke-ciجریان اپراتور
جریان فعلی اپراتور QA یک سایت QA دوپنجرهای است:
- چپ: داشبورد Gateway (Control UI) با agent.
- راست: QA Lab، نمایشدهنده رونوشت مشابه Slack و برنامه سناریو.
آن را با این فرمان اجرا کنید:
pnpm qa:lab:upاین فرمان سایت QA را میسازد، مسیر gateway پشتیبانیشده با Docker را راهاندازی میکند، و صفحه QA Lab را در دسترس قرار میدهد تا یک اپراتور یا حلقه خودکار بتواند به agent یک ماموریت QA بدهد، رفتار واقعی کانال را مشاهده کند، و ثبت کند چه چیزی کار کرد، شکست خورد، یا مسدود باقی ماند.
برای تکرار سریعتر رابط کاربری QA Lab بدون بازسازی image Docker در هر بار، پشته را با یک بسته QA Lab نصبشده بهصورت bind-mount راهاندازی کنید:
pnpm openclaw qa docker-build-imagepnpm qa:lab:buildpnpm qa:lab:up:fastpnpm qa:lab:watchqa:lab:up:fast سرویسهای Docker را روی یک image از پیش ساخته نگه میدارد و
extensions/qa-lab/web/dist را داخل کانتینر qa-lab بهصورت bind-mount متصل میکند. qa:lab:watch
آن بسته را هنگام تغییر بازسازی میکند، و وقتی hash دارایی QA Lab تغییر کند
مرورگر خودکار بازبارگذاری میشود.
برای یک دودسنجی سیگنال محلی OpenTelemetry، اجرا کنید:
pnpm qa:otel:smokeاین اسکریپت یک دریافتکننده محلی OTLP/HTTP را راهاندازی میکند، سناریوی QA
otel-trace-smoke را با Plugin diagnostics-otel فعال اجرا میکند، سپس بررسی میکند که traceها،
metricها، و logها صادر شده باشند. spanهای trace protobuf صادرشده را decode میکند
و شکل بحرانی برای release را بررسی میکند:
openclaw.run، openclaw.harness.run، یک span فراخوانی مدل با semantic-convention
جدید GenAI، openclaw.context.assembled، و openclaw.message.delivery
باید حاضر باشند. دودسنجی مقدار
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental را اجبار میکند، بنابراین span فراخوانی مدل
باید از نام {gen_ai.operation.name} {gen_ai.request.model} استفاده کند؛
فراخوانیهای مدل در turnهای موفق نباید StreamAbandoned صادر کنند؛ IDهای خام diagnostic و
ویژگیهای openclaw.content.* باید بیرون از trace بمانند. payloadهای خام OTLP
نباید sentinel مربوط به prompt، sentinel مربوط به response، یا کلید session
QA را داشته باشند. این اسکریپت otel-smoke-summary.json را کنار artifactهای مجموعه QA مینویسد.
برای یک دودسنجی OpenTelemetry پشتیبانیشده با collector، اجرا کنید:
pnpm qa:otel:collector-smokeاین مسیر یک کانتینر Docker واقعی OpenTelemetry Collector را جلوی همان دریافتکننده محلی قرار میدهد. هنگام تغییر سیمکشی endpoint، سازگاری collector، یا رفتار صدور OTLP که دریافتکننده درونفرآیندی ممکن است پنهان کند، از آن استفاده کنید.
برای دودسنجی scrape محافظتشده Prometheus، اجرا کنید:
pnpm qa:prometheus:smokeآن نام مستعار سناریوی QA به نام docker-prometheus-smoke را با فعال بودن
diagnostics-prometheus اجرا میکند، تأیید میکند که scrapeهای بدون احراز هویت
رد میشوند، سپس بررسی میکند که scrape احراز هویتشده شامل خانوادههای معیار
حیاتی برای انتشار باشد، بدون محتوای prompt، محتوای پاسخ، شناسههای خام
تشخیصی، توکنهای احراز هویت، یا مسیرهای محلی.
برای اجرای پشتسرهم هر دو smoke مشاهدهپذیری، استفاده کنید از:
pnpm qa:observability:smokeبرای مسیر OpenTelemetry پشتیبانیشده با collector بههمراه smoke مربوط به scrape محافظتشده Prometheus، استفاده کنید از:
pnpm qa:observability:collector-smokeQA مشاهدهپذیری فقط برای source-checkout باقی میماند. tarball مربوط به npm
عمداً QA Lab را حذف میکند، بنابراین مسیرهای انتشار Docker بسته، فرمانهای qa
را اجرا نمیکنند. هنگام تغییر instrumention تشخیصی، از pnpm qa:otel:smoke،
pnpm qa:prometheus:smoke، یا pnpm qa:observability:smoke از یک source checkout
ساختهشده استفاده کنید.
برای یک مسیر smoke واقعی از نظر transport برای Matrix که به credentials ارائهدهنده مدل نیاز ندارد، پروفایل سریع را با ارائهدهنده قطعی mock OpenAI اجرا کنید:
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000 \ pnpm openclaw qa matrix --provider-mode mock-openai --profile fast --fail-fastبرای مسیر ارائهدهنده live-frontier، credentials سازگار با 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 برای این مسیر در QA Matrix قرار دارد. در یک نگاه: یک homeserver دورریختنی Tuwunel را در Docker provision میکند، کاربران موقت driver/SUT/observer را ثبت میکند، Plugin واقعی Matrix را داخل یک Gateway فرزند QA محدود به همان transport اجرا میکند (بدون qa-channel)، سپس یک گزارش Markdown، خلاصه JSON، artifact رویدادهای مشاهدهشده، و لاگ خروجی ترکیبی را زیر .artifacts/qa-e2e/matrix-<timestamp>/ مینویسد.
سناریوها رفتار transport را پوشش میدهند که تستهای واحد نمیتوانند از ابتدا تا انتها اثبات کنند: gating بر اساس mention، سیاستهای allow-bot، allowlistها، پاسخهای سطح بالا و threadشده، مسیریابی DM، مدیریت reaction، سرکوب ویرایش ورودی، حذف تکرار replay پس از restart، بازیابی از وقفه homeserver، تحویل metadata تأیید، مدیریت media، و جریانهای bootstrap/recovery/verification مربوط به Matrix E2EE. پروفایل CLI مربوط به E2EE همچنین openclaw matrix encryption setup و فرمانهای verification را پیش از بررسی پاسخهای Gateway، از طریق همان homeserver دورریختنی اجرا میکند.
Discord همچنین سناریوهای opt-in فقط برای Mantis برای بازتولید باگ دارد. از
--scenario discord-status-reactions-tool-only برای timeline صریح reaction
وضعیت استفاده کنید، یا از --scenario discord-thread-reply-filepath-attachment
برای ایجاد یک thread واقعی Discord و تأیید اینکه message.thread-reply یک پیوست
filePath را حفظ میکند. این سناریوها در مسیر پیشفرض live Discord قرار
نمیگیرند، زیرا بهجای پوشش smoke گسترده، probeهای بازتولید قبل/بعد هستند.
workflow مربوط به thread-attachment در Mantis همچنین میتواند وقتی
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_DIR یا
MANTIS_DISCORD_VIEWER_CHROME_PROFILE_TGZ_B64 در محیط QA پیکربندی شده باشد،
یک ویدیوی شاهد Discord Web با کاربر واردشده اضافه کند. آن پروفایل viewer فقط
برای capture بصری است؛ تصمیم pass/fail همچنان از oracle مربوط به Discord REST
میآید.
CI از همان سطح فرمان در .github/workflows/qa-live-transports-convex.yml استفاده میکند.
اجراهای زمانبندیشده و دستی پیشفرض، پروفایل سریع Matrix را با credentials
live-frontier ارائهشده توسط QA، --fast، و
OPENCLAW_QA_MATRIX_NO_REPLY_WINDOW_MS=3000 اجرا میکنند. اجرای دستی
matrix_profile=all به پنج shard پروفایل fan out میشود.
برای مسیرهای smoke واقعی از نظر transport برای Telegram، Discord، Slack، و WhatsApp:
pnpm openclaw qa telegrampnpm openclaw qa discordpnpm openclaw qa slackpnpm openclaw qa whatsappآنها یک کانال واقعی از پیش موجود را با دو ربات یا حساب هدف میگیرند (driver + SUT). env vars لازم، فهرست سناریوها، artifactهای خروجی، و pool credential مربوط به Convex در مرجع QA برای Telegram، Discord، Slack، و WhatsApp در پایین مستند شدهاند.
برای اجرای کامل VM دسکتاپ Slack با نجات VNC، اجرا کنید:
pnpm openclaw qa mantis slack-desktop-smoke \ --gateway-setup \ --scenario slack-canary \ --keep-leaseآن فرمان یک ماشین دسکتاپ/مرورگر Crabbox را lease میکند، مسیر live Slack را
داخل VM اجرا میکند، Slack Web را در مرورگر VNC باز میکند، دسکتاپ را capture
میکند، و وقتی video capture در دسترس باشد، slack-qa/،
slack-desktop-smoke.png، و slack-desktop-smoke.mp4 را به دایرکتوری artifact
مربوط به Mantis کپی میکند. leaseهای دسکتاپ/مرورگر Crabbox ابزارهای capture و
بستههای helper مربوط به browser/native-build را از ابتدا فراهم میکنند، بنابراین
سناریو فقط باید روی leaseهای قدیمیتر fallbackها را نصب کند. Mantis زمانبندی
کلی و بهازای هر فاز را در mantis-slack-desktop-smoke-report.md گزارش میکند
تا اجراهای کند نشان دهند زمان صرف warmup lease، دریافت credential، setup remote،
یا کپی artifact شده است. پس از ورود دستی به Slack Web از طریق VNC، از
--lease-id <cbx_...> دوباره استفاده کنید؛ leaseهای استفادهمجددشده همچنین cache
فروشگاه pnpm مربوط به Crabbox را گرم نگه میدارند. مقدار پیشفرض
--hydrate-mode source از یک source checkout تأیید میکند و install/build را
داخل VM اجرا میکند. از --hydrate-mode prehydrated فقط وقتی استفاده کنید که
workspace remote استفادهمجددشده از قبل node_modules و dist/ ساختهشده دارد؛
آن حالت گام پرهزینه install/build را رد میکند و وقتی workspace آماده نباشد
fail closed میشود. با --gateway-setup، Mantis یک Gateway پایدار OpenClaw Slack
را داخل VM روی پورت 38973 در حال اجرا باقی میگذارد؛ بدون آن، فرمان مسیر عادی
QA Slack ربات-به-ربات را اجرا میکند و پس از capture کردن artifact خارج میشود.
برای اثبات UI تأیید native Slack با شواهد دسکتاپ، حالت checkpoint تأیید Mantis را اجرا کنید:
pnpm openclaw qa mantis slack-desktop-smoke \ --approval-checkpoints \ --credential-source convex \ --credential-role maintainerاین حالت با --gateway-setup ناسازگار است. سناریوهای تأیید Slack را اجرا میکند،
شناسههای سناریوی غیرتأیید را رد میکند، در هر وضعیت تأیید pending و resolved
منتظر میماند، پیام مشاهدهشده Slack API را در
approval-checkpoints/<scenario>-pending.png و
approval-checkpoints/<scenario>-resolved.png render میکند، سپس اگر هر checkpoint،
شاهد پیام، acknowledgement، یا screenshot رندرشده گمشده یا خالی باشد شکست
میخورد. leaseهای سرد CI ممکن است همچنان sign-in Slack را در
slack-desktop-smoke.png نشان دهند؛ تصویرهای checkpoint تأیید، اثبات بصری این
مسیر هستند.
چکلیست operator، فرمان dispatch مربوط به GitHub workflow، قرارداد evidence-comment، جدول تصمیم hydrate-mode، تفسیر timing، و گامهای مدیریت failure در Runbook دسکتاپ Slack برای Mantis قرار دارند.
برای یک task دسکتاپ به سبک agent/CV، اجرا کنید:
pnpm openclaw qa mantis visual-task \ --browser-url https://example.net \ --expect-text "Example Domain" \ --vision-model openai/gpt-5.5visual-task یک ماشین دسکتاپ/مرورگر Crabbox را lease یا دوباره استفاده میکند،
crabbox record --while را شروع میکند، مرورگر قابل مشاهده را از طریق یک
visual-driver تودرتو هدایت میکند، visual-task.png را capture میکند، وقتی
--vision-mode image-describe انتخاب شده باشد openclaw infer image describe
را روی screenshot اجرا میکند، و visual-task.mp4،
mantis-visual-task-summary.json، mantis-visual-task-driver-result.json، و
mantis-visual-task-report.md را مینویسد. وقتی --expect-text تنظیم شده باشد،
prompt بینایی یک verdict ساختیافته JSON میخواهد و فقط وقتی pass میشود که مدل
شواهد قابل مشاهده مثبت گزارش کند؛ پاسخ منفیای که صرفاً متن هدف را نقل میکند
assertion را fail میکند. از --vision-mode metadata برای smoke بدون مدل استفاده
کنید که بدون فراخوانی یک ارائهدهنده فهم تصویر، plumbing دسکتاپ، مرورگر،
screenshot، و ویدیو را اثبات میکند. Recording یک artifact الزامی برای
visual-task است؛ اگر Crabbox هیچ visual-task.mp4 غیرخالی ضبط نکند، task حتی
وقتی visual driver pass شده باشد fail میشود. هنگام failure، Mantis lease را
برای VNC نگه میدارد مگر اینکه task قبلاً pass شده باشد و --keep-lease تنظیم
نشده باشد.
پیش از استفاده از credentials زنده pooled، اجرا کنید:
pnpm openclaw qa credentials doctordoctor محیط broker مربوط به Convex را بررسی میکند، تنظیمات endpoint را اعتبارسنجی میکند، و وقتی secret maintainer حاضر باشد، دسترسیپذیری admin/list را تأیید میکند. برای secrets فقط وضعیت set/missing را گزارش میکند.
پوشش transport زنده
مسیرهای transport زنده بهجای اینکه هرکدام شکل فهرست سناریوی خود را اختراع کنند،
یک قرارداد مشترک دارند. qa-channel مجموعه synthetic گسترده رفتار محصول است و
بخشی از ماتریس پوشش transport زنده نیست.
runnerهای transport زنده باید شناسههای سناریوی مشترک، helperهای پوشش baseline،
و helper انتخاب سناریو را از openclaw/plugin-sdk/qa-live-transport-scenarios
| مسیر | Canary | gating بر اساس mention | ربات-به-ربات | بلوک allowlist | پاسخ سطح بالا | پاسخ quote | ادامه پس از restart | follow-up در thread | جداسازی thread | مشاهده reaction | فرمان help | ثبت فرمان native |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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 را بهعنوان مجموعه گسترده رفتار محصول نگه میدارد، درحالیکه
Matrix، Telegram، و دیگر transportهای زنده یک چکلیست صریح مشترک برای قرارداد
transport دارند.
برای یک مسیر VM دورریختنی Linux بدون آوردن Docker به مسیر QA، اجرا کنید:
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baselineاین فرمان یک guest تازه Multipass را boot میکند، وابستگیها را نصب میکند،
OpenClaw را داخل guest میسازد، qa suite را اجرا میکند، سپس گزارش و خلاصه
عادی QA را به .artifacts/qa-e2e/... روی host برمیگرداند.
این همان رفتار انتخاب سناریو را که qa suite روی host دارد دوباره استفاده میکند.
اجراهای suite روی host و Multipass بهصورت پیشفرض چندین سناریوی انتخابشده را با
workerهای Gateway ایزوله بهصورت موازی اجرا میکنند. qa-channel بهصورت پیشفرض
concurrency برابر 4 دارد که با تعداد سناریوهای انتخابشده محدود میشود. برای
تنظیم تعداد worker از --concurrency <count> استفاده کنید، یا برای اجرای serial
از --concurrency 1 استفاده کنید.
برای اجرای pack benchmark دستیار شخصی از --pack personal-agent استفاده کنید.
selector مربوط به pack با flagهای تکرارشده --scenario افزایشی است: ابتدا
سناریوهای صریح اجرا میشوند، سپس سناریوهای pack به ترتیب pack با حذف موارد
تکراری اجرا میشوند.
وقتی یک runner سفارشی QA از قبل setup مربوط به OpenTelemetry collector را فراهم
میکند و میخواهد سناریوهای smoke تشخیصی OpenTelemetry و Prometheus باهم انتخاب
شوند، از --pack observability استفاده کنید.
وقتی هر سناریویی fail شود، فرمان با non-zero خارج میشود. وقتی artifactها را
بدون exit code شکستخورده میخواهید، از --allow-failures استفاده کنید.
اجراهای live ورودیهای پشتیبانیشده auth مربوط به QA را که برای guest عملی
هستند forward میکنند: کلیدهای provider مبتنی بر env، مسیر پیکربندی provider
زنده QA، و وقتی حاضر باشد CODEX_HOME. --output-dir را زیر ریشه repo نگه دارید
تا guest بتواند از طریق workspace mountشده به host بنویسد.
مرجع 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> |
محل نوشتن گزارشها، خلاصهها، شواهد، مصنوعات ویژه ترابری، و لاگ خروجی. مسیرهای نسبی نسبت به --repo-root حل میشوند. |
--repo-root <path> |
process.cwd() |
ریشه مخزن هنگام فراخوانی از یک cwd خنثی. |
--sut-account <id> |
sut |
شناسه حساب موقت داخل پیکربندی QA gateway. |
--provider-mode <mode> |
live-frontier |
mock-openai یا live-frontier (live-openai قدیمی همچنان کار میکند). |
--model <ref> / --alt-model <ref> |
پیشفرض provider | ارجاعهای مدل اصلی/جایگزین. |
--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 داشته باشد؛ مشاهده باتبهبات زمانی بهترین عملکرد را دارد که هر دو بات Bot-to-Bot Communication Mode را در @BotFather فعال کرده باشند.
env لازم هنگام --credential-source env:
OPENCLAW_QA_TELEGRAM_GROUP_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، پاسخهای فرمان native، آدرسدهی فرمان، و پاسخهای گروهی باتبهبات را پوشش میدهد. پیشفرضهای mock-openai همچنین بررسیهای قطعی زنجیره پاسخ و جریاندهی پیام نهایی را شامل میشوند. telegram-current-session-status-tool همچنان opt-in میماند، چون فقط وقتی مستقیماً پس از canary رشتهبندی شود پایدار است، نه پس از پاسخهای دلخواه فرمان native. برای چاپ تفکیک پیشفرض/اختیاری فعلی همراه با ارجاعهای رگرسیون از pnpm openclaw qa telegram --list-scenarios --provider-mode mock-openai استفاده کنید.
مصنوعات خروجی:
telegram-qa-report.mdqa-evidence.json- مدخلهای شواهد برای بررسیهای ترابری زنده، شامل فیلدهای پروفایل، پوشش، provider، کانال، مصنوعات، نتیجه، و RTT.
اجراهای بسته Telegram از همان قرارداد اعتبارنامه Telegram استفاده میکنند. اندازهگیری تکرارشونده RTT بخشی از مسیر زنده عادی بسته Telegram است؛ توزیع RTT برای بررسی RTT انتخابشده در qa-evidence.json زیر result.timing ادغام میشود.
OPENCLAW_QA_CREDENTIAL_SOURCE=convex \pnpm test:docker:npm-telegram-liveوقتی OPENCLAW_QA_CREDENTIAL_SOURCE=convex تنظیم شده باشد، wrapper زنده بسته یک اعتبارنامه kind: "telegram" را lease میکند، env مربوط به گروه/driver/SUT bot اجارهشده را به اجرای بسته نصبشده صادر میکند، lease را Heartbeat میکند، و هنگام خاموشی آن را آزاد میکند. wrapper بسته بهطور پیشفرض، خارج از CI و هنگام انتخاب Convex، ۲۰ بررسی RTT از telegram-mentioned-message-reply، مهلت RTT برابر ۳۰ ثانیه، و نقش Convex برابر maintainer دارد. برای تنظیم اندازهگیری RTT بدون ایجاد فرمان RTT جداگانه یا قالب خلاصه ویژه Telegram، OPENCLAW_NPM_TELEGRAM_RTT_SAMPLES، OPENCLAW_NPM_TELEGRAM_RTT_TIMEOUT_MS، یا OPENCLAW_NPM_TELEGRAM_RTT_MAX_FAILURES را override کنید.
QA برای Discord
pnpm openclaw qa discordیک کانال guild خصوصی واقعی Discord را با دو بات هدف میگیرد: یک بات driver که توسط harness کنترل میشود و یک بات SUT که توسط gateway فرزند OpenClaw از طریق Plugin همراه Discord راهاندازی میشود. مدیریت mention کانال، ثبت فرمان native /help توسط بات SUT در 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- باید با شناسه کاربر بات SUT که Discord برمیگرداند مطابقت داشته باشد (در غیر این صورت مسیر سریعاً شکست میخورد).
اختیاری:
OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1بدنه پیامها را در مصنوعات پیام مشاهدهشده نگه میدارد.OPENCLAW_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- سناریوی voice بهصورت opt-in. بهتنهایی اجرا میشود،channels.discord.voice.autoJoinرا فعال میکند، و تأیید میکند که وضعیت voice فعلی بات SUT در Discord همان کانال voice/stage هدف است. اعتبارنامههای Discord در Convex ممکن استvoiceChannelIdاختیاری داشته باشند؛ در غیر این صورت runner اولین کانال voice/stage قابلمشاهده در guild را کشف میکند.discord-status-reactions-tool-only- سناریوی Mantis بهصورت opt-in. بهتنهایی اجرا میشود چون SUT را باmessages.statusReactions.enabled=trueبه پاسخهای guild همیشهروشن و فقطابزار تغییر میدهد، سپس یک خط زمانی reaction از REST بههمراه مصنوعات بصری HTML/PNG را ضبط میکند. گزارشهای قبل/بعد Mantis همچنین مصنوعات MP4 ارائهشده توسط سناریو را بهصورتbaseline.mp4وcandidate.mp4حفظ میکنند.
سناریوی اتصال خودکار voice در Discord را صریحاً اجرا کنید:
pnpm openclaw qa discord \ --scenario discord-voice-autojoin \ --provider-mode mock-openaiسناریوی status-reaction در Mantis را صریحاً اجرا کنید:
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- مدخلهای شواهد برای بررسیهای ترابری زنده.discord-qa-observed-messages.json- بدنهها redact میشوند مگر اینکهOPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1باشد.discord-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 راهاندازی میشود.
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بدنه پیامها را در مصنوعات پیام مشاهدهشده نگه میدارد.OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIRcheckpointهای تأیید بصری را برای Mantis فعال میکند. runner فایلهای<scenario>.pending.jsonو<scenario>.resolved.jsonرا مینویسد، سپس منتظر فایلهای.ack.jsonمطابق میماند.OPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_TIMEOUT_MSمهلت acknowledgment برای checkpoint را override میکند. پیشفرض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- سناریوی opt-in برای تأیید exec بومی Slack. یک تأیید exec را از طریق gateway درخواست میکند، تأیید میکند پیام Slack دکمههای تأیید native دارد، آن را resolve میکند، و بهروزرسانی Slack resolveشده را تأیید میکند.slack-approval-plugin-native- سناریوی opt-in برای تأیید Plugin بومی Slack. ارسال تأیید exec و Plugin را با هم فعال میکند تا رویدادهای Plugin توسط مسیریابی تأیید exec سرکوب نشوند، سپس همان مسیر UI بومی Slack در حالت pending/resolved را تأیید میکند.
مصنوعات خروجی:
slack-qa-report.mdqa-evidence.json- مدخلهای شواهد برای بررسیهای ترابری زنده.slack-qa-observed-messages.json- بدنهها redact میشوند مگر اینکهOPENCLAW_QA_SLACK_CAPTURE_CONTENT=1باشد.approval-checkpoints/- فقط وقتی Mantis مقدارOPENCLAW_QA_SLACK_APPROVAL_CHECKPOINT_DIRرا تنظیم کند؛ شامل JSON مربوط به checkpoint، JSON مربوط به acknowledgment، و نماگرفتهای pending/resolved است.
راهاندازی فضای کاری Slack
این مسیر به دو اپ Slack متمایز در یک workspace نیاز دارد، بههمراه کانالی که هر دو بات عضو آن باشند:
channelId- شناسهCxxxxxxxxxxکانالی که هر دو بات به آن دعوت شدهاند. از یک کانال اختصاصی استفاده کنید؛ این مسیر در هر اجرا در آن پست میگذارد.driverBotToken- توکن بات (xoxb-...) برای اپ Driver.sutBotToken- توکن بات (xoxb-...) برای اپ SUT، که باید از اپ Slack مربوط به driver جدا باشد تا شناسه کاربر بات آن متمایز باشد.sutAppToken- توکن سطح اپ (xapp-...) برای اپ SUT باconnections:write، که توسط Socket Mode استفاده میشود تا اپ SUT بتواند رویدادها را دریافت کند.
یک workspace اختصاصی Slack برای QA را به استفاده مجدد از workspace تولید ترجیح دهید.
manifest مربوط به SUT در زیر عمداً نصب تولیدی Plugin همراه Slack (extensions/slack/src/setup-shared.ts:10) را به مجوزها و رویدادهایی که مجموعه QA زنده Slack پوشش میدهد محدود میکند. برای راهاندازی کانال تولید همانطور که کاربران میبینند، راهاندازی سریع کانال Slack را ببینید؛ جفت QA Driver/SUT عمداً جداست چون این مسیر به دو شناسه کاربر بات متمایز در یک workspace نیاز دارد.
۱. اپ Driver را ایجاد کنید
به api.slack.com/apps بروید → ایجاد برنامه جدید → از یک manifest → فضای کاری QA را انتخاب کنید، manifest زیر را بچسبانید، سپس نصب در فضای کاری را بزنید:
{ "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 تبدیل میشود. درایور فقط باید پیامها را ارسال کند و خودش را شناسایی کند؛ بدون رویدادها، بدون Socket Mode.
۲. برنامه SUT را ایجاد کنید
در همان فضای کاری، ایجاد برنامه جدید → از یک manifest را تکرار کنید. این برنامه QA عمدا از نسخه محدودتری از manifest تولیدی Plugin همراه Slack (extensions/slack/src/setup-shared.ts:10) استفاده میکند: scopeها و رویدادهای واکنش حذف شدهاند، چون مجموعه QA زنده Slack هنوز مدیریت واکنش را پوشش نمیدهد.
{ "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 برنامه را ایجاد کرد، در صفحه تنظیمات آن دو کار انجام دهید:
- نصب در فضای کاری → Bot User OAuth Token را کپی کنید → این مقدار به
sutBotTokenتبدیل میشود. - اطلاعات پایه → توکنهای سطح برنامه → تولید توکن و scopeها → scope
connections:writeرا اضافه کنید → ذخیره کنید → مقدارxapp-...را کپی کنید → این مقدار بهsutAppTokenتبدیل میشود.
با فراخوانی auth.test روی هر توکن، تأیید کنید که دو بات شناسههای کاربری متمایز دارند. runtime درایور و SUT را با شناسه کاربر تشخیص میدهد؛ استفاده مجدد از یک برنامه برای هر دو، mention-gating را بلافاصله ناموفق میکند.
۳. کانال را ایجاد کنید
در فضای کاری QA، یک کانال بسازید (مثلا #openclaw-qa) و هر دو بات را از داخل کانال دعوت کنید:
/invite @OpenClaw QA Driver/invite @OpenClaw QA SUTشناسه Cxxxxxxxxxx را از اطلاعات کانال → درباره → Channel ID کپی کنید - این مقدار به channelId تبدیل میشود. یک کانال عمومی کافی است؛ اگر از کانال خصوصی استفاده کنید، هر دو برنامه از قبل groups:history دارند، بنابراین خواندنهای تاریخچه harness همچنان موفق میشوند.
۴. اعتبارنامهها را ثبت کنید
دو گزینه وجود دارد. برای اشکالزدایی روی یک ماشین از env varها استفاده کنید (چهار متغیر OPENCLAW_QA_SLACK_* را تنظیم کنید و --credential-source env را پاس دهید)، یا pool مشترک Convex را seed کنید تا CI و سایر نگهدارندگان بتوانند آنها را lease کنند.
برای pool Convex، چهار فیلد را در یک فایل 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 را داشته باشید.
۵. انتها به انتها تأیید کنید
lane را بهصورت محلی اجرا کنید تا تأیید شود هر دو بات میتوانند از طریق broker با یکدیگر صحبت کنند:
pnpm openclaw qa slack \ --credential-source convex \ --credential-role maintainer \ --output-dir .artifacts/qa-e2e/slack-localیک اجرای سبز در بسیار کمتر از ۳۰ ثانیه کامل میشود و slack-qa-report.md هر دو slack-canary و slack-mention-gating را با وضعیت pass نشان میدهد. اگر lane حدود ۹۰ ثانیه گیر کند و با Convex credential pool exhausted for kind "slack" خارج شود، یا pool خالی است یا همه ردیفها lease شدهاند - qa credentials list --kind slack --status all --json به شما میگوید کدامیک است.
QA WhatsApp
pnpm openclaw qa whatsappدو حساب اختصاصی WhatsApp Web را هدف میگیرد: یک حساب درایور که توسط harness کنترل میشود و یک حساب SUT که توسط Gateway فرزند OpenClaw از طریق Plugin همراه WhatsApp شروع میشود.
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-pending-history-context،whatsapp-broadcast-group-fanout،whatsapp-group-activation-always،whatsapp-group-reply-to-bot-triggers، سناریوهای کنش/رسانه/نظرسنجی گروه، وwhatsapp-group-allowlist-blockرا فعال میکند.OPENCLAW_QA_WHATSAPP_CAPTURE_CONTENT=1بدنه پیامها را در artifactهای observed-message نگه میدارد.
کاتالوگ سناریو (extensions/qa-lab/src/live-transports/whatsapp/whatsapp-live.runtime.ts):
- baseline و gating گروه:
whatsapp-canary،whatsapp-pairing-block،whatsapp-mention-gating،whatsapp-group-pending-history-context،whatsapp-group-activation-always،whatsapp-group-reply-to-bot-triggers،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. - رفتار پاسخ و خروجی نهایی:
whatsapp-tool-only-usage-footer،whatsapp-reply-to-message،whatsapp-group-reply-to-message،whatsapp-reply-to-mode-batched،whatsapp-reply-context-isolation،whatsapp-reply-delivery-shape،whatsapp-stream-final-message-accounting. - کنشهای پیام در مسیر کاربر:
whatsapp-agent-message-action-reactاز یک DM واقعی درایور شروع میشود، اجازه میدهد مدل ابزارmessageرا فراخوانی کند، و واکنش native WhatsApp را مشاهده میکند.whatsapp-agent-message-action-upload-fileاز همان posture برایmessage(action=upload-file)استفاده میکند و رسانه native WhatsApp را مشاهده میکند.whatsapp-group-agent-message-action-reactوwhatsapp-group-agent-message-action-upload-fileهمان کنشهای قابل مشاهده برای کاربر را در یک گروه واقعی WhatsApp اثبات میکنند. - fanout گروه:
whatsapp-broadcast-group-fanoutاز یک پیام گروه WhatsApp که mention شده شروع میشود و پاسخهای قابل مشاهده متمایز ازmainوqa-secondرا تأیید میکند. - فعالسازی گروه:
whatsapp-group-activation-alwaysیک session گروه واقعی را به/activation alwaysتغییر میدهد، اثبات میکند که یک پیام گروهی بدون mention agent را بیدار میکند، سپس/activation mentionرا بازمیگرداند.whatsapp-group-reply-to-bot-triggersیک پاسخ بات را seed میکند، یک پاسخ native نقلقولشده به آن را بدون mention صریح میفرستد، و تأیید میکند که agent از آن context پاسخ بیدار میشود. - رسانه ورودی و پیامهای ساختیافته:
whatsapp-inbound-image-caption،whatsapp-audio-preflight،whatsapp-inbound-structured-messages،whatsapp-group-audio-gating،whatsapp-inbound-reaction-no-trigger. اینها رویدادهای واقعی تصویر، صوت، سند، مکان، مخاطب، استیکر، و واکنش WhatsApp را از طریق درایور ارسال میکنند. - probeهای مستقیم قرارداد Gateway:
whatsapp-outbound-media-matrix،whatsapp-outbound-document-preserves-filename،whatsapp-outbound-poll،whatsapp-group-outbound-media،whatsapp-group-outbound-poll،whatsapp-message-actions،whatsapp-reply-context-isolation،whatsapp-reply-delivery-shape. اینها عمدا model prompting را دور میزنند و قراردادهای قطعی Gateway/channel برایsend،poll، وmessage.actionرا اثبات میکنند. - پوشش کنترل دسترسی:
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-exec-group-reaction-native،whatsapp-approval-plugin-native. - واکنشهای وضعیت:
whatsapp-status-reactions،whatsapp-status-reaction-lifecycle.
کاتالوگ در حال حاضر شامل ۵۰ سناریو است. lane پیشفرض live-frontier برای
پوشش smoke سریع، با ۱۰ سناریو کوچک نگه داشته شده است. lane پیشفرض mock-openai
۴۴ سناریوی قطعی را از طریق transport واقعی WhatsApp اجرا میکند و
فقط خروجی مدل را mock میکند. سناریوهای تأییدیه و چند بررسی سنگینتر/مسدودکننده
همچنان با شناسه سناریو صریح باقی میمانند.
درایور QA WhatsApp رویدادهای زنده ساختیافته (text، media،
location، reaction، و poll) را مشاهده میکند و میتواند بهصورت فعال رسانه، نظرسنجی،
مخاطب، مکان، و استیکر ارسال کند. QA Lab آن درایور را از طریق
سطح پکیج @openclaw/whatsapp/api.js وارد میکند، نه با دسترسی به فایلهای خصوصی
runtime WhatsApp. برای مشاهدههای گروهی، fromJid همان JID گروه است، در حالی که
participantJid و fromPhoneE164 فرستنده شرکتکننده را شناسایی میکنند. محتوای پیام
بهصورت پیشفرض redact میشود. probeهای مستقیم Gateway برای
نظرسنجی، upload-file، رسانه، نظرسنجی گروه، رسانه گروه، و reply-shape بررسیهای قرارداد transport/API
هستند؛ آنها بهعنوان اثباتی در نظر گرفته نمیشوند که یک prompt کاربر باعث شده agent
همان کنش را انتخاب کند. اثبات کنش در مسیر کاربر از سناریوهایی مانند
whatsapp-agent-message-action-react و
whatsapp-group-agent-message-action-react میآید، جایی که درایور یک پیام عادی
WhatsApp میفرستد و QA Lab artifact native WhatsApp حاصل را مشاهده میکند.
گزارشهای WhatsApp شامل posture هر سناریو (user-path، direct-gateway،
یا native-approval) هستند تا شواهد با قراردادی قویتر از آنچه واقعا اثبات میکنند
اشتباه گرفته نشوند.
artifactهای خروجی:
whatsapp-qa-report.mdqa-evidence.json- مدخلهای شواهد برای بررسیهای transport زنده.whatsapp-qa-observed-messages.json- بدنهها redact میشوند مگر اینکهOPENCLAW_QA_WHATSAPP_CAPTURE_CONTENT=1باشد.
pool اعتبارنامه Convex
laneهای Telegram، Discord، Slack، و WhatsApp میتوانند بهجای خواندن env varهای بالا، اعتبارنامهها را از یک pool مشترک Convex lease کنند. --credential-source convex را پاس دهید (یا OPENCLAW_QA_CREDENTIAL_SOURCE=convex را تنظیم کنید)؛ QA Lab یک lease انحصاری میگیرد، در طول اجرا برای آن Heartbeat میزند، و هنگام shutdown آن را آزاد میکند. kindهای 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. مسیرهای عمومی QA Lab نباید این نوع را دریافت کنند. - 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 یک اجارهٔ انحصاری Convex
telegram-user را هم برای درایور CLI مربوط به TDLib و هم برای شاهد
Telegram Desktop نگه میدارد، سپس پس از انتشار اثبات آن را آزاد میکند.
وقتی یک PR به diff بصری قطعی نیاز دارد، Mantis میتواند از همان پاسخ مدل
ساختگی روی main و روی سرشاخهٔ PR استفاده کند، در حالی که قالببند Telegram یا
لایهٔ تحویل تغییر میکند. پیشفرضهای ضبط برای کامنتهای PR تنظیم شدهاند: کلاس
استاندارد Crabbox، ضبط دسکتاپ با 24fps، GIF حرکتی با 24fps، و عرض پیشنمایش
1920px. کامنتهای قبل/بعد باید یک بستهٔ تمیز منتشر کنند که فقط GIFهای موردنظر
را شامل میشود.
مسیرهای Slack نیز میتوانند از مخزن استفاده کنند. بررسیهای شکل payload در Slack در حال حاضر بهجای broker در اجراگر QA مربوط به Slack قرار دارند؛ از { channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string } استفاده کنید، با یک شناسهٔ کانال Slack مانند Cxxxxxxxxxx. برای تأمین app و scope، راهاندازی فضای کاری Slack را ببینید.
متغیرهای محیطی عملیاتی و قرارداد endpoint مربوط به broker در Convex در آزمایش → اعتبارنامههای مشترک Telegram از طریق Convex قرار دارند (نام بخش پیش از مخزن چندکاناله است؛ معنای اجاره در همهٔ نوعها مشترک است).
seedهای متکی به مخزن
داراییهای seed در qa/ قرار دارند:
qa/scenarios/index.yamlqa/scenarios/<theme>/*.yaml
اینها عمداً در git هستند تا طرح QA هم برای انسانها و هم برای agent قابل مشاهده باشد.
qa-lab باید یک اجراگر عمومی سناریوهای YAML باقی بماند. هر فایل YAML سناریو
منبع حقیقت برای یک اجرای آزمون است و باید این موارد را تعریف کند:
titleدر سطح بالا- metadata مربوط به
scenario - metadata اختیاری category، capability، lane، و risk در
scenario - ارجاعهای docs و code در
scenario - نیازمندیهای اختیاری Plugin در
scenario - patch اختیاری پیکربندی Gateway در
scenario flowاجرایی در سطح بالا برای سناریوهای flow، یاscenario.execution.kind/scenario.execution.pathبرای سناریوهای Vitest و Playwright
سطح runtime قابل استفادهٔ مجدد که پشتوانهٔ flow است مجاز است عمومی
و cross-cutting باقی بماند. برای مثال، سناریوهای YAML میتوانند helperهای سمت
انتقال را با helperهای سمت مرورگر ترکیب کنند که Control UI جاسازیشده را از طریق
درز browser.request در Gateway هدایت میکنند، بدون اینکه اجراگر حالت خاص اضافه شود.
فایلهای سناریو باید بر اساس قابلیت محصول گروهبندی شوند، نه پوشهٔ درخت
source. هنگام جابهجایی فایلها، شناسههای سناریو را پایدار نگه دارید؛ برای
قابلیت ردیابی پیادهسازی از docsRefs و codeRefs استفاده کنید.
فهرست baseline باید بهاندازهای گسترده بماند که این موارد را پوشش دهد:
- گفتوگوی DM و کانال
- رفتار thread
- چرخهٔ عمر action پیام
- callbackهای Cron
- یادآوری memory
- تعویض مدل
- تحویل به subagent
- خواندن مخزن و خواندن docs
- یک task کوچک build مانند Lobster Invaders
مسیرهای mock ارائهدهنده
qa suite دو مسیر mock محلی برای ارائهدهنده دارد:
mock-openaimock سناریوآگاه OpenClaw است. این مسیر، مسیر mock قطعی پیشفرض برای QA متکی به مخزن و gateهای parity باقی میماند.aimockیک سرور ارائهدهندهٔ مبتنی بر AIMock را برای پوشش آزمایشی protocol، fixture، record/replay، و chaos راهاندازی میکند. این مسیر افزایشی است و جایگزین dispatcher سناریویmock-openaiنمیشود.
پیادهسازی مسیرهای ارائهدهنده زیر extensions/qa-lab/src/providers/ قرار دارد.
هر ارائهدهنده مالک پیشفرضها، راهاندازی سرور محلی، پیکربندی مدل Gateway،
نیازهای staging مربوط به auth-profile، و flagهای قابلیت live/mock خودش است. کد
مشترک suite و Gateway باید بهجای شاخهزدن بر اساس نام ارائهدهندهها، از طریق
رجیستری ارائهدهنده مسیریابی کند.
adapterهای انتقال
qa-lab مالک یک درز انتقال عمومی برای سناریوهای QA در YAML است. qa-channel
پیشفرض synthetic است. crabline سرورهای محلی با شکل ارائهدهنده را راهاندازی
میکند و Pluginهای کانال معمول OpenClaw را در برابر آنها اجرا میکند. live
برای اعتبارنامههای واقعی ارائهدهنده و کانالهای خارجی رزرو شده است.
در سطح معماری، این تفکیک چنین است:
qa-labمالک اجرای عمومی سناریو، همزمانی worker، نوشتن artifact، و گزارشدهی است.- adapter انتقال مالک پیکربندی Gateway، آمادگی، مشاهدهٔ ورودی و خروجی، actionهای انتقال، و وضعیت نرمالشدهٔ انتقال است.
- فایلهای سناریوی YAML زیر
qa/scenarios/اجرای آزمون را تعریف میکنند؛qa-labسطح runtime قابل استفادهٔ مجددی را فراهم میکند که آنها را اجرا میکند.
افزودن کانال
افزودن یک کانال به سیستم QA مبتنی بر YAML به پیادهسازی کانال بهعلاوهٔ
یک بستهٔ سناریو نیاز دارد که قرارداد کانال را تمرین کند. برای پوشش smoke در CI،
سرور ارائهدهندهٔ محلی Crabline متناظر را اضافه کنید و آن را از طریق درایور
crabline در دسترس قرار دهید.
وقتی میزبان مشترک qa-lab میتواند مالک flow باشد، یک ریشهٔ فرمان QA جدید در سطح بالا اضافه نکنید.
qa-lab مالک سازوکارهای میزبان مشترک است:
- ریشهٔ فرمان
openclaw qa - راهاندازی و teardown مجموعه
- همزمانی worker
- نوشتن artifact
- تولید گزارش
- اجرای سناریو
- aliasهای سازگاری برای سناریوهای قدیمیتر
qa-channel
Pluginهای runner مالک قرارداد انتقال هستند:
- اینکه
openclaw qa <runner>چگونه زیر ریشهٔ مشترکqamount میشود - اینکه Gateway چگونه برای آن انتقال پیکربندی میشود
- اینکه آمادگی چگونه بررسی میشود
- اینکه رویدادهای ورودی چگونه تزریق میشوند
- اینکه پیامهای خروجی چگونه مشاهده میشوند
- اینکه transcriptها و وضعیت نرمالشدهٔ انتقال چگونه در معرض استفاده قرار میگیرند
- اینکه actionهای متکی بر انتقال چگونه اجرا میشوند
- اینکه reset یا cleanup اختصاصی انتقال چگونه مدیریت میشود
حداقل معیار پذیرش برای یک کانال جدید:
qa-labرا بهعنوان مالک ریشهٔ مشترکqaنگه دارید.- transport runner را روی درز میزبان مشترک
qa-labپیادهسازی کنید. - سازوکارهای اختصاصی انتقال را داخل runner Plugin یا harness کانال نگه دارید.
- runner را بهصورت
openclaw qa <runner>mount کنید، نه با ثبت یک root command رقیب. Pluginهای runner بایدqaRunnersرا درopenclaw.plugin.jsonاعلام کنند و آرایهٔ متناظرqaRunnerCliRegistrationsرا ازruntime-api.tsexport کنند.runtime-api.tsرا سبک نگه دارید؛ اجرای lazy مربوط به CLI و runner باید پشت entrypointهای جداگانه بماند. - سناریوهای YAML را زیر دایرکتوریهای موضوعی
qa/scenarios/بنویسید یا تطبیق دهید. - برای سناریوهای جدید از helperهای عمومی سناریو استفاده کنید.
- aliasهای سازگاری موجود را فعال نگه دارید مگر اینکه مخزن در حال انجام یک migration عمدی باشد.
قاعدهٔ تصمیمگیری سختگیرانه است:
- اگر رفتار را میتوان یکبار در
qa-labبیان کرد، آن را درqa-labبگذارید. - اگر رفتار به یک انتقال کانال وابسته است، آن را در همان runner Plugin یا harness Plugin نگه دارید.
- اگر سناریویی به قابلیت جدیدی نیاز دارد که بیش از یک کانال میتواند از آن استفاده کند، بهجای شاخهٔ اختصاصی کانال در
suite.tsیک helper عمومی اضافه کنید. - اگر رفتاری فقط برای یک انتقال معنا دارد، سناریو را اختصاصی انتقال نگه دارید و این را در قرارداد سناریو صریح کنید.
نام helperهای سناریو
helperهای عمومی ترجیحی برای سناریوهای جدید:
waitForTransportReadywaitForChannelReadyinjectInboundMessageinjectOutboundMessagewaitForTransportOutboundMessagewaitForChannelOutboundMessagewaitForNoTransportOutboundgetTransportSnapshotreadTransportMessagereadTransportTranscriptformatTransportTranscriptresetTransport
aliasهای سازگاری برای سناریوهای موجود همچنان در دسترس هستند - waitForQaChannelReady، waitForOutboundMessage، waitForNoOutbound، formatConversationTranscript، resetBus - اما نوشتن سناریوهای جدید باید از نامهای عمومی استفاده کند. aliasها برای جلوگیری از migration یکباره وجود دارند، نه بهعنوان الگوی آینده.
گزارشدهی
qa-lab یک گزارش protocol در Markdown را از خط زمانی bus مشاهدهشده export میکند.
گزارش باید به این موارد پاسخ دهد:
- چه چیزی کار کرد
- چه چیزی شکست خورد
- چه چیزی همچنان مسدود ماند
- چه سناریوهای follow-up ارزش افزودن دارند
برای inventory سناریوهای موجود - که هنگام اندازهگیری کار follow-up یا اتصال یک انتقال جدید مفید است - pnpm openclaw qa coverage را اجرا کنید (برای خروجی قابل خواندن توسط ماشین، --json را اضافه کنید).
هنگام انتخاب اثبات متمرکز برای یک رفتار یا مسیر فایل لمسشده، pnpm openclaw qa coverage --match <query> را اجرا کنید.
گزارش match در metadata سناریو، ارجاعهای docs، ارجاعهای code، شناسههای coverage، Pluginها، و نیازمندیهای ارائهدهنده جستوجو میکند، سپس targetهای متناظر qa suite --scenario ... را چاپ میکند.
هر اجرای qa suite برای مجموعهٔ سناریوی انتخابشده artifactهای سطح بالای
qa-evidence.json، qa-suite-summary.json، و qa-suite-report.md را مینویسد.
سناریوهایی که execution.kind: vitest یا execution.kind: playwright را اعلام
میکنند مسیر آزمون متناظر را اجرا میکنند و logهای جداگانه برای هر سناریو نیز
مینویسند. سناریوهایی که execution.kind: script را اعلام میکنند، تولیدکنندهٔ
evidence در execution.path را از طریق node --import tsx اجرا میکنند (با
گسترش ${outputDir} و ${scenarioId} در execution.args)؛ تولیدکننده
qa-evidence.json خودش را مینویسد، entryهای آن به خروجی suite وارد میشوند و
مسیرهای artifact آن نسبت به همان qa-evidence.json تولیدکننده resolve میشوند.
وقتی qa suite از طریق qa run --qa-profile فراخوانی شود، همان
qa-evidence.json خلاصهٔ scorecard مربوط به profile را نیز برای دستههای
taxonomy انتخابشده شامل میشود.
با آن بهعنوان کمک کشف برخورد کنید، نه جایگزین gate؛ سناریوی انتخابشده همچنان به حالت ارائهدهندهٔ مناسب، انتقال live، 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این فرمان فرایندهای فرزند Gateway برای QA محلی را اجرا میکند، نه Docker. سناریوهای ارزیابی شخصیت باید پرسونا را از طریق SOUL.md تنظیم کنند، سپس نوبتهای معمول کاربر مانند گفتوگو، کمک درباره فضای کاری، و کارهای کوچک روی فایل را اجرا کنند. به مدل نامزد نباید گفته شود که در حال ارزیابی است. این فرمان هر رونوشت کامل را حفظ میکند، آمار پایه اجرای کار را ثبت میکند، سپس از مدلهای داور در حالت سریع و با استدلال xhigh در جاهایی که پشتیبانی میشود میخواهد اجراها را بر اساس طبیعیبودن، حسوحال، و طنز رتبهبندی کنند.
هنگام مقایسه ارائهدهندگان، از --blind-judge-models استفاده کنید: اعلان داور همچنان همه رونوشتها و وضعیت اجرای کار را دریافت میکند، اما ارجاعهای نامزد با برچسبهای خنثی مانند candidate-01 جایگزین میشوند؛ گزارش پس از تجزیه، رتبهبندیها را دوباره به ارجاعهای واقعی نگاشت میکند.
اجرای نامزدها بهطور پیشفرض از تفکر high استفاده میکند، با medium برای GPT-5.5 و xhigh برای ارجاعهای قدیمیتر ارزیابی OpenAI که از آن پشتیبانی میکنند. یک نامزد مشخص را بهصورت درونخطی با --model provider/model,thinking=<level> بازنویسی کنید. --thinking <level> همچنان یک مقدار جایگزین سراسری تنظیم میکند، و شکل قدیمیتر --model-thinking <provider/model=level> برای سازگاری نگه داشته شده است.
ارجاعهای نامزد OpenAI بهطور پیشفرض از حالت سریع استفاده میکنند تا در جاهایی که ارائهدهنده پشتیبانی میکند پردازش اولویتدار بهکار رود. وقتی یک نامزد یا داور منفرد به بازنویسی نیاز دارد، ,fast، ,no-fast، یا ,fast=false را بهصورت درونخطی اضافه کنید. فقط وقتی --fast را پاس دهید که میخواهید حالت سریع را برای همه مدلهای نامزد اجباری کنید. مدتزمانهای نامزد و داور برای تحلیل بنچمارک در گزارش ثبت میشوند، اما اعلانهای داور بهصراحت میگویند که رتبهبندی بر اساس سرعت انجام نشود.
اجرای مدلهای نامزد و داور هر دو بهطور پیشفرض از همروندی 16 استفاده میکنند. وقتی محدودیتهای ارائهدهنده یا فشار Gateway محلی اجرای کار را بیش از حد پرنویز میکند، --concurrency یا --judge-concurrency را کاهش دهید.
وقتی هیچ نامزد --model پاس داده نشود، ارزیابی شخصیت بهطور پیشفرض از
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 استفاده میکنند.