Building plugins

Plugin công cụ

defineToolPlugin tạo một Plugin chỉ bổ sung các công cụ mà tác nhân có thể gọi: không có kênh, nhà cung cấp mô hình, hook, dịch vụ hoặc backend thiết lập. Hàm này tạo siêu dữ liệu manifest mà OpenClaw cần để khám phá công cụ mà không phải tải mã runtime của Plugin.

Đối với các Plugin nhà cung cấp, kênh, hook, dịch vụ hoặc đa khả năng, thay vào đó hãy bắt đầu với Xây dựng Plugin, Plugin kênh, hoặc Plugin nhà cung cấp.

Yêu cầu

  • Node 22.19+, Node 23.11+ hoặc Node 24+.
  • Đầu ra gói TypeScript ESM.
  • typebox trong dependencies (không chỉ trong devDependencies - Plugin được tạo sẽ nhập gói này trong thời gian chạy).
  • openclaw >=2026.5.17, phiên bản đầu tiên xuất openclaw/plugin-sdk/tool-plugin.
  • Thư mục gốc của gói phân phối dist/, openclaw.plugin.jsonpackage.json.

Bắt đầu nhanh

bash
openclaw plugins init stock-quotes --name "Stock Quotes"cd stock-quotesnpm installnpm run plugin:buildnpm run plugin:validatenpm test

plugins init tạo khung:

Tệp Mục đích
src/index.ts Điểm vào defineToolPlugin với một công cụ echo
src/index.test.ts Kiểm thử siêu dữ liệu xác nhận danh sách công cụ
tsconfig.json Đầu ra TypeScript NodeNext vào dist/
vitest.config.ts Cấu hình Vitest cho src/**/*.test.ts
package.json Script, phụ thuộc runtime, openclaw.extensions: ["./dist/index.js"]
openclaw.plugin.json Siêu dữ liệu manifest được tạo cho công cụ ban đầu

npm run plugin:build chạy npm run build (tsc), sau đó chạy openclaw plugins build --entry ./dist/index.js. npm run plugin:validate xây dựng lại và chạy openclaw plugins validate --entry ./dist/index.js. Khi xác thực thành công, kết quả sau sẽ được in:

text
Plugin stock-quotes is valid.

Các tùy chọn của openclaw plugins init <id>:

Cờ Mặc định Tác dụng
--directory <path> <id> Thư mục đầu ra
--name <name> <id> viết kiểu tiêu đề Tên hiển thị
--type <type> tool Loại khung: tool hoặc provider
--force tắt Ghi đè thư mục đầu ra hiện có

Viết một công cụ

defineToolPlugin nhận định danh Plugin, một lược đồ cấu hình tùy chọn và một danh sách công cụ tĩnh. Kiểu tham số và cấu hình được suy luận từ các lược đồ TypeBox.

typescript
  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",        };      },    }),  ],});

Tên công cụ là API ổn định. Hãy chọn tên duy nhất, viết thường và đủ cụ thể để tránh xung đột với các công cụ lõi hoặc Plugin khác.

Công cụ tùy chọn và công cụ factory

Đặt optional: true khi người dùng cần đưa công cụ vào danh sách cho phép một cách rõ ràng trước khi công cụ được gửi đến mô hình. openclaw plugins build ghi mục manifest toolMetadata.<tool>.optional tương ứng, nhờ đó OpenClaw có thể nhận biết công cụ là tùy chọn mà không phải tải mã runtime của Plugin.

typescript
tool({  name: "workflow_run",  description: "Run an external workflow.",  parameters: Type.Object({ goal: Type.String() }),  optional: true,  execute: ({ goal }) => ({ queued: true, goal }),});

Sử dụng factory khi công cụ cần ngữ cảnh công cụ runtime trước khi có thể được tạo — để từ chối tham gia một lượt chạy cụ thể, kiểm tra trạng thái sandbox hoặc liên kết các trình trợ giúp runtime. Siêu dữ liệu vẫn ở trạng thái tĩnh dù công cụ cụ thể được tạo trong thời gian chạy.

typescript
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);  },});

Factory vẫn khai báo trước một tên công cụ cố định. Sử dụng trực tiếp definePluginEntry khi Plugin tính toán tên công cụ một cách động hoặc kết hợp công cụ với hook, dịch vụ, nhà cung cấp hoặc lệnh.

Giá trị trả về

defineToolPlugin bọc các giá trị trả về thuần túy vào định dạng kết quả công cụ của OpenClaw:

  • Trả về một chuỗi khi mô hình cần thấy chính xác văn bản đó.
  • Trả về một giá trị tương thích với JSON khi bạn muốn mô hình thấy JSON đã định dạng và OpenClaw lưu giữ giá trị gốc trong details.
typescript
tool({  name: "echo_text",  description: "Echo input text.",  parameters: Type.Object({    input: Type.String(),  }),  execute: ({ input }) => input,});
typescript
tool({  name: "echo_json",  description: "Echo input as structured JSON.",  parameters: Type.Object({    input: Type.String(),  }),  execute: ({ input }) => ({ input, length: input.length }),});

Sử dụng công cụ factory khi bạn cần một AgentToolResult tùy chỉnh hoặc muốn tái sử dụng một phần triển khai api.registerTool hiện có.

Cấu hình

configSchema là tùy chọn. Nếu bỏ qua, OpenClaw áp dụng một lược đồ đối tượng rỗng nghiêm ngặt; manifest được tạo vẫn bao gồm configSchema.

typescript
export default defineToolPlugin({  id: "no-config-tools",  name: "No Config Tools",  description: "Adds tools that do not need configuration.",  tools: () => [],});

Khi có configSchema, đối số execute thứ hai được định kiểu từ lược đồ đó:

typescript
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 đọc cấu hình Plugin từ mục của Plugin trong cấu hình Gateway. Không mã hóa cứng thông tin bí mật trong mã nguồn hoặc ví dụ tài liệu; hãy sử dụng cấu hình, biến môi trường hoặc SecretRefs theo mô hình bảo mật của Plugin.

Siêu dữ liệu được tạo

OpenClaw phải đọc manifest của Plugin trước khi nhập mã runtime của Plugin. defineToolPlugin cung cấp siêu dữ liệu tĩnh cho mục đích này và openclaw plugins build ghi siêu dữ liệu đó vào gói. Chạy lại trình tạo sau khi thay đổi mã định danh, tên, mô tả, lược đồ cấu hình, cơ chế kích hoạt hoặc tên công cụ của Plugin:

bash
npm run buildopenclaw plugins build --entry ./dist/index.js

Manifest được tạo cho một Plugin có một công cụ:

json
{  "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 là hợp đồng khám phá quan trọng: nó cho OpenClaw biết Plugin nào sở hữu từng công cụ mà không phải tải runtime của mọi Plugin đã cài đặt. Một manifest lỗi thời có thể khiến công cụ biến mất khỏi quá trình khám phá hoặc khiến lỗi đăng ký bị quy cho sai Plugin.

Siêu dữ liệu gói

openclaw plugins build cũng đồng bộ package.json với điểm vào runtime đã chọn:

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"]  }}

Phân phối JavaScript đã xây dựng (./dist/index.js), không phải điểm vào mã nguồn TypeScript. Điểm vào mã nguồn chỉ hoạt động khi phát triển cục bộ trong workspace.

Xác thực trong CI

plugins build --check thất bại mà không ghi lại tệp khi siêu dữ liệu được tạo đã lỗi thời:

bash
npm run buildopenclaw plugins build --entry ./dist/index.js --checkopenclaw plugins validate --entry ./dist/index.jsnpm test

plugins validate kiểm tra rằng:

  • openclaw.plugin.json tồn tại và vượt qua trình tải manifest thông thường.
  • Điểm vào hiện tại xuất siêu dữ liệu defineToolPlugin.
  • Các trường manifest được tạo khớp với siêu dữ liệu của điểm vào.
  • contracts.tools khớp với các tên công cụ đã khai báo.
  • package.json trỏ openclaw.extensions đến điểm vào runtime đã chọn.

Cài đặt và kiểm tra cục bộ

Từ một bản checkout OpenClaw riêng biệt hoặc CLI đã cài đặt, hãy cài đặt đường dẫn gói:

bash
openclaw plugins install ./stock-quotesopenclaw plugins inspect stock-quotes --runtime

Để kiểm thử nhanh gói đã đóng gói, trước tiên hãy đóng gói rồi cài đặt tệp tarball:

bash
npm packopenclaw plugins install npm-pack:./openclaw-plugin-stock-quotes-0.1.0.tgzopenclaw plugins inspect stock-quotes --runtime --json

Sau khi cài đặt, hãy khởi động lại hoặc tải lại Gateway và yêu cầu tác nhân sử dụng công cụ. Nếu công cụ không hiển thị, hãy kiểm tra runtime của Plugin và danh mục công cụ có hiệu lực trước khi thay đổi mã (xem Khắc phục sự cố).

Phát hành

Phát hành thông qua ClawHub sau khi gói đã sẵn sàng. clawhub package publish nhận một nguồn: thư mục cục bộ, kho lưu trữ GitHub (owner/repo[@ref]) hoặc URL tarball.

bash
clawhub package publish ./stock-quotes --dry-runclawhub package publish ./stock-quotes

Cài đặt bằng bộ định vị ClawHub rõ ràng:

bash
openclaw plugins install clawhub:your-org/stock-quotes

Các đặc tả gói npm thuần vẫn được cài đặt từ npm trong giai đoạn chuyển đổi khi ra mắt, nhưng ClawHub là bề mặt khám phá và phân phối ưu tiên cho các Plugin OpenClaw. Xem Phát hành trên ClawHub để biết phạm vi chủ sở hữu và quy trình đánh giá bản phát hành.

Khắc phục sự cố

plugin entry not found: ./dist/index.js

Tệp điểm vào đã chọn không tồn tại. Chạy npm run build, sau đó chạy lại openclaw plugins build --entry ./dist/index.js hoặc openclaw plugins validate --entry ./dist/index.js.

plugin entry does not expose defineToolPlugin metadata

Điểm vào không xuất một giá trị được tạo bởi defineToolPlugin. Hãy xác nhận phần xuất mặc định của mô-đun là kết quả defineToolPlugin(...), hoặc truyền điểm vào chính xác bằng --entry.

openclaw.plugin.json generated metadata is stale

Manifest không còn khớp với siêu dữ liệu của điểm vào. Chạy:

bash
npm run buildopenclaw plugins build --entry ./dist/index.js

Commit cả các thay đổi đối với openclaw.plugin.jsonpackage.json.

package.json openclaw.extensions must include ./dist/index.js

Siêu dữ liệu gói trỏ đến một điểm vào runtime khác. Chạy openclaw plugins build --entry ./dist/index.js để trình tạo đồng bộ siêu dữ liệu gói với điểm vào mà bạn định phân phối.

Cannot find package 'typebox'

Plugin đã xây dựng nhập typebox trong thời gian chạy. Hãy giữ gói này trong dependencies, cài đặt lại, xây dựng lại và chạy lại quá trình xác thực.

Công cụ không xuất hiện sau khi cài đặt

Kiểm tra các mục sau theo thứ tự:

  1. openclaw plugins inspect <plugin-id> --runtime
  2. openclaw plugins validate --root <plugin-root> --entry ./dist/index.js
  3. openclaw.plugin.jsoncontracts.tools với các tên công cụ như mong đợi.
  4. package.jsonopenclaw.extensions: ["./dist/index.js"].
  5. Gateway đã được khởi động lại hoặc tải lại sau khi cài đặt plugin.

Xem thêm

Was this useful?
On this page

On this page