Building plugins
Plugins الأدوات
defineToolPlugin ينشئ plugin لا يضيف سوى أدوات قابلة للاستدعاء من الوكيل: من دون
قناة، أو موفّر نماذج، أو خطاف، أو خدمة، أو واجهة خلفية للإعداد. ويولّد
بيانات manifest الوصفية التي يحتاج إليها OpenClaw لاكتشاف الأدوات من دون تحميل شيفرة
وقت تشغيل plugin.
بالنسبة إلى plugins الخاصة بالموفّرين أو القنوات أو الخطافات أو الخدمات أو ذات الإمكانات المختلطة، ابدأ بدلًا من ذلك بـ إنشاء plugins، أو Plugins القنوات، أو Plugins الموفّرين.
المتطلبات
- Node 22.22.3+، أو Node 24.15+، أو Node 25.9+.
- مخرجات حزمة TypeScript ESM.
typeboxفيdependencies(وليس فقطdevDependencies- إذ يستورده plugin المولّد في وقت التشغيل).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 testينشئ plugins 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 |
بيانات manifest الوصفية المولّدة للأداة الأولية |
يشغّل 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.
تطبع عملية التحقق الناجحة:
Plugin stock-quotes صالح.خيارات openclaw plugins init <id>:
| العلامة | القيمة الافتراضية | التأثير |
|---|---|---|
--directory <path> |
<id> |
دليل المخرجات |
--name <name> |
<id> بحالة أحرف العنوان |
اسم العرض |
--type <type> |
tool |
نوع الهيكل: tool أو provider |
--force |
معطّل | استبدال دليل مخرجات موجود |
كتابة أداة
تأخذ defineToolPlugin هوية plugin، ومخطط إعداد اختياريًا، وقائمة
ثابتة من الأدوات. ويُستدل على أنواع المعاملات والإعداد من
مخططات 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 المستقرة. اختر أسماء فريدة، وبأحرف صغيرة، و محددة بما يكفي لتجنّب التعارض مع الأدوات الأساسية أو plugins الأخرى.
الأدوات الاختيارية وأدوات المصانع
عيّن optional: true عندما ينبغي للمستخدمين إضافة الأداة صراحةً إلى قائمة السماح قبل
إرسالها إلى نموذج. تكتب openclaw plugins build إدخال manifest المطابق
toolMetadata.<tool>.optional، بحيث يستطيع OpenClaw معرفة أن
الأداة اختيارية من دون تحميل شيفرة وقت تشغيل plugin.
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
مباشرةً عندما يحسب plugin أسماء الأدوات ديناميكيًا أو يدمج الأدوات
مع الخطافات أو الخدمات أو الموفّرين أو الأوامر.
قيم الإرجاع
تغلّف 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 مخطط كائن فارغًا صارمًا؛
ويظل manifest المولّد يتضمن 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 إعداد plugin من إدخال plugin في إعداد Gateway. لا تضمّن الأسرار مباشرةً في المصدر أو أمثلة التوثيق؛ استخدم الإعداد، أو متغيرات البيئة، أو SecretRefs وفقًا لنموذج أمان plugin.
البيانات الوصفية المولّدة
يجب أن يقرأ OpenClaw manifest الخاص بـ plugin قبل استيراد شيفرة وقت تشغيل plugin.
تكشف defineToolPlugin بيانات وصفية ثابتة لهذا الغرض، و
تكتبها openclaw plugins build في الحزمة. أعد تشغيل المولّد بعد
تغيير معرّف plugin أو اسمه أو وصفه أو مخطط إعداده أو تفعيله أو أسماء
الأدوات:
npm run buildopenclaw plugins build --entry ./dist/index.jsmanifest مولّد لـ plugin ذي أداة واحدة:
{ "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 بأي
plugin يملك كل أداة من دون تحميل وقت تشغيل كل plugin مثبّت. يعني
manifest القديم أن أداة قد تختفي من الاكتشاف، أو أن خطأ تسجيل
يُنسب إلى plugin غير الصحيح.
بيانات الحزمة الوصفية
تحاذي 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 testيتحقق plugins validate مما يلي:
- وجود
openclaw.plugin.jsonواجتيازه محمّل manifest المعتاد. - تصدير نقطة الدخول الحالية بيانات
defineToolPluginالوصفية. - تطابق حقول manifest المولّد مع بيانات نقطة الدخول الوصفية.
- تطابق
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 أو أعد تحميله واطلب من الوكيل استخدام الأداة. إذا لم تكن الأداة ظاهرة، فافحص وقت تشغيل plugin وكتالوج الأدوات الفعّال قبل تغيير الشيفرة (راجع استكشاف الأخطاء وإصلاحها).
النشر
انشر عبر 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 هو سطح الاكتشاف والتوزيع المفضّل لـ plugins الخاصة بـ 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
لم يعد manifest يطابق بيانات نقطة الدخول الوصفية. شغّل:
npm run buildopenclaw plugins build --entry ./dist/index.jsثبّت تغييرات كل من openclaw.plugin.json وpackage.json في commit.
package.json openclaw.extensions must include ./dist/index.js
تشير بيانات الحزمة الوصفية إلى نقطة دخول وقت تشغيل مختلفة. شغّل
openclaw plugins build --entry ./dist/index.js كي يحاذي المولّد
بيانات الحزمة الوصفية مع نقطة الدخول التي تنوي شحنها.
Cannot find package 'typebox'
يستورد plugin المبني 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.