Building plugins
ساخت Pluginها
Pluginها OpenClaw را بدون تغییر هسته گسترش میدهند. یک Plugin میتواند یک کانال پیامرسانی، ارائهدهنده مدل، بکاند محلی CLI، ابزار عامل، هوک، ارائهدهنده رسانه، یا قابلیت دیگری تحت مالکیت Plugin اضافه کند.
نیازی نیست یک Plugin خارجی را به مخزن OpenClaw اضافه کنید. بسته را در ClawHub منتشر کنید و کاربران آن را با دستور زیر نصب میکنند:
openclaw plugins install clawhub:<package-name>در دوره گذار راهاندازی، مشخصات بسته بدون پیشوند همچنان از npm نصب میشوند. زمانیکه تفکیکپذیری از طریق ClawHub را میخواهید، از پیشوند
clawhub: استفاده کنید.
الزامات
- Node 22.22.3+، Node 24.15+، یا Node 25.9+، و
npmیاpnpm. - ماژولهای TypeScript ESM.
- برای کار روی Pluginهای همراه درون مخزن، مخزن را کلون و
pnpm installرا اجرا کنید. توسعه Plugin در نسخه منبع فقط با pnpm انجام میشود، زیرا OpenClaw Pluginهای همراه را از بستههای فضای کاریextensions/*کشف میکند.
انتخاب ساختار Plugin
OpenClaw را به یک پلتفرم پیامرسانی متصل کنید.
یک ارائهدهنده مدل، رسانه، جستوجو، واکشی، گفتار یا بلادرنگ اضافه کنید.
یک CLI محلی هوش مصنوعی را از طریق جایگزینی مدل OpenClaw اجرا کنید.
ابزارهای عامل را ثبت کنید.
شروع سریع
با ثبت یک ابزار عامل الزامی، یک Plugin ابزار حداقلی بسازید. این کوتاهترین ساختار مفید Plugin است و بسته، مانیفست، نقطه ورود و اثبات محلی را پوشش میدهد.
ایجاد فراداده بسته
{"name": "@myorg/openclaw-my-plugin","version": "1.0.0","type": "module","dependencies": {"typebox": "1.1.39"},"peerDependencies": {"openclaw": ">=2026.3.24-beta.2"},"openclaw": {"extensions": ["./index.ts"],"compat": {"pluginApi": ">=2026.3.24-beta.2","minGatewayVersion": "2026.3.24-beta.2"},"build": {"openclawVersion": "2026.3.24-beta.2","pluginSdkVersion": "2026.3.24-beta.2"}}}{"id": "my-plugin","name": "My Plugin","description": "Adds a custom tool to OpenClaw","contracts": {"tools": ["my_tool"]},"activation": {"onStartup": true},"configSchema": {"type": "object","additionalProperties": false}}Pluginهای خارجی منتشرشده باید ورودیهای زمان اجرا را به فایلهای JavaScript ساختهشده ارجاع دهند. برای قرارداد کامل نقطه ورود، به نقاط ورود SDK مراجعه کنید.
هر Plugin حتی بدون پیکربندی به یک مانیفست نیاز دارد. ابزارهای زمان اجرا باید
در contracts.tools ظاهر شوند تا OpenClaw بتواند مالکیت را بدون
بارگذاری پیشدستانه زمان اجرای همه Pluginها کشف کند. activation.onStartup را
آگاهانه تنظیم کنید؛ این نمونه هنگام راهاندازی Gateway بارگذاری میشود.
سطوح Plugin مورد اعتماد میزبان نیز با مانیفست محدود میشوند و برای Pluginهای
نصبشده به اعلان صریح نیاز دارند: api.registerAgentToolResultMiddleware(...)
مستلزم فهرستشدن هر زمان اجرای هدف در contracts.agentToolResultMiddleware است،
و api.registerTrustedToolPolicy(...) به درج هر شناسه سیاست در
contracts.trustedToolPolicies نیاز دارد. این اعلانها بازرسی هنگام نصب
و ثبت زمان اجرا را همراستا نگه میدارند.
برای مشاهده همه فیلدهای مانیفست، به مانیفست Plugin مراجعه کنید.
ثبت ابزار
import { Type } from "typebox";import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; export default definePluginEntry({ id: "my-plugin", name: "My Plugin", description: "Adds a custom tool to OpenClaw", register(api) { api.registerTool({ name: "my_tool", description: "Echo one input value", parameters: Type.Object({ input: Type.String() }), outputSchema: Type.Object( { input: Type.String() }, { additionalProperties: false }, ), async execute(_id, params) { const details = { input: params.input }; return { content: [{ type: "text", text: `Got: ${params.input}` }], details, }; }, }); },});برای Pluginهای غیرکانالی از definePluginEntry استفاده کنید. Pluginهای کانال
در عوض از defineChannelPluginEntry در openclaw/plugin-sdk/core استفاده میکنند.
آزمایش زمان اجرا
برای یک Plugin نصبشده یا خارجی، زمان اجرای بارگذاریشده را بررسی کنید:
openclaw plugins inspect my-plugin --runtime --jsonاگر Plugin یک فرمان CLI ثبت میکند، آن فرمان را نیز اجرا و خروجی را
تأیید کنید؛ برای نمونه، openclaw demo-plugin ping.
برای یک Plugin همراه در این مخزن، OpenClaw بستههای Plugin نسخه منبع
را از فضای کاری extensions/* کشف میکند. نزدیکترین آزمون هدفمند را
اجرا کنید:
pnpm test extensions/my-plugin/pnpm checkآزمایش نصب بسته
پیش از انتشار یک Plugin آماده بستهبندی، همان ساختار نصبی را آزمایش کنید که
کاربران دریافت خواهند کرد. ابتدا یک مرحله ساخت اضافه کنید، ورودیهای زمان اجرا مانند
openclaw.extensions را به JavaScript ساختهشده مانند ./dist/index.js ارجاع دهید، و
مطمئن شوید npm pack آن خروجی dist/ را شامل میشود. ورودیهای منبع TypeScript
فقط برای نسخههای منبع و مسیرهای توسعه محلی هستند.
سپس Plugin را بستهبندی کنید و فایل tar را با npm-pack: نصب کنید:
npm pack --pack-destination /tmpopenclaw plugins install npm-pack:/tmp/<plugin-package>.tgz --forceopenclaw plugins inspect my-plugin --runtime --jsonnpm-pack: از پروژه npm مدیریتشده OpenClaw برای هر Plugin استفاده میکند، بنابراین
خطاهای وابستگی زمان اجرا را که آزمایش نسخه منبع ممکن است پنهان کند، شناسایی
میکند. این کار ساختار بسته و وابستگی را اثبات میکند، نه اعتماد رسمی متصل به کاتالوگ را.
واردسازیهای زمان اجرا باید در dependencies یا optionalDependencies باشند؛
وابستگیهایی که فقط در devDependencies باقی بمانند، برای پروژه
زمان اجرای مدیریتشده نصب نخواهند شد.
برای اثبات نهایی رفتار رسمی یا دارای امتیاز ویژه Plugin، از نصب مستقیم آرشیو/مسیر استفاده نکنید. منابع مستقیم برای اشکالزدایی محلی مفیدند، اما همان مسیر وابستگی نصبهای npm یا ClawHub را اثبات نمیکنند. اگر Plugin شما به وضعیت Plugin رسمی مورد اعتماد وابسته است، یک اثبات دوم از طریق نصب رسمی مبتنی بر کاتالوگ یا مسیر بسته منتشرشدهای اضافه کنید که اعتماد رسمی را ثبت میکند. برای جزئیات ریشه نصب و مالکیت وابستگی، به تفکیکپذیری وابستگی Plugin مراجعه کنید.
انتشار
بسته را پیش از انتشار اعتبارسنجی کنید:
clawhub package publish your-org/your-plugin --dry-runclawhub package publish your-org/your-pluginقطعهکدهای مرجع بسته ClawHub در docs/snippets/plugin-publish/ قرار دارند.
نصب
بسته منتشرشده را از طریق ClawHub نصب کنید:
openclaw plugins install clawhub:your-org/your-pluginثبت ابزارها
ابزارها میتوانند الزامی یا اختیاری باشند. ابزارهای الزامی هنگام فعالبودن Plugin همیشه در دسترساند. ابزارهای اختیاری پیش از آنکه OpenClaw زمان اجرای Plugin مالک را بارگذاری کند، به انتخاب صریح کاربر نیاز دارند.
کارخانههای ابزار زمینه زمان اجرای مورد اعتماد را دریافت میکنند، از جمله deliveryContext،
nativeChannelId برای گفتوگوی فعال پلتفرم در صورت دسترسبودن، و
requesterSenderId.
register(api) { api.registerTool( { name: "workflow_tool", description: "Run a workflow", parameters: Type.Object({ pipeline: Type.String() }), outputSchema: Type.Object( { pipeline: Type.String() }, { additionalProperties: false }, ), async execute(_id, params) { return { content: [{ type: "text", text: params.pipeline }], details: { pipeline: params.pipeline }, }; }, }, { optional: true }, );}outputSchema اختیاری است. این مورد مقدار ساختاریافته details را توصیف میکند که
حالت کد و جستوجوی ابزار از آن استفاده میکنند. فراخوانیهای
کاتالوگ طرحوارههای نامعتبر را پیش از اجرا رد میکنند و مقدار نهایی را پس از
هوکهای ابزار اعتبارسنجی میکنند. برای ابزارهای فاقد نتیجه JSON پایدار، آن را حذف کنید. برای
قرارداد کامل، به Pluginهای ابزار مراجعه کنید.
هر ابزاری که با api.registerTool(...) ثبت میشود باید در مانیفست
Plugin نیز اعلام شود:
{ "contracts": { "tools": ["workflow_tool"] }, "toolMetadata": { "workflow_tool": { "optional": true } }}کاربران با tools.allow آن را فعال میکنند:
{ tools: { allow: ["workflow_tool"] }, // یا ["my-plugin"] برای همه ابزارهای یک Plugin}ابزارهای اختیاری تعیین میکنند که آیا ابزار در معرض مدل قرار گیرد یا خیر. زمانیکه یک ابزار یا هوک باید پس از انتخاب توسط مدل و پیش از اجرای عمل درخواست تأیید کند، از درخواستهای مجوز Plugin استفاده کنید.
از ابزارهای اختیاری برای عوارض جانبی، فایلهای اجرایی نامتعارف یا قابلیتهایی استفاده کنید که
نباید بهطور پیشفرض در معرض مدل قرار گیرند. نام ابزارها نباید با نام ابزارهای هسته
تداخل داشته باشد؛ موارد متعارض نادیده گرفته و در تشخیصهای Plugin گزارش میشوند. ثبتهای
بدشکل نیز به همین روش نادیده گرفته و گزارش میشوند: نبود name غیرخالی،
execute که تابع نیست، یا توصیفگر ابزار بدون شیء parameters.
کارخانههای ابزار یک شیء زمینه تأمینشده توسط زمان اجرا دریافت میکنند. زمانیکه ابزار نیاز دارد
مدل فعال نوبت جاری را ثبت، نمایش یا خود را با آن سازگار کند، از ctx.activeModel
استفاده کنید؛ این مقدار میتواند شامل provider، modelId و modelRef باشد. با آن
بهعنوان فراداده اطلاعاتی زمان اجرا رفتار کنید، نه مرز امنیتی در برابر اپراتور
محلی، کد Plugin نصبشده یا زمان اجرای تغییریافته OpenClaw. ابزارهای محلی
حساس همچنان باید به انتخاب صریح Plugin یا اپراتور نیاز داشته باشند و
هنگامیکه فراداده مدل فعال وجود ندارد یا مناسب نیست، بهصورت بسته شکست بخورند.
مانیفست مالکیت و کشف را اعلام میکند؛ اجرا همچنان پیادهسازی زنده
ابزار ثبتشده را فراخوانی میکند. toolMetadata.<tool>.optional: true را
با api.registerTool(..., { optional: true }) همراستا نگه دارید تا OpenClaw بتواند از
بارگذاری زمان اجرای آن Plugin تا زمانیکه ابزار صریحاً در فهرست مجاز قرار گیرد، خودداری کند.
قراردادهای واردسازی
از زیرمسیرهای متمرکز SDK وارد کنید:
در بسته Plugin خود، برای واردسازیهای داخلی از فایلهای barrel محلی مانند api.ts و
runtime-api.ts استفاده کنید. Plugin خود را از طریق یک مسیر SDK وارد نکنید. کمکتابعهای
مختص ارائهدهنده باید در بسته ارائهدهنده باقی بمانند، مگر اینکه مرز واقعاً عمومی باشد.
متدهای سفارشی RPC در Gateway یک نقطه ورود پیشرفته هستند. آنها را زیر یک
پیشوند مختص Plugin نگه دارید؛ فضاهای نام مدیریتی هسته مانند config.*،
exec.approvals.*، operator.admin.*، wizard.* و update.* رزرو میمانند
و به operator.admin منتهی میشوند. پل
openclaw/plugin-sdk/gateway-method-runtime برای مسیرهای HTTP Plugin که contracts.gatewayMethodDispatch: ["authenticated-request"] را اعلام میکنند، رزرو شده است.
برای نقشه کامل واردسازی، به نمای کلی SDK برای Plugin مراجعه کنید.
فیلدهای سازگاری SDK در OpenClaw دارای حاشیهنویسیهای TypeScript @deprecated هستند
که ویرایشگرها آنها را بهصورت هشدار مهاجرت نمایش میدهند. برای اعمال آنها هنگام ساخت،
یک قاعده آگاه از نوع مانند
@typescript-eslint/no-deprecated
را فعال کنید. Oxlint از نوعها آگاه نیست، بنابراین نمیتواند این حاشیهنویسیها را اعمال کند.
فهرست بررسی پیش از ارسال
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
package.json دارای فرادادهٔ صحیح openclaw است
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s مانیفست openclaw.plugin.json موجود و معتبر است OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
نقطهٔ ورود از defineChannelPluginEntry یا definePluginEntry استفاده میکند
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
همهٔ importها از مسیرهای متمرکز plugin-sdk/<subpath> استفاده میکنند
OPENCLAW_DOCS_MARKER:calloutClose: