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 należy zamiast tego zacząć od Tworzenie pluginów, Pluginy kanałów lub Pluginy dostawców.
Wymagania
- Node 22.22.3+, Node 24.15+ lub Node 25.9+.
- Pakiet wynikowy TypeScript ESM.
typeboxwdependencies(nie tylkodevDependencies— wygenerowany plugin importuje go w czasie działania).openclaw >=2026.5.17, 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 "Notowania giełdowe"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 |
Wynik kompilacji 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 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 wykonuje kompilację i uruchamia openclaw plugins validate --entry ./dist/index.js.
Pomyślna walidacja wyświetla:
Plugin stock-quotes jest prawidłowy.Opcje openclaw plugins init <id>:
| Flaga | Wartość domyślna | Działanie |
|---|---|---|
--directory <path> |
<id> |
Katalog wynikowy |
--name <name> |
<id> zapisany jak tytuł |
Nazwa wyświetlana |
--type <type> |
tool |
Typ szkieletu: tool lub provider |
--force |
wyłączona | Zastąpienie istniejącego katalogu wynikowego |
Tworzenie narzędzia
defineToolPlugin przyjmuje tożsamość pluginu, opcjonalny schemat konfiguracji oraz
statyczną listę narzędzi. Typy parametrów i konfiguracji są wywnioskowywane ze
schematów TypeBox.
export default defineToolPlugin({ id: "stock-quotes", name: "Notowania giełdowe", description: "Pobiera migawki notowań giełdowych.", configSchema: Type.Object({ apiKey: Type.Optional(Type.String({ description: "Klucz API notowań." })), baseUrl: Type.Optional(Type.String({ description: "Bazowy adres URL API notowań." })), }), tools: (tool) => [ tool({ name: "stock_quote", label: "Notowanie giełdowe", description: "Pobiera migawkę notowania giełdowego.", parameters: Type.Object({ symbol: Type.String({ description: "Symbol giełdowy, na przykład 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ą stabilne API. Należy wybierać nazwy unikatowe, zapisane małymi literami i na tyle szczegółowe, aby uniknąć kolizji z narzędziami podstawowymi lub innymi pluginami.
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 odpowiedni
wpis manifestu toolMetadata.<tool>.optional, dzięki czemu OpenClaw może rozpoznać, że
narzędzie jest opcjonalne, bez ładowania kodu środowiska uruchomieniowego pluginu.
tool({ name: "workflow_run", description: "Uruchamia zewnętrzny przepływ pracy.", parameters: Type.Object({ goal: Type.String() }), optional: true, execute: ({ goal }) => ({ queued: true, goal }),});Użyj factory, gdy narzędzie wymaga kontekstu narzędzia środowiska uruchomieniowego, zanim będzie mogło zostać
utworzone — aby zrezygnować z niego dla konkretnego uruchomienia, sprawdzić stan piaskownicy lub powiązać
funkcje pomocnicze środowiska uruchomieniowego. Metadane pozostają statyczne, mimo że konkretne narzędzie jest tworzone
w czasie działania.
tool({ name: "local_workflow", description: "Uruchamia lokalny przepływ pracy poza sesjami w piaskownicy.", 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: "Powtarza tekst wejściowy.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => input,});tool({ name: "echo_json", description: "Powtarza dane wejściowe jako ustrukturyzowany JSON.", parameters: Type.Object({ input: Type.String(), }), execute: ({ input }) => ({ input, length: input.length }),});Użyj narzędzia fabrycznego, gdy potrzebny jest niestandardowy AgentToolResult lub gdy ma zostać ponownie użyta
istniejąca implementacja api.registerTool.
Konfiguracja
configSchema jest opcjonalny. Jeśli zostanie pominięty, OpenClaw zastosuje ścisły schemat pustego obiektu;
wygenerowany manifest nadal będzie zawierał configSchema.
export default defineToolPlugin({ id: "no-config-tools", name: "Narzędzia bez konfiguracji", description: "Dodaje narzędzia, które nie wymagają konfiguracji.", tools: () => [],});W przypadku configSchema typ drugiego argumentu execute jest z niego wywnioskowywany:
const configSchema = Type.Object({ apiKey: Type.String(),}); export default defineToolPlugin({ id: "configured-tools", name: "Skonfigurowane narzędzia", description: "Dodaje skonfigurowane narzędzia.", configSchema, tools: (tool) => [ tool({ name: "configured_ping", description: "Sprawdza, czy konfiguracja jest dostępna.", parameters: Type.Object({}), execute: (_params, config) => ({ hasKey: config.apiKey.length > 0 }), }), ],});OpenClaw odczytuje konfigurację pluginu z jego wpisu w konfiguracji Gateway. Nie należy wpisywać na stałe sekretów w kodzie źródłowym ani przykładach dokumentacji; należy używać konfiguracji, zmiennych środowiskowych lub SecretRefs zgodnie z modelem zabezpieczeń pluginu.
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. Generator należy uruchomić 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": "Notowania giełdowe", "description": "Pobiera migawki notowań giełdowych.", "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ć brak narzędzia w wynikach wykrywania lub przypisanie błędu
rejestracji 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"] }}Należy dostarczać skompilowany JavaScript (./dist/index.js), a nie punkt wejścia kodu źródłowego TypeScript.
Punkty wejścia kodu źródłowego działają tylko podczas programowania lokalnie w obszarze roboczym.
Walidacja w CI
plugins build --check kończy się niepowodzeniem bez przepisywania 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 ładowanie manifestu.- Bieżący punkt wejścia eksportuje metadane
defineToolPlugin. - Pola wygenerowanego manifestu odpowiadają metadanym punktu wejścia.
contracts.toolsodpowiada zadeklarowanym nazwom narzędzi.package.jsonwskazuje za pomocąopenclaw.extensionswybrany punkt wejścia środowiska uruchomieniowego.
Instalacja i lokalna inspekcja
W osobnym repozytorium roboczym OpenClaw lub za pomocą zainstalowanego CLI zainstaluj pakiet ze ścieżki:
openclaw plugins install ./stock-quotesopenclaw plugins inspect stock-quotes --runtimeAby wykonać test dymny pakietu, najpierw utwórz pakiet i 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 oraz 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: folder lokalny, 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-quotesPodczas przejściowego okresu wdrożenia proste specyfikacje pakietów npm nadal są instalowane z npm, ale ClawHub jest preferowanym miejscem wykrywania i dystrybucji pluginów OpenClaw. Informacje o zakresie właściciela i przeglądzie wydania zawiera 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
openclaw plugins build --entry ./dist/index.js lub
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(...), lub 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 ma zostać dostarczony.
Cannot find package 'typebox'
Skompilowany plugin importuje typebox w czasie działania. Pozostaw go w dependencies,
zainstaluj ponownie, ponownie skompiluj i uruchom walidację.
Narzędzie nie pojawia się po instalacji
Sprawdź kolejno:
openclaw plugins inspect <plugin-id> --runtimeopenclaw plugins validate --root <plugin-root> --entry ./dist/index.jsopenclaw.plugin.jsonmacontracts.toolsz oczekiwanymi nazwami narzędzi.package.jsonmaopenclaw.extensions: ["./dist/index.js"].- Gateway został ponownie uruchomiony lub przeładowany po zainstalowaniu pluginu.