Building plugins
إضافات الأدوات
يبني defineToolPlugin مكوّنًا إضافيًا لا يضيف سوى أدوات يمكن للوكيل استدعاؤها: بلا
قناة أو موفّر نماذج أو خطاف أو خدمة أو واجهة إعداد خلفية. وهو يولّد
بيانات البيان الوصفية التي يحتاجها OpenClaw لاكتشاف الأدوات دون تحميل
شفرة وقت تشغيل المكوّن الإضافي.
بالنسبة إلى المكوّنات الإضافية الخاصة بالموفّرين أو القنوات أو الخطافات أو الخدمات أو ذات القدرات المختلطة، ابدأ بدلًا من ذلك بـ بناء المكوّنات الإضافية أو مكوّنات القنوات الإضافية، أو مكوّنات الموفّرين الإضافية.
المتطلبات
- Node 22.19+ أو Node 23.11+ أو Node 24+.
- مخرجات حزمة 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 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 |
بيانات بيان وصفية مولّدة للأداة الأولية |
يشغّل 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 is valid.خيارات 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. لا تضمّن الأسرار مباشرةً في المصدر أو أمثلة التوثيق؛ استخدم الإعداد أو متغيرات البيئة أو SecretRefs وفقًا لنموذج أمان المكوّن الإضافي.
البيانات الوصفية المولّدة
يجب أن يقرأ 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 testيتحقق plugins validate مما يلي:
- وجود
openclaw.plugin.jsonواجتيازه لمحمّل البيان المعتاد. - تصدير نقطة الدخول الحالية للبيانات الوصفية الخاصة بـ
defineToolPlugin. - تطابق حقول البيان المولّد مع البيانات الوصفية لنقطة الدخول.
- تطابق
contracts.toolsمع أسماء الأدوات المصرّح بها. - إشارة
openclaw.extensionsفيpackage.jsonإلى نقطة دخول وقت التشغيل المحددة.
التثبيت والفحص محليًا
من نسخة مستقلة من 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.js- يحتوي
openclaw.plugin.jsonعلىcontracts.toolsبأسماء الأدوات المتوقعة. - يحتوي
package.jsonعلىopenclaw.extensions: ["./dist/index.js"]. - أُعيد تشغيل Gateway أو أُعيد تحميله بعد تثبيت الـ Plugin.