Tools
نمایش ویجت
show_widget یک ابزار اصلی است که یک ویجت HTML مستقل را در سطح فعلی کاربر نمایش میدهد. OpenClaw آن را بهصورت درونخطی در Control UI و رونوشتهای Quick Chat در iOS، Android، macOS و Linux رندر میکند؛ داشبورد Linux از Control UI مرورگر استفاده میکند. در یک نشست Discord که Activities در آن فعال است، Plugin مربوط به Discord یک دکمه باز کردن ویجت ارسال میکند که آن را بهصورت یک Activity اجرا میکند.
ویجتها چگونه کار میکنند
وقتی عامل show_widget را فراخوانی میکند، هسته OpenClaw، widget_code را درون یک سند HTML حداقلی قرار میدهد، آن را بهعنوان سند Canvas ذخیره میکند و یک دستگیره پیشنمایش برمیگرداند. Control UI آن دستگیره را در یک iframe سندباکسشده رندر میکند، درحالیکه Quick Chat در iOS، Android، macOS و Linux از نماهای وب ایزوله استفاده میکند. کلاینتهای کامل چت، ویجت را پس از بارگذاری مجدد تاریخچه بازیابی میکنند؛ Quick Chat ویجت را برای پاسخ فعال خود نگه میدارد.
در نشستهای Control UI، یک ویجت Canvas را همچنین میتوان به داشبورد نشست سنجاق کرد. در فراخوانی ابزار، pin: true را تنظیم کنید یا روی یک ویجت موجود در رونوشت از سنجاق کردن به داشبورد استفاده کنید. HTML سنجاقشده پشت همان میزبان سندباکس با مبدأ اختصاصی و iframe دوگانهای اجرا میشود که MCP Apps استفاده میکند؛ مرورگر هرگز یک اتصال داده ویجت را درون قاب غیرقابلاعتماد تفکیک نمیکند.
برای تعبیه در مرورگر، سند پوشاننده چهار پل کوچک میزبان را پیرامون کد ویجت تزریق میکند:
- یک گزارشگر اندازه، ارتفاع محتوای رندرشده را به چت تعبیهکننده ارسال میکند؛ چت آن را محدود میکند و iframe را با آن تطبیق میدهد (160 تا 1200 پیکسل).
- یک پل میزبان، تابع کمکی قدیمی
sendPrompt(text)و همچنین APIهای ساختیافتهopenclaw.prompt، openclaw.state، openclaw.dataوopenclaw.cronرا تعریف میکند. اعلانهای درونخطی چت، کانال پیام خصوصی خود را حفظ میکنند؛ APIهای داشبورد از یک کانال درخواست متصل به بلیت نما استفاده میکنند. به ویجتهای تعاملی و قابلیتهای داشبورد مراجعه کنید. - یک پل پوسته به توکنهای طراحی فعلی Control UI گوش میدهد و آنها را هنگام بارگذاری و دوباره پس از هر تغییر پوسته، بهصورت متغیرهای CSS اعمال میکند.
- یک پل عکس فوری، وقتی چت تعبیهکننده درخواست برونبری میدهد، سند فعلی ویجت را بهصورت PNG رندر میکند.
همهچیز دیگر درون قاب باقی میماند: سند در یک مبدأ مبهم با یک سیاست امنیت محتوا سختگیرانه اجرا میشود، بنابراین اسکریپتهای ویجت نمیتوانند به Control UI، Gateway یا شبکه دسترسی پیدا کنند.
پیادهسازی اصلی فقط زمانی در دسترس است که کلاینت Gateway آغازکننده، قابلیت inline-widgets را اعلام کند. Control UI و برنامههای بومی پشتیبانیشده این قابلیت را بهطور خودکار اعلام میکنند. Quick Chat در Linux برای اتصالهای Gateway که به پین سفارشی گواهی نهایی TLS نیاز دارند، فقط متنی باقی میماند، زیرا WebView پلتفرم آن نمیتواند آن پین را متصل کند. پیادهسازی Discord فقط در نشستهای Discord که Activities در آنها پیکربندی شده است در دسترس است. سایر اجراهای کانال، show_widget را دریافت نمیکنند.
انتقال قابلیت، بکاندهای مدل تعبیهشده، app-server مربوط به Codex و مبتنی بر CLI را پوشش میدهد. فراخوانهای MCP احرازشده با مجوز و فراخوانهای مستقیم ابزار از طریق HTTP همچنان در حالت بسته و امن شکست میخورند، زیرا قابلیتهای کلاینت را اعلام نمیکنند.
سیستم طراحی
هر ویجت Canvas شامل یک شیوهنامه پایه بدون کلاس و مجموعه کوچکی از توکنها است:
| توکن | کاربرد |
|---|---|
--surface |
رنگ سطح در سطح صفحه |
--card |
پسزمینه کارت، دکمه و کد |
--elevated |
پسزمینه برجسته کنترل فرم |
--text |
متن پیشفرض بدنه و کنترل |
--text-strong |
عنوانها و مقادیر برجسته |
--muted |
متن ثانویه و حاشیههای ظریف |
--border |
جداکنندههای استاندارد و حاشیههای کارت |
--border-strong |
حاشیههای پررنگ کنترل |
--accent |
پیوندها و حلقههای تمرکز |
--accent-fill |
پُرکننده کنش اصلی |
--accent-fg |
متن روی یک کنش اصلی |
--ok |
وضعیت موفقیت |
--warn |
وضعیت هشدار |
--danger |
وضعیت خطا یا مخرب |
--info |
وضعیت اطلاعرسانی |
--radius |
شعاع مشترک گوشه کنترل و کارت |
--font-body |
پشته قلم بدنه میزبان |
--font-mono |
پشته قلم تکفاصله میزبان |
--accent-subtle، --ok-subtle، --warn-subtle، --danger-subtle، --info-subtle |
پسزمینههای نیمهشفاف مشتقشده وضعیت |
عنوانها، بندها، پیوندها، دکمهها، ورودیها، انتخابگرها، ناحیههای متنی، جدولها و بلوکهای کد بدون کلاس، سبکهای پایه را دریافت میکنند. کلاسهای کمکی الگوهای رایج را فراهم میکنند:
.cardبرای یک سطح محتوا با حاشیه.badge، بههمراه.ok، .warn، .dangerیا.info، برای برچسبهای فشرده وضعیت.metricبرای یک مقدار عددی برجسته.mutedبرای متن ثانویه.rowبرای یک چیدمان افقی سطربندیشوندهbutton.primaryبرای کنش اصلی
Control UI هنگام بارگذاری یک ویجت و هر بار که پوسته تغییر میکند، پیامی از نوع openclaw:widget-theme با مقادیر پوسته فعال ارسال میکند. بنابراین ویجتها بدون بارگذاری مجدد، همه خانوادههای پوسته، از جمله Claw، Knot، Dash و پوستههای سفارشی را دنبال میکنند. خارج از Control UI، از جمله در برنامههای بومی و بازکردنهای مستقیم، ویجتها از پالت روشن یا تاریک تعبیهشدهای استفاده میکنند که prefers-color-scheme انتخاب کرده است.
ویجتها را با سه قاعده بسازید:
- برای هر رنگ و پسزمینه از متغیرهای طراحی استفاده کنید. مقادیر رنگ را بهصورت ثابت در کد ننویسید.
- پسزمینه صفحه را شفاف نگه دارید تا ویجت به سطح میزبان خود تعلق داشته باشد.
--accent-fillرا حداکثر برای یک کنش اصلی در نظر بگیرید.
برونبری: در چت وب، منوی کارت ویجت را باز کنید تا ویجت رندرشده را در کلیپبورد کپی یا آن را بهصورت PNG بارگیری کنید. اسناد قدیمیتر ویجت که پل عکس فوری ندارند، به بارگیری فایل HTML بازمیگردند.
استفاده از ابزار
هر دو پیادهسازی از فیلدهای الزامی یکسانی استفاده میکنند:
titlestringrequiredعنوان کوتاهی که همراه پیشنمایش درونخطی و در عنوان سند میزبانیشده نمایش داده میشود.
widget_codestringrequiredHTML یا SVG مستقل. برای کلاینتهای ویجت درونخطی، ورودیای که پس از حذف فاصلههای ابتدا و انتها با <svg آغاز شود، در حالت SVG رندر میشود؛ حداکثر طول 262,144 نویسه است. Discord یک سند کامل HTML یا قطعه بدنه تا 48 KiB را میپذیرد.
Discord همچنین متن اختیاری button_label را برای دکمه اجرای Activity میپذیرد. شِمای Canvas عمداً این فیلد مختص Discord را حذف میکند.
ابزار اصلی Canvas این فیلدهای اختیاری جایگذاری داشبورد را میپذیرد:
pin: ویجت را همچنین روی داشبورد نشست قرار دهید.name: نام پایدار ویجت؛ مقدار پیشفرض، یک نامک ازtitleاست.tab: نامک زبانه مقصد.size: یکی ازsm، md، lg، xlیاfull.after: نام ویجت همسطحی که ویجت باید پس از آن قرار گیرد.capabilities: دسترسی درخواستی یک ویجت سنجاقشده.netOriginsشامل مبدأهای دقیق HTTPS است؛toolsشاملprompt، یک اتصال خواندن موجود در فهرست مجاز، یا یک کنش دقیقcron.trigger:<jobId>است.
نتیجه اصلی شامل یک دستگیره پیشنمایش Canvas است، بنابراین Control UI و برنامههای بومی پشتیبانیشده، ویجت را مستقیماً از فراخوانی ابزار رندر میکنند و پس از بارگذاری مجدد تاریخچه آن را بازیابی میکنند. نتایج سنجاقشده همچنین نام ویجت بورد را حفظ میکنند تا Control UI پس از بارگذاری مجدد رونوشت، گزینه سنجاق تکراری ارائه نکند. Discord شناسههای ویجت ذخیرهشده و پیام ارسالشده را برمیگرداند.
discord_widget برای یک نسخه بهعنوان نام مستعار منسوخشده ثبت باقی میماند. فراخوانیهای جدید عامل باید از show_widget استفاده کنند.
ویجتهای تعاملی
در Control UI، اسکریپتهای ویجت میتوانند مکالمه را هدایت کنند. سند پوشاننده یک تابع سراسری sendPrompt(text) تعریف میکند؛ فراخوانی آن، text را چنان به چت ارسال میکند که گویی کاربر پیام را تایپ و ارسال کرده است. آن را به دکمهها یا کنترلهای دیگر متصل کنید تا جریانهای تعاملی مانند انتخابگرها، آزمونها یا داشبوردهای کاوش جزئیات ساخته شوند. برنامههای بومی کد تعاملی ویجت را رندر میکنند، اما این پل اعلان چت را ارائه نمیدهند.
<button onclick="sendPrompt('آزمونهای ناموفق را با جزئیات نمایش بده')">آزمونهای ناموفق</button>هر اعلان در هر دو سوی مرز قاب اعتبارسنجی میشود:
sendPromptبه فعالسازی گذرای کاربر درون ویجت نیاز دارد: این قابلیت فقط طی چند ثانیه پس از کلیک کاربر یا فشردن یک کلید در ویجت کار میکند؛ بنابراین آن را به دکمهها و سایر اهداف کلیک متصل کنید — فراخوانی خودکار آن هنگام بارگذاری هیچ کاری نمیکند. پل، نقطه پایانی ارسال را برای خود خصوصی نگه میدارد و در مرورگرهایی که فعالسازی کاربر را ارائه نمیکنند، در حالت بسته و امن شکست میخورد؛ بنابراین کد ویجت نمیتواند بررسی را دور بزند.- اختیار اعلان فقط به سند اصلی ویجت تعلق دارد. پل قابلاعتماد پیش از آنکه کد ویجت بتواند قاب را اجرا یا پیمایش کند، نقطه پایانی کانال خود را به چت ارائه میدهد؛ چت فقط همان نخستین پیشنهاد را میپذیرد و کانال هنگام پیمایش همراه سند از بین میرود. URLهای تعبیهای که از بیرون مجاز شدهاند، هرگز پذیرفته نمیشوند.
- قاب ویجت باید در رونوشت چت قابلمشاهده و دارای تمرکز باشد — نشانه دیگری که میزبان مشاهده میکند تا معلوم شود کاربر واقعاً با این ویجت تعامل دارد.
- متن باید پس از حذف فاصلههای ابتدا و انتها خالی نباشد و حداکثر 4,000 نویسه داشته باشد.
- اعلانهایی که با
/آغاز میشوند رد میشوند، بنابراین کد ویجت نمیتواند فرمانهای چت مانند/approveیا/stopرا فعال کند. - هر سند ویجت میتواند در هر دقیقه لغزان حداکثر 10 اعلان ارسال کند؛ اعلانهای اضافی بیسروصدا حذف میشوند.
اعلانهای پذیرفتهشده بهصورت پیامهای عادی کاربر در رونوشت ظاهر میشوند و یک نوبت عادی عامل را در نشستی آغاز میکنند که مالک ویجت است. هیچ کانال بازخوردی به درون ویجت وجود ندارد: یک اعلان حذفشده بیسروصدا شکست میخورد و ویجت نمیتواند پاسخ عامل را بخواند.
قابلیتهای داشبورد
پس از آنکه اپراتور اعلامیه نمایشدادهشده روی کارت در انتظار را بررسی کرد، ویجتهای سنجاقشده میتوانند از یک API میزبان متصل به بلیت استفاده کنند:
openclaw.prompt.send(text)به فعالسازی موقت کاربر نیاز دارد و پیامی قابلمشاهده در بخش نوشتن پیام درج میکند. اعلام و دریافت مجوز ابزارpromptتأیید اضافی برای هر کلیک را حذف میکند؛ اعتبارسنجی، بررسیهای تمرکز و محدودیتهای نرخ همچنان اعمال میشوند.openclaw.state.emit(payload)یک اعلان به نشست اضافه میکند. اندازه بارهای داده به 8 KiB محدود است و ارسالهای یکسان کلاینت در بازه پنج ثانیه با هم ادغام میشوند.openclaw.data.read(bindingId, params?)فقط در Gateway تفکیک میشود. اتصالهای قابلاعطای مجوز عبارتاند ازsessions.list،usage.status،usage.cost،cron.list،cron.status،agents.listوhealth.openclaw.cron.trigger(jobId)تنها زمانی یک کار موجود را فوراً اجرا میکند که قابلیت دقیقcron.trigger:<jobId>اعطا شده باشد.
دسترسی شبکه از ابزارهای میزبان جدا است. مبدأهای دقیق HTTPS را در capabilities.netOrigins قرار دهید؛ پس از تأیید، فقط همان مبدأها وارد connect-src ویجت میشوند. نویسههای عام، اطلاعات احراز هویت، مسیرها، رشتههای پرسوجو و مبدأهای اعلامنشده همچنان مسدود میمانند. پورت صریح فقط زمانی مجاز است که بخشی از مبدأ اعلامشده باشد.
امنیت و ذخیرهسازی
اسناد ویجت از سیاستهای محدودکننده امنیت محتوا استفاده میکنند. سبک و اسکریپت درونخطی مجازند، اما بارگذاری منابع خارجی همچنان مسدود است. ویجتهای درونخطی رونوشت نمیتوانند از شبکه واکشی کنند. ویجت سنجاقشده داشبورد فقط میتواند مبدأهای دقیق HTTPS را که عامل اعلام و اپراتور اعطا کرده است واکشی کند.
iframe رابط کنترل همیشه allow-same-origin را حذف میکند، حتی زمانی که حالت سراسری جاسازی trusted است؛ بنابراین اسکریپتهای ویجت نمیتوانند مبدأ برنامه والد را بخوانند. کلاینتهای بومی از نماهای وب ایزوله و غیرماندگار استفاده میکنند و پیمایش به خارج از ویجت میزبانیشده را مسدود میکنند. میزبان سند اصلی نیز ویجتها را با سرآیند پاسخ Content-Security-Policy: sandbox allow-scripts ارائه میکند؛ بنابراین حتی رندر مستقیم نیز ویجت را بهجای مبدأ برنامه، در مبدأیی مات اجرا میکند. فقط کد ویجتی را رندر کنید که مایلید در آن قاب ایزوله اجرا شود.
iframe همچنین از gateway.controlUi.embedSandbox پیروی میکند. سطح پیشفرض scripts ضمن حفظ جداسازی مبدأ، از ویجتهای تعاملی پشتیبانی میکند.
ریسک باقیمانده پذیرفتهشده خروجی کانال داده WebRTC در معماری داشبورد مستند شده است.
Canvas در هر نشست حداکثر 32 ویجت نگه میدارد (یا در صورت نبود نشست، بهازای هر عامل). ایجاد ویجتی دیگر، قدیمیترین سند را در آن محدوده حذف میکند.