Plugins

ساخت Plugin‌ها

Pluginها OpenClaw را با قابلیت‌های جدید گسترش می‌دهند: کانال‌ها، ارائه‌دهندگان مدل، گفتار، رونویسی بلادرنگ، صدای بلادرنگ، درک رسانه، تولید تصویر، تولید ویدئو، دریافت وب، جستجوی وب، ابزارهای عامل، یا هر ترکیبی از آن‌ها.

نیازی نیست Plugin خود را به مخزن OpenClaw اضافه کنید. در ClawHub منتشر کنید و کاربران با openclaw plugins install clawhub:<package-name> نصب می‌کنند. مشخصات بستهٔ خام همچنان در دورهٔ گذار راه‌اندازی از npm نصب می‌شوند.

پیش‌نیازها

  • Node >= 22 و یک مدیر بسته (npm یا pnpm)
  • آشنایی با TypeScript (ESM)
  • برای Pluginهای داخل مخزن: مخزن clone شده باشد و pnpm install انجام شده باشد. توسعهٔ Plugin از checkout منبع فقط با pnpm انجام می‌شود، چون OpenClaw Pluginهای باندل‌شده را از بسته‌های فضای کاری extensions/* بارگذاری می‌کند.

چه نوع Plugin؟

برای Plugin کانالی که تضمین نمی‌شود هنگام اجرای ورود اولیه/راه‌اندازی نصب شده باشد، از createOptionalChannelSetupSurface(...) از openclaw/plugin-sdk/channel-setup استفاده کنید. این یک جفت adapter راه‌اندازی + wizard تولید می‌کند که نیازمندی نصب را اعلام می‌کند و تا زمانی که Plugin نصب نشده باشد، در نوشتن پیکربندی واقعی به‌صورت بسته شکست می‌خورد.

شروع سریع: Plugin ابزار

این راهنما یک Plugin حداقلی می‌سازد که یک ابزار عامل را ثبت می‌کند. Pluginهای کانال و ارائه‌دهنده راهنماهای اختصاصی دارند که در بالا پیوند شده‌اند.

  • بسته و manifest را ایجاد کنید

    {
    "name": "@myorg/openclaw-my-plugin",
    "version": "1.0.0",
    "type": "module",
    "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 به یک manifest نیاز دارد، حتی بدون پیکربندی. ابزارهایی که در زمان اجرا ثبت می‌شوند باید در contracts.tools فهرست شوند تا OpenClaw بتواند Plugin مالک را بدون بارگذاری runtime هر Plugin کشف کند. Pluginها همچنین باید activation.onStartup را آگاهانه اعلام کنند. این نمونه آن را روی true تنظیم می‌کند. برای schema کامل، Manifest را ببینید. snippetهای canonical انتشار ClawHub در docs/snippets/plugin-publish/ قرار دارند.

  • نقطهٔ ورود را بنویسید

    // index.ts
    import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
    import { Type } from "@sinclair/typebox";
    
    export default definePluginEntry({
      id: "my-plugin",
      name: "My Plugin",
      description: "Adds a custom tool to OpenClaw",
      register(api) {
        api.registerTool({
          name: "my_tool",
          description: "Do a thing",
          parameters: Type.Object({ input: Type.String() }),
          async execute(_id, params) {
            return { content: [{ type: "text", text: `Got: ${params.input}` }] };
          },
        });
      },
    });
    

    definePluginEntry برای Pluginهای غیرکانالی است. برای کانال‌ها، از defineChannelPluginEntry استفاده کنید - Pluginهای کانال را ببینید. برای گزینه‌های کامل نقطهٔ ورود، نقاط ورود را ببینید.

  • آزمایش و انتشار

    Pluginهای خارجی: با ClawHub اعتبارسنجی و منتشر کنید، سپس نصب کنید:

    clawhub package publish your-org/your-plugin --dry-run
    clawhub package publish your-org/your-plugin
    openclaw plugins install clawhub:@myorg/openclaw-my-plugin
    

    مشخصات بستهٔ خام مانند @myorg/openclaw-my-plugin در دورهٔ گذار راه‌اندازی از npm نصب می‌شوند. وقتی resolution از ClawHub می‌خواهید، از clawhub: استفاده کنید.

    Pluginهای داخل مخزن: زیر درخت فضای کاری Plugin باندل‌شده قرار دهید - به‌صورت خودکار کشف می‌شود.

    pnpm test -- <bundled-plugin-root>/my-plugin/
    
  • قابلیت‌های Plugin

    یک Plugin واحد می‌تواند هر تعداد قابلیت را از طریق شیء api ثبت کند:

    قابلیت روش ثبت راهنمای تفصیلی
    استنتاج متن (LLM) api.registerProvider(...) Pluginهای ارائه‌دهنده
    backend استنتاج CLI api.registerCliBackend(...) backendهای CLI
    کانال / پیام‌رسانی api.registerChannel(...) Pluginهای کانال
    گفتار (TTS/STT) api.registerSpeechProvider(...) Pluginهای ارائه‌دهنده
    رونویسی بلادرنگ api.registerRealtimeTranscriptionProvider(...) Pluginهای ارائه‌دهنده
    صدای بلادرنگ api.registerRealtimeVoiceProvider(...) Pluginهای ارائه‌دهنده
    درک رسانه api.registerMediaUnderstandingProvider(...) Pluginهای ارائه‌دهنده
    تولید تصویر api.registerImageGenerationProvider(...) Pluginهای ارائه‌دهنده
    تولید موسیقی api.registerMusicGenerationProvider(...) Pluginهای ارائه‌دهنده
    تولید ویدئو api.registerVideoGenerationProvider(...) Pluginهای ارائه‌دهنده
    دریافت وب api.registerWebFetchProvider(...) Pluginهای ارائه‌دهنده
    جستجوی وب api.registerWebSearchProvider(...) Pluginهای ارائه‌دهنده
    middleware نتیجهٔ ابزار api.registerAgentToolResultMiddleware(...) نمای کلی SDK
    ابزارهای عامل api.registerTool(...) در ادامه
    فرمان‌های سفارشی api.registerCommand(...) نقاط ورود
    هوک‌های Plugin api.on(...) هوک‌های Plugin
    هوک‌های رویداد داخلی api.registerHook(...) نقاط ورود
    routeهای HTTP api.registerHttpRoute(...) جزئیات داخلی
    زیر‌فرمان‌های CLI api.registerCli(...) نقاط ورود

    برای API کامل ثبت، نمای کلی SDK را ببینید.

    Pluginهای باندل‌شده می‌توانند وقتی به بازنویسی async نتیجهٔ ابزار پیش از دیده‌شدن خروجی توسط مدل نیاز دارند، از api.registerAgentToolResultMiddleware(...) استفاده کنند. runtimeهای هدف را در contracts.agentToolResultMiddleware اعلام کنید، برای مثال ["pi", "codex"]. این یک seam مورد اعتماد برای Plugin باندل‌شده است؛ Pluginهای خارجی باید هوک‌های معمول OpenClaw Plugin را ترجیح دهند، مگر اینکه OpenClaw برای این قابلیت یک سیاست اعتماد صریح اضافه کند.

    اگر Plugin شما متدهای RPC سفارشی Gateway را ثبت می‌کند، آن‌ها را روی یک پیشوند مختص Plugin نگه دارید. namespaceهای مدیریتی core (config.*, exec.approvals.*, wizard.*, update.*) رزرو می‌مانند و همیشه به operator.admin resolve می‌شوند، حتی اگر یک Plugin scope محدودتری درخواست کند.

    معنای guardهای هوک که باید در نظر داشته باشید:

    • before_tool_call: { block: true } نهایی است و handlerهای با اولویت پایین‌تر را متوقف می‌کند.
    • before_tool_call: { block: false } به‌عنوان نبود تصمیم در نظر گرفته می‌شود.
    • before_tool_call: { requireApproval: true } اجرای عامل را مکث می‌کند و از کاربر از طریق overlay تأیید exec، دکمه‌های Telegram، تعاملات Discord، یا فرمان /approve روی هر کانال تأیید می‌خواهد.
    • before_install: { block: true } نهایی است و handlerهای با اولویت پایین‌تر را متوقف می‌کند.
    • before_install: { block: false } به‌عنوان نبود تصمیم در نظر گرفته می‌شود.
    • message_sending: { cancel: true } نهایی است و handlerهای با اولویت پایین‌تر را متوقف می‌کند.
    • message_sending: { cancel: false } به‌عنوان نبود تصمیم در نظر گرفته می‌شود.
    • message_received: وقتی به routing thread/topic ورودی نیاز دارید، فیلد typed threadId را ترجیح دهید. metadata را برای موارد اضافی مختص کانال نگه دارید.
    • message_sending: فیلدهای routing typed replyToId / threadId را به کلیدهای metadata مختص کانال ترجیح دهید.

    فرمان /approve هم تأییدهای exec و هم تأییدهای Plugin را با fallback محدود مدیریت می‌کند: وقتی id تأیید exec پیدا نشود، OpenClaw همان id را از طریق تأییدهای Plugin دوباره امتحان می‌کند. forwarding تأیید Plugin می‌تواند به‌طور مستقل از طریق approvals.plugin در config پیکربندی شود.

    اگر لوله‌کشی تأیید سفارشی باید همان حالت fallback محدود را تشخیص دهد، به‌جای تطبیق دستی رشته‌های انقضای تأیید، isApprovalNotFoundError از openclaw/plugin-sdk/error-runtime را ترجیح دهید.

    برای نمونه‌ها و مرجع هوک، هوک‌های Plugin را ببینید.

    ثبت ابزارهای عامل

    ابزارها تابع‌های typed هستند که LLM می‌تواند آن‌ها را فراخوانی کند. آن‌ها می‌توانند الزامی (همیشه در دسترس) یا اختیاری (با انتخاب کاربر) باشند:

    register(api) {
      // Required tool - always available
      api.registerTool({
        name: "my_tool",
        description: "Do a thing",
        parameters: Type.Object({ input: Type.String() }),
        async execute(_id, params) {
          return { content: [{ type: "text", text: params.input }] };
        },
      });
    
      // Optional tool - user must add to allowlist
      api.registerTool(
        {
          name: "workflow_tool",
          description: "Run a workflow",
          parameters: Type.Object({ pipeline: Type.String() }),
          async execute(_id, params) {
            return { content: [{ type: "text", text: params.pipeline }] };
          },
        },
        { optional: true },
      );
    }
    

    هر ابزاری که با api.registerTool(...) ثبت می‌شود باید در manifest Plugin نیز اعلام شود:

    {
      "contracts": {
        "tools": ["my_tool", "workflow_tool"]
      },
      "toolMetadata": {
        "workflow_tool": {
          "optional": true
        }
      }
    }
    

    OpenClaw توصیف‌گر اعتبارسنجی‌شده را از ابزار ثبت‌شده ضبط و کش می‌کند، بنابراین plugins داده‌های description یا schema را در manifest تکرار نمی‌کنند. قرارداد manifest فقط مالکیت و کشف را اعلام می‌کند؛ اجرا همچنان پیاده‌سازی زنده ابزار ثبت‌شده را فراخوانی می‌کند. برای ابزارهایی که با api.registerTool(..., { optional: true }) ثبت شده‌اند، مقدار toolMetadata.<tool>.optional: true را تنظیم کنید تا OpenClaw بتواند تا زمانی که ابزار به‌صراحت در فهرست مجاز قرار نگرفته، از بارگذاری runtime آن Plugin خودداری کند.

    کاربران ابزارهای اختیاری را در پیکربندی فعال می‌کنند:

    {
      tools: { allow: ["workflow_tool"] },
    }
    
    • نام ابزارها نباید با ابزارهای هسته تداخل داشته باشد (تداخل‌ها نادیده گرفته می‌شوند)
    • ابزارهایی با اشیای ثبت‌نام نادرست، از جمله مواردی که parameters ندارند، به‌جای خراب‌کردن اجرای agentها نادیده گرفته می‌شوند و در diagnostics مربوط به Plugin گزارش می‌شوند
    • برای ابزارهایی با اثرات جانبی یا نیازمندی‌های دودویی اضافی از optional: true استفاده کنید
    • کاربران می‌توانند با افزودن شناسه Plugin به tools.allow همه ابزارهای یک Plugin را فعال کنند

    ثبت فرمان‌های CLI

    Plugins می‌توانند با api.registerCli گروه‌های فرمان ریشه openclaw اضافه کنند. برای هر ریشه فرمان سطح‌بالا descriptors ارائه دهید تا OpenClaw بتواند بدون بارگذاری مشتاقانه runtime همه Pluginها، فرمان را نمایش داده و مسیریابی کند.

    register(api) {
      api.registerCli(
        ({ program }) => {
          const demo = program
            .command("demo-plugin")
            .description("Run demo plugin commands");
    
          demo
            .command("ping")
            .description("Check that the plugin CLI is executable")
            .action(() => {
              console.log("demo-plugin:pong");
            });
        },
        {
          descriptors: [
            {
              name: "demo-plugin",
              description: "Run demo plugin commands",
              hasSubcommands: true,
            },
          ],
        },
      );
    }
    

    پس از نصب، ثبت runtime را بررسی کنید و فرمان را اجرا کنید:

    openclaw plugins inspect demo-plugin --runtime --json
    openclaw demo-plugin ping
    

    قراردادهای import

    همیشه از مسیرهای متمرکز openclaw/plugin-sdk/<subpath> import کنید:

    
    
    // Wrong: monolithic root (deprecated, will be removed)
    
    

    برای مرجع کامل زیرمسیرها، نمای کلی SDK را ببینید.

    درون Plugin خود، برای importهای داخلی از فایل‌های barrel محلی (api.ts، runtime-api.ts) استفاده کنید - هرگز Plugin خودتان را از طریق مسیر SDK آن import نکنید.

    برای Pluginهای provider، helperهای ویژه provider را در همان barrelهای ریشه package نگه دارید مگر اینکه آن مرز واقعاً عمومی باشد. نمونه‌های bundled فعلی:

    • Anthropic: wrapperهای جریان Claude و helperهای service_tier / beta
    • OpenAI: سازنده‌های provider، helperهای مدل پیش‌فرض، providerهای realtime
    • OpenRouter: سازنده provider به‌همراه helperهای onboarding/پیکربندی

    اگر یک helper فقط درون یک package مربوط به provider bundled مفید است، آن را به‌جای ارتقا دادن به openclaw/plugin-sdk/* روی همان مرز ریشه package نگه دارید.

    برخی مرزهای helper تولیدشده openclaw/plugin-sdk/<bundled-id> هنوز برای نگهداری bundled-plugin زمانی وجود دارند که استفاده مالک ثبت‌شده داشته باشند. با آن‌ها به‌عنوان سطح‌های رزروشده برخورد کنید، نه الگوی پیش‌فرض برای Pluginهای شخص ثالث جدید.

    چک‌لیست پیش از ارسال

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s package.json metadata درست openclaw را دارد OPENCLAW_DOCS_MARKER:calloutClose:

    OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s manifest 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: