Building plugins
Pluginy narzędziowe
defineToolPlugin tworzy Plugin, który dodaje wyłącznie narzędzia wywoływane przez agenta: bez
kanału, dostawcy modeli, haka, usługi ani zaplecza konfiguracji. Generuje
metadane manifestu potrzebne OpenClaw do wykrywania narzędzi bez ładowania
kodu środowiska uruchomieniowego Pluginu.
W przypadku Pluginów dostawców, kanałów, haków, usług lub Pluginów o mieszanych możliwościach zacznij zamiast tego od Tworzenie Pluginów, Pluginy kanałów albo Pluginy dostawców.
Wymagania
- Node 22.19+, Node 23.11+ lub Node 24+.
- Pakiet TypeScript ESM generujący dane wyjściowe.
typeboxwdependencies(nie tylko wdevDependencies— wygenerowany Plugin importuje go w czasie działania).openclaw >=2026.5.17, czyli pierwsza wersja eksportującaopenclaw/plugin-sdk/tool-plugin.- Katalog główny pakietu zawierający
dist/,openclaw.plugin.jsonorazpackage.json.
Szybki start
openclaw plugins init stock-quotes --name "Stock Quotes"cd stock-quotesnpm installnpm run plugin:buildnpm run plugin:validatenpm testplugins init tworzy szkielet:
| Plik | Przeznaczenie |
|---|---|
src/index.ts |
Punkt wejścia defineToolPlugin z jednym narzędziem echo |
src/index.test.ts |
Test metadanych sprawdzający listę narzędzi |
tsconfig.json |
Dane wyjściowe TypeScript NodeNext w dist/ |
vitest.config.ts |
Konfiguracja Vitest dla src/**/*.test.ts |
package.json |
Skrypty, zależności środowiska uruchomieniowego, openclaw.extensions: ["./dist/index.js"] |
openclaw.plugin.json |
Wygenerowane metadane manifestu dla początkowego narzędzia |
npm run plugin:build uruchamia npm run build (tsc), a następnie
openclaw plugins build --entry ./dist/index.js. npm run plugin:validate
ponownie buduje projekt i uruchamia openclaw plugins validate --entry ./dist/index.js.
Pomyślna walidacja wyświetla:
Plugin stock-quotes is valid.Opcje openclaw plugins init <id>:
| Flaga | Wartość domyślna | Działanie |
|---|---|---|
--directory <path> |
<id> |
Katalog wyjściowy |
--name <name> |
<id> w formacie tytułu |
Nazwa wyświetlana |
--type <type> |
tool |
Typ szkieletu: tool lub provider |
--force |
wyłączona | Zastępuje istniejący katalog wyjściowy |
Pisanie narzędzia
defineToolPlugin przyjmuje tożsamość Pluginu, opcjonalny schemat konfiguracji
oraz statyczną listę narzędzi. Typy parametrów i konfiguracji są wywnioskowane
ze schematów 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", }; }, }), ],});Nazwy narzędzi stanowią stabilny interfejs API. Wybieraj nazwy unikatowe, pisane małymi literami i wystarczająco szczegółowe, aby uniknąć kolizji z narzędziami rdzenia lub innych Pluginów.
Narzędzia opcjonalne i fabryczne
Ustaw optional: true, gdy użytkownicy powinni jawnie dodać narzędzie do listy
dozwolonych, zanim zostanie ono wysłane do modelu. openclaw plugins build
zapisuje odpowiadający wpis manifestu toolMetadata.<tool>.optional, dzięki
czemu OpenClaw może rozpoznać narzędzie jako opcjonalne bez ładowania kodu
środowiska uruchomieniowego Pluginu.
tool({ name: "workflow_run", description: "Run an external workflow.", parameters: Type.Object({ goal: Type.String() }), optional: true, execute: ({ goal }) => ({ queued: true, goal }),});Użyj factory, gdy narzędzie przed utworzeniem potrzebuje kontekstu narzędzia
środowiska uruchomieniowego — aby wyłączyć je dla konkretnego uruchomienia,
sprawdzić stan piaskownicy lub powiązać pomocnicze elementy środowiska
uruchomieniowego. Metadane pozostają statyczne, mimo że konkretne narzędzie
jest tworzone w czasie działania.
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); },});Fabryki nadal deklarują z góry stałą nazwę narzędzia. Użyj bezpośrednio
definePluginEntry, gdy Plugin dynamicznie oblicza nazwy narzędzi lub łączy
narzędzia z hakami, usługami, dostawcami albo poleceniami.
Wartości zwracane
defineToolPlugin opakowuje zwykłe wartości zwracane w format wyniku narzędzia
OpenClaw:
- Zwróć ciąg znaków, gdy model powinien zobaczyć dokładnie ten tekst.
- Zwróć wartość zgodną z JSON, gdy model powinien zobaczyć sformatowany JSON,
a OpenClaw ma zachować oryginalną wartość w
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 }),});Użyj narzędzia fabrycznego, gdy potrzebujesz niestandardowego
AgentToolResult lub chcesz ponownie wykorzystać istniejącą implementację
api.registerTool.
Konfiguracja
configSchema jest opcjonalny. Jeśli go pominiesz, OpenClaw zastosuje ścisły
schemat pustego obiektu; wygenerowany manifest nadal będzie zawierał
configSchema.
export default defineToolPlugin({ id: "no-config-tools", name: "No Config Tools", description: "Adds tools that do not need configuration.", tools: () => [],});W przypadku użycia configSchema typ drugiego argumentu execute jest z niego
wywnioskowany:
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 odczytuje konfigurację Pluginu z jego wpisu w konfiguracji Gateway. Nie zapisuj na stałe sekretów w kodzie źródłowym ani przykładach dokumentacji; zgodnie z modelem bezpieczeństwa Pluginu używaj konfiguracji, zmiennych środowiskowych lub SecretRefs.
Wygenerowane metadane
OpenClaw musi odczytać manifest Pluginu przed zaimportowaniem kodu jego
środowiska uruchomieniowego. defineToolPlugin udostępnia w tym celu statyczne
metadane, a openclaw plugins build zapisuje je w pakiecie. Uruchom generator
ponownie po zmianie identyfikatora, nazwy, opisu, schematu konfiguracji,
aktywacji lub nazw narzędzi Pluginu:
npm run buildopenclaw plugins build --entry ./dist/index.jsWygenerowany manifest Pluginu z jednym narzędziem:
{ "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 jest istotnym kontraktem wykrywania: informuje OpenClaw,
który Plugin jest właścicielem każdego narzędzia, bez ładowania środowiska
uruchomieniowego wszystkich zainstalowanych Pluginów. Nieaktualny manifest
może spowodować, że narzędzie nie zostanie wykryte albo błąd rejestracji
zostanie przypisany niewłaściwemu Pluginowi.
Metadane pakietu
openclaw plugins build dostosowuje również package.json do wybranego punktu
wejścia środowiska uruchomieniowego:
{ "type": "module", "files": ["dist", "openclaw.plugin.json", "README.md"], "dependencies": { "typebox": "^1.1.38" }, "peerDependencies": { "openclaw": ">=2026.5.17" }, "openclaw": { "extensions": ["./dist/index.js"] }}Publikuj zbudowany JavaScript (./dist/index.js), a nie punkt wejścia w kodzie
źródłowym TypeScript. Punkty wejścia w kodzie źródłowym działają wyłącznie
podczas programowania lokalnie w obszarze roboczym.
Walidacja w CI
plugins build --check kończy się niepowodzeniem bez nadpisywania plików,
gdy wygenerowane metadane są nieaktualne:
npm run buildopenclaw plugins build --entry ./dist/index.js --checkopenclaw plugins validate --entry ./dist/index.jsnpm testplugins validate sprawdza, czy:
openclaw.plugin.jsonistnieje i przechodzi standardowe wczytywanie manifestu.- Bieżący punkt wejścia eksportuje metadane
defineToolPlugin. - Wygenerowane pola manifestu odpowiadają metadanym punktu wejścia.
contracts.toolsodpowiada zadeklarowanym nazwom narzędzi.package.jsonwskazuje wopenclaw.extensionswybrany punkt wejścia środowiska uruchomieniowego.
Lokalna instalacja i inspekcja
W osobnym katalogu roboczym OpenClaw lub przy użyciu zainstalowanego CLI zainstaluj pakiet ze ścieżki:
openclaw plugins install ./stock-quotesopenclaw plugins inspect stock-quotes --runtimeAby przeprowadzić test dymny spakowanego pakietu, najpierw go spakuj, a następnie zainstaluj archiwum tar:
npm packopenclaw plugins install npm-pack:./openclaw-plugin-stock-quotes-0.1.0.tgzopenclaw plugins inspect stock-quotes --runtime --jsonPo instalacji uruchom ponownie lub przeładuj Gateway i poproś agenta o użycie narzędzia. Jeśli narzędzie nie jest widoczne, przed zmianą kodu sprawdź środowisko uruchomieniowe Pluginu i efektywny katalog narzędzi (zobacz Rozwiązywanie problemów).
Publikowanie
Gdy pakiet będzie gotowy, opublikuj go za pośrednictwem ClawHub.
clawhub package publish przyjmuje źródło: lokalny folder, repozytorium GitHub
(owner/repo[@ref]) lub adres URL archiwum tar.
clawhub package publish ./stock-quotes --dry-runclawhub package publish ./stock-quotesZainstaluj przy użyciu jawnego lokalizatora ClawHub:
openclaw plugins install clawhub:your-org/stock-quotesSame specyfikatory pakietów npm nadal instalują pakiety z npm w okresie przejściowym wdrożenia, ale ClawHub jest preferowaną platformą wykrywania i dystrybucji Pluginów OpenClaw. Informacje o zakresie właściciela i przeglądzie wydania znajdziesz w sekcji Publikowanie w ClawHub.
Rozwiązywanie problemów
plugin entry not found: ./dist/index.js
Wybrany plik punktu wejścia nie istnieje. Uruchom npm run build, a następnie
ponownie uruchom openclaw plugins build --entry ./dist/index.js albo
openclaw plugins validate --entry ./dist/index.js.
plugin entry does not expose defineToolPlugin metadata
Punkt wejścia nie wyeksportował wartości utworzonej przez defineToolPlugin.
Upewnij się, że domyślnym eksportem modułu jest wynik defineToolPlugin(...),
albo przekaż właściwy punkt wejścia za pomocą --entry.
openclaw.plugin.json generated metadata is stale
Manifest nie odpowiada już metadanym punktu wejścia. Uruchom:
npm run buildopenclaw plugins build --entry ./dist/index.jsZatwierdź zmiany zarówno w openclaw.plugin.json, jak i package.json.
package.json openclaw.extensions must include ./dist/index.js
Metadane pakietu wskazują inny punkt wejścia środowiska uruchomieniowego.
Uruchom openclaw plugins build --entry ./dist/index.js, aby generator
dostosował metadane pakietu do punktu wejścia, który zamierzasz opublikować.
Cannot find package 'typebox'
Zbudowany Plugin importuje typebox w czasie działania. Pozostaw go
w dependencies, ponownie zainstaluj zależności, przebuduj projekt i ponownie
uruchom walidację.
Narzędzie nie pojawia się po instalacji
Sprawdź kolejno następujące elementy:
openclaw plugins inspect <plugin-id> --runtimeopenclaw plugins validate --root <plugin-root> --entry ./dist/index.js- Plik
openclaw.plugin.jsonzawieracontracts.toolsz oczekiwanymi nazwami narzędzi. - Plik
package.jsonzawieraopenclaw.extensions: ["./dist/index.js"]. - Po zainstalowaniu pluginu Gateway został uruchomiony ponownie lub przeładowany.