Building plugins
Pluginهای ابزار
defineToolPlugin افزونهای میسازد که فقط ابزارهای قابلفراخوانی توسط عامل را اضافه میکند: بدون
کانال، ارائهدهنده مدل، هوک، سرویس یا بکاند راهاندازی. این دستور فراداده مانیفستی را
تولید میکند که OpenClaw برای کشف ابزارها بدون بارگذاری کد زمان اجرای افزونه به آن
نیاز دارد.
برای افزونههای ارائهدهنده، کانال، هوک، سرویس یا افزونههای دارای قابلیتهای ترکیبی، بهجای آن با ساخت افزونهها، افزونههای کانال، یا افزونههای ارائهدهنده شروع کنید.
الزامات
- Node 22.22.3+، Node 24.15+ یا Node 25.9+.
- خروجی بسته TypeScript ESM.
typeboxدرdependencies(نه فقطdevDependencies؛ افزونه تولیدشده آن را در زمان اجرا وارد میکند).openclaw >=2026.5.17، نخستین نسخهای کهopenclaw/plugin-sdk/tool-pluginرا صادر میکند.- ریشه بستهای که
dist/،openclaw.plugin.jsonوpackage.jsonرا ارائه میکند.
شروع سریع
openclaw plugins init stock-quotes --name "Stock Quotes"cd stock-quotesnpm installnpm run plugin:buildnpm run plugin:validatenpm testplugins init موارد زیر را داربستبندی میکند:
| فایل | هدف |
|---|---|
src/index.ts |
ورودی defineToolPlugin با یک ابزار echo |
src/index.test.ts |
آزمون فراداده برای بررسی فهرست ابزارها |
tsconfig.json |
خروجی TypeScript با NodeNext در dist/ |
vitest.config.ts |
پیکربندی Vitest برای src/**/*.test.ts |
package.json |
اسکریپتها، وابستگیهای زمان اجرا، openclaw.extensions: ["./dist/index.js"] |
openclaw.plugin.json |
فراداده مانیفست تولیدشده برای ابزار اولیه |
npm run plugin:build ابتدا npm run build (tsc) و سپس
openclaw plugins build --entry ./dist/index.js را اجرا میکند. npm run plugin:validate
دوباره میسازد و openclaw plugins validate --entry ./dist/index.js را اجرا میکند.
اعتبارسنجی موفق این پیام را چاپ میکند:
افزونه stock-quotes معتبر است.گزینههای openclaw plugins init <id>:
| پرچم | پیشفرض | اثر |
|---|---|---|
--directory <path> |
<id> |
پوشه خروجی |
--name <name> |
<id> با حروف عنوانی |
نام نمایشی |
--type <type> |
tool |
نوع داربست: tool یا provider |
--force |
غیرفعال | بازنویسی پوشه خروجی موجود |
نوشتن ابزار
defineToolPlugin هویت افزونه، یک طرحواره پیکربندی اختیاری و یک
فهرست ایستای ابزارها را میگیرد. نوع پارامترها و پیکربندی از
طرحوارههای TypeBox استنتاج میشود.
export default defineToolPlugin({ id: "stock-quotes", name: "Stock Quotes", description: "Fetch stock quote snapshots.", configSchema: Type.Object({ apiKey: Type.Optional(Type.String({ description: "Quote API key." })), baseUrl: Type.Optional(Type.String({ description: "Quote API base URL." })), }), tools: (tool) => [ tool({ name: "stock_quote", label: "Stock Quote", description: "Fetch a stock quote snapshot.", parameters: Type.Object({ symbol: Type.String({ description: "Ticker symbol, for example OPEN." }), }), async execute({ symbol }, config, context) { context.signal?.throwIfAborted(); return { symbol: symbol.toUpperCase(), configured: Boolean(config.apiKey), baseUrl: config.baseUrl ?? "https://api.example.com", }; }, }), ],});نام ابزارها API پایدار هستند. نامهایی را انتخاب کنید که یکتا، با حروف کوچک و بهاندازه کافی مشخص باشند تا با ابزارهای هسته یا افزونههای دیگر تداخل نکنند.
ابزارهای اختیاری و کارخانهای
زمانی optional: true را تنظیم کنید که کاربران باید پیش از ارسال ابزار به مدل، آن را
صراحتاً در فهرست مجاز قرار دهند. openclaw plugins build ورودی مانیفست متناظر
toolMetadata.<tool>.optional را مینویسد تا OpenClaw بتواند بدون بارگذاری کد زمان اجرای افزونه
اختیاری بودن ابزار را تشخیص دهد.
tool({ name: "workflow_run", description: "Run an external workflow.", parameters: Type.Object({ goal: Type.String() }), optional: true, execute: ({ goal }) => ({ queued: true, goal }),});زمانی از factory استفاده کنید که ابزار پیش از ساختهشدن به زمینه ابزار زمان اجرا نیاز دارد؛
برای انصراف در یک اجرای خاص، بررسی وضعیت سندباکس یا اتصال
کمککنندههای زمان اجرا. با اینکه ابزار واقعی در زمان اجرا ساخته میشود،
فراداده ایستا باقی میماند.
tool({ name: "local_workflow", description: "Run a local workflow outside sandboxed sessions.", parameters: Type.Object({ goal: Type.String() }), optional: true, factory({ api, toolContext }) { if (toolContext.sandboxed) { return null; } return createLocalWorkflowTool(api); },});کارخانهها همچنان نام ثابتی را از پیش برای ابزار اعلام میکنند. زمانی مستقیماً از definePluginEntry
استفاده کنید که افزونه نام ابزارها را بهصورت پویا محاسبه میکند یا ابزارها را
با هوکها، سرویسها، ارائهدهندگان یا فرمانها ترکیب میکند.
مقادیر بازگشتی
defineToolPlugin مقادیر بازگشتی ساده را در قالب نتیجه ابزار OpenClaw
بستهبندی میکند:
- زمانی رشته برگردانید که مدل باید دقیقاً همان متن را ببیند.
- زمانی مقداری سازگار با JSON برگردانید که میخواهید مدل JSON قالببندیشده را ببیند
و OpenClaw مقدار اصلی را در
detailsنگه دارد.
tool({ name: "echo_text", description: "Echo input text.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => input,});tool({ name: "echo_json", description: "Echo input as structured JSON.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => ({ input, length: input.length }),});زمانی از ابزار کارخانهای استفاده کنید که به یک AgentToolResult سفارشی نیاز دارید یا میخواهید از
پیادهسازی موجود api.registerTool دوباره استفاده کنید.
پیکربندی
configSchema اختیاری است. آن را حذف کنید تا OpenClaw یک طرحواره سختگیرانه شیء خالی
اعمال کند؛ مانیفست تولیدشده همچنان شامل configSchema خواهد بود.
export default defineToolPlugin({ id: "no-config-tools", name: "No Config Tools", description: "Adds tools that do not need configuration.", tools: () => [],});با یک configSchema، نوع آرگومان دوم execute از آن استنتاج میشود:
const configSchema = Type.Object({ apiKey: Type.String(),}); export default defineToolPlugin({ id: "configured-tools", name: "Configured Tools", description: "Adds configured tools.", configSchema, tools: (tool) => [ tool({ name: "configured_ping", description: "Check whether configuration is available.", parameters: Type.Object({}), execute: (_params, config) => ({ hasKey: config.apiKey.length > 0 }), }), ],});OpenClaw پیکربندی افزونه را از ورودی آن افزونه در پیکربندی Gateway میخواند. اطلاعات محرمانه را در کد منبع یا نمونههای مستندات بهصورت ثابت ننویسید؛ مطابق مدل امنیتی افزونه از پیکربندی، متغیرهای محیطی یا SecretRefها استفاده کنید.
فراداده تولیدشده
OpenClaw باید پیش از واردکردن کد زمان اجرای افزونه، مانیفست افزونه را بخواند.
defineToolPlugin فراداده ایستا را برای این کار ارائه میکند و
openclaw plugins build آن را در بسته مینویسد. پس از تغییر شناسه، نام، توضیحات، طرحواره پیکربندی، فعالسازی یا نام ابزارهای
افزونه، مولد را دوباره اجرا کنید:
npm run buildopenclaw plugins build --entry ./dist/index.jsمانیفست تولیدشده برای افزونهای با یک ابزار:
{ "id": "stock-quotes", "name": "Stock Quotes", "description": "Fetch stock quote snapshots.", "version": "0.1.0", "configSchema": { "type": "object", "additionalProperties": false, "properties": {} }, "activation": { "onStartup": true }, "contracts": { "tools": ["stock_quote"] }}contracts.tools قرارداد مهم کشف است: به OpenClaw میگوید کدام
افزونه مالک هر ابزار است، بدون اینکه زمان اجرای همه افزونههای نصبشده بارگذاری شود. مانیفست
قدیمی باعث میشود ابزاری در کشف ظاهر نشود یا خطای ثبت بهاشتباه به افزونه دیگری
نسبت داده شود.
فراداده بسته
openclaw plugins build همچنین package.json را با ورودی زمان اجرای انتخابشده
همراستا میکند:
{ "type": "module", "files": ["dist", "openclaw.plugin.json", "README.md"], "dependencies": { "typebox": "^1.1.38" }, "peerDependencies": { "openclaw": ">=2026.5.17" }, "openclaw": { "extensions": ["./dist/index.js"] }}JavaScript ساختهشده (./dist/index.js) را ارائه کنید، نه ورودی کد منبع TypeScript.
ورودیهای کد منبع فقط برای توسعه محلی در فضای کاری عمل میکنند.
اعتبارسنجی در CI
اگر فراداده تولیدشده قدیمی باشد، plugins build --check بدون بازنویسی فایلها
با شکست مواجه میشود:
npm run buildopenclaw plugins build --entry ./dist/index.js --checkopenclaw plugins validate --entry ./dist/index.jsnpm testplugins validate بررسی میکند که:
openclaw.plugin.jsonوجود داشته باشد و از بارگذار عادی مانیفست عبور کند.- ورودی فعلی فراداده
defineToolPluginرا صادر کند. - فیلدهای مانیفست تولیدشده با فراداده ورودی مطابقت داشته باشند.
contracts.toolsبا نام ابزارهای اعلامشده مطابقت داشته باشد.package.json،openclaw.extensionsرا به ورودی زمان اجرای انتخابشده اشاره دهد.
نصب و بررسی محلی
از یک نسخه جداگانه OpenClaw یا CLI نصبشده، مسیر بسته را نصب کنید:
openclaw plugins install ./stock-quotesopenclaw plugins inspect stock-quotes --runtimeبرای آزمون دود بستهبندیشده، ابتدا بسته را بسازید و tarball را نصب کنید:
npm packopenclaw plugins install npm-pack:./openclaw-plugin-stock-quotes-0.1.0.tgzopenclaw plugins inspect stock-quotes --runtime --jsonپس از نصب، Gateway را راهاندازی مجدد یا بازبارگذاری کنید و از عامل بخواهید از ابزار استفاده کند. اگر ابزار قابلمشاهده نیست، پیش از تغییر کد، زمان اجرای افزونه و کاتالوگ مؤثر ابزار را بررسی کنید (به عیبیابی مراجعه کنید).
انتشار
پس از آمادهشدن بسته، آن را از طریق ClawHub منتشر کنید. clawhub package publish
یک منبع میگیرد: پوشه محلی، مخزن GitHub (owner/repo[@ref]) یا
نشانی URL یک tarball.
clawhub package publish ./stock-quotes --dry-runclawhub package publish ./stock-quotesبا یک مکانیاب صریح ClawHub نصب کنید:
openclaw plugins install clawhub:your-org/stock-quotesدر دوره گذار عرضه، مشخصات ساده بسته npm همچنان از npm نصب میشوند، اما ClawHub سطح ترجیحی کشف و توزیع برای افزونههای OpenClaw است. برای دامنه مالک و بازبینی انتشار، به انتشار در ClawHub مراجعه کنید.
عیبیابی
plugin entry not found: ./dist/index.js
فایل ورودی انتخابشده وجود ندارد. npm run build را اجرا کنید، سپس
openclaw plugins build --entry ./dist/index.js یا
openclaw plugins validate --entry ./dist/index.js را دوباره اجرا کنید.
plugin entry does not expose defineToolPlugin metadata
ورودی، مقداری ساختهشده توسط defineToolPlugin را صادر نکرد. تأیید کنید که
صادرات پیشفرض ماژول، نتیجه defineToolPlugin(...) است یا ورودی
صحیح را با --entry ارسال کنید.
openclaw.plugin.json generated metadata is stale
مانیفست دیگر با فراداده ورودی مطابقت ندارد. اجرا کنید:
npm run buildopenclaw plugins build --entry ./dist/index.jsتغییرات هر دو openclaw.plugin.json و package.json را ثبت کنید.
package.json openclaw.extensions must include ./dist/index.js
فراداده بسته به ورودی زمان اجرای دیگری اشاره میکند.
openclaw plugins build --entry ./dist/index.js را اجرا کنید تا مولد،
فراداده بسته را با ورودیای که قصد ارائه آن را دارید همراستا کند.
Cannot find package 'typebox'
افزونه ساختهشده در زمان اجرا typebox را وارد میکند. آن را در dependencies
نگه دارید، دوباره نصب و ساخته و اعتبارسنجی را مجدداً اجرا کنید.
ابزار پس از نصب ظاهر نمیشود
این موارد را بهترتیب بررسی کنید:
openclaw plugins inspect <plugin-id> --runtimeopenclaw plugins validate --root <plugin-root> --entry ./dist/index.jsopenclaw.plugin.jsonدارایcontracts.toolsبا نامهای مورد انتظار ابزارها است.package.jsonدارایopenclaw.extensions: ["./dist/index.js"]است.- Gateway پس از نصب Plugin بازراهاندازی یا بازخوانی شده است.