Plugins
Tworzenie Pluginów
Pluginy rozszerzają OpenClaw o nowe możliwości: kanały, dostawców modeli, mowę, transkrypcję w czasie rzeczywistym, głos w czasie rzeczywistym, rozumienie mediów, generowanie obrazów, generowanie wideo, pobieranie z sieci, wyszukiwanie w sieci, narzędzia agentów albo dowolną kombinację.
Nie musisz dodawać swojego pluginu do repozytorium OpenClaw. Opublikuj go w
ClawHub, a użytkownicy zainstalują go poleceniem
openclaw plugins install clawhub:<package-name>. Same specyfikacje pakietów nadal
instalują z npm podczas przejścia uruchomieniowego.
Wymagania wstępne
- Node >= 22 i menedżer pakietów (npm lub pnpm)
- Znajomość TypeScript (ESM)
- W przypadku pluginów w repozytorium: sklonowane repozytorium i wykonane
pnpm install. Tworzenie pluginów w checkoutcie źródeł jest obsługiwane tylko przez pnpm, ponieważ OpenClaw ładuje dołączone pluginy z pakietów workspaceextensions/*.
Jaki rodzaj pluginu?
Połącz OpenClaw z platformą komunikacyjną (Discord, IRC itd.)
Dodaj dostawcę modelu (LLM, proxy lub niestandardowy endpoint)
Zamapuj lokalne AI CLI na tekstowy fallback runner OpenClaw
Zarejestruj narzędzia agentów, hooki zdarzeń lub usługi - kontynuuj poniżej
W przypadku pluginu kanału, który nie ma gwarancji, że będzie zainstalowany podczas
onboardingu/konfiguracji, użyj createOptionalChannelSetupSurface(...) z
openclaw/plugin-sdk/channel-setup. Tworzy on parę adaptera konfiguracji i kreatora,
która informuje o wymaganiu instalacji i bezpiecznie odmawia rzeczywistych zapisów konfiguracji,
dopóki plugin nie zostanie zainstalowany.
Szybki start: plugin narzędzia
Ten przewodnik tworzy minimalny plugin, który rejestruje narzędzie agenta. Pluginy kanałów i dostawców mają dedykowane przewodniki podlinkowane powyżej.
Utwórz pakiet i 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
}
}
Każdy plugin potrzebuje manifestu, nawet bez konfiguracji. Narzędzia rejestrowane w runtime
muszą być wymienione w contracts.tools, aby OpenClaw mógł wykryć plugin będący właścicielem
bez ładowania runtime każdego pluginu. Pluginy powinny też celowo deklarować
activation.onStartup. Ten przykład ustawia ją na true. Pełny schemat znajduje się w
Manifeście. Kanoniczne fragmenty publikacji w ClawHub
znajdują się w docs/snippets/plugin-publish/.
Napisz punkt wejścia
// 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 jest przeznaczone dla pluginów innych niż kanałowe. W przypadku kanałów użyj
defineChannelPluginEntry - zobacz Pluginy kanałów.
Pełne opcje punktu wejścia opisano w Punktach wejścia.
Przetestuj i opublikuj
Pluginy zewnętrzne: zweryfikuj i opublikuj za pomocą ClawHub, a następnie zainstaluj:
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
openclaw plugins install clawhub:@myorg/openclaw-my-plugin
Same specyfikacje pakietów, takie jak @myorg/openclaw-my-plugin, instalują z npm podczas
przejścia uruchomieniowego. Użyj clawhub:, gdy chcesz rozwiązywania przez ClawHub.
Pluginy w repozytorium: umieść je w drzewie workspace dołączonych pluginów - zostaną wykryte automatycznie.
pnpm test -- <bundled-plugin-root>/my-plugin/
Możliwości pluginów
Jeden plugin może zarejestrować dowolną liczbę możliwości przez obiekt api:
| Możliwość | Metoda rejestracji | Szczegółowy przewodnik |
|---|---|---|
| Inferencja tekstu (LLM) | api.registerProvider(...) |
Pluginy dostawców |
| Backend inferencji CLI | api.registerCliBackend(...) |
Pluginy backendu CLI |
| Kanał / komunikacja | api.registerChannel(...) |
Pluginy kanałów |
| Mowa (TTS/STT) | api.registerSpeechProvider(...) |
Pluginy dostawców |
| Transkrypcja w czasie rzeczywistym | api.registerRealtimeTranscriptionProvider(...) |
Pluginy dostawców |
| Głos w czasie rzeczywistym | api.registerRealtimeVoiceProvider(...) |
Pluginy dostawców |
| Rozumienie mediów | api.registerMediaUnderstandingProvider(...) |
Pluginy dostawców |
| Generowanie obrazów | api.registerImageGenerationProvider(...) |
Pluginy dostawców |
| Generowanie muzyki | api.registerMusicGenerationProvider(...) |
Pluginy dostawców |
| Generowanie wideo | api.registerVideoGenerationProvider(...) |
Pluginy dostawców |
| Pobieranie z sieci | api.registerWebFetchProvider(...) |
Pluginy dostawców |
| Wyszukiwanie w sieci | api.registerWebSearchProvider(...) |
Pluginy dostawców |
| Middleware wyników narzędzi | api.registerAgentToolResultMiddleware(...) |
Omówienie SDK |
| Narzędzia agentów | api.registerTool(...) |
Poniżej |
| Niestandardowe polecenia | api.registerCommand(...) |
Punkty wejścia |
| Hooki pluginów | api.on(...) |
Hooki pluginów |
| Wewnętrzne hooki zdarzeń | api.registerHook(...) |
Punkty wejścia |
| Trasy HTTP | api.registerHttpRoute(...) |
Mechanizmy wewnętrzne |
| Podpolecenia CLI | api.registerCli(...) |
Punkty wejścia |
Pełne API rejestracji opisano w Omówieniu SDK.
Dołączone pluginy mogą używać api.registerAgentToolResultMiddleware(...), gdy
potrzebują asynchronicznego przepisywania wyników narzędzi, zanim model zobaczy dane wyjściowe. Zadeklaruj
docelowe runtime’y w contracts.agentToolResultMiddleware, na przykład
["pi", "codex"]. To zaufany punkt integracji dołączonych pluginów; pluginy zewnętrzne
powinny preferować zwykłe hooki pluginów OpenClaw, dopóki OpenClaw nie rozwinie
jawnej polityki zaufania dla tej możliwości.
Jeśli Twój plugin rejestruje niestandardowe metody RPC Gateway, trzymaj je pod
prefiksem właściwym dla pluginu. Główne administracyjne przestrzenie nazw (config.*,
exec.approvals.*, wizard.*, update.*) pozostają zarezerwowane i zawsze rozwiązują się do
operator.admin, nawet jeśli plugin poprosi o węższy zakres.
Semantyka strażników hooków, o której warto pamiętać:
before_tool_call:{ block: true }jest terminalne i zatrzymuje handlery o niższym priorytecie.before_tool_call:{ block: false }jest traktowane jak brak decyzji.before_tool_call:{ requireApproval: true }wstrzymuje wykonanie agenta i prosi użytkownika o zatwierdzenie przez nakładkę zatwierdzeń exec, przyciski Telegram, interakcje Discord albo polecenie/approvew dowolnym kanale.before_install:{ block: true }jest terminalne i zatrzymuje handlery o niższym priorytecie.before_install:{ block: false }jest traktowane jak brak decyzji.message_sending:{ cancel: true }jest terminalne i zatrzymuje handlery o niższym priorytecie.message_sending:{ cancel: false }jest traktowane jak brak decyzji.message_received: preferuj typowane polethreadId, gdy potrzebujesz routingu przychodzącego wątku/tematu. Zachowajmetadatana dodatki specyficzne dla kanału.message_sending: preferuj typowane pola routingureplyToId/threadIdzamiast kluczy metadanych specyficznych dla kanału.
Polecenie /approve obsługuje zarówno zatwierdzenia exec, jak i pluginów z ograniczonym fallbackiem: gdy identyfikator zatwierdzenia exec nie zostanie znaleziony, OpenClaw ponawia próbę użycia tego samego identyfikatora w zatwierdzeniach pluginów. Przekazywanie zatwierdzeń pluginów można skonfigurować niezależnie przez approvals.plugin w konfiguracji.
Jeśli niestandardowa obsługa zatwierdzeń musi wykryć ten sam przypadek ograniczonego fallbacku,
preferuj isApprovalNotFoundError z openclaw/plugin-sdk/error-runtime
zamiast ręcznie dopasowywać ciągi wygasania zatwierdzeń.
Przykłady i referencję hooków znajdziesz w Hookach pluginów.
Rejestrowanie narzędzi agentów
Narzędzia to typowane funkcje, które LLM może wywoływać. Mogą być wymagane (zawsze dostępne) albo opcjonalne (użytkownik musi je włączyć):
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 },
);
}
Każde narzędzie zarejestrowane przez api.registerTool(...) musi być również zadeklarowane w
manifeście pluginu:
{
"contracts": {
"tools": ["my_tool", "workflow_tool"]
},
"toolMetadata": {
"workflow_tool": {
"optional": true
}
}
}
OpenClaw przechwytuje i buforuje zweryfikowany deskryptor z zarejestrowanego narzędzia,
więc pluginy nie duplikują danych description ani schematu w manifeście. Kontrakt
manifestu deklaruje tylko własność i wykrywanie; wykonanie nadal wywołuje
aktywną implementację zarejestrowanego narzędzia.
Ustaw toolMetadata.<tool>.optional: true dla narzędzi zarejestrowanych za pomocą
api.registerTool(..., { optional: true }), aby OpenClaw mógł uniknąć ładowania
runtime tego pluginu, dopóki narzędzie nie zostanie jawnie dodane do listy dozwolonych.
Użytkownicy włączają opcjonalne narzędzia w konfiguracji:
{
tools: { allow: ["workflow_tool"] },
}
- Nazwy narzędzi nie mogą kolidować z narzędziami rdzenia (konflikty są pomijane)
- Narzędzia z nieprawidłowo sformułowanymi obiektami rejestracji, w tym z brakującym
parameters, są pomijane i zgłaszane w diagnostyce pluginu zamiast przerywać uruchomienia agenta - Użyj
optional: truedla narzędzi ze skutkami ubocznymi lub dodatkowymi wymaganiami binarnymi - Użytkownicy mogą włączyć wszystkie narzędzia z pluginu, dodając identyfikator pluginu do
tools.allow
Rejestrowanie poleceń CLI
Pluginy mogą dodawać główne grupy poleceń openclaw za pomocą api.registerCli. Podaj
descriptors dla każdego najwyższego poziomu głównego polecenia, aby OpenClaw mógł wyświetlać i kierować
polecenie bez gorliwego ładowania runtime każdego pluginu.
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,
},
],
},
);
}
Po instalacji zweryfikuj rejestrację runtime i wykonaj polecenie:
openclaw plugins inspect demo-plugin --runtime --json
openclaw demo-plugin ping
Konwencje importu
Zawsze importuj ze skoncentrowanych ścieżek openclaw/plugin-sdk/<subpath>:
// Wrong: monolithic root (deprecated, will be removed)
Pełne odniesienie do podścieżek znajdziesz w Przeglądzie SDK.
W swoim pluginie używaj lokalnych plików zbiorczych (api.ts, runtime-api.ts) dla
importów wewnętrznych - nigdy nie importuj własnego pluginu przez jego ścieżkę SDK.
W przypadku pluginów dostawców trzymaj pomocniki specyficzne dla dostawcy w tych plikach zbiorczych katalogu głównego pakietu, chyba że seam jest naprawdę ogólny. Obecne dołączone przykłady:
- Anthropic: wrappery strumienia Claude oraz pomocniki
service_tier/ beta - OpenAI: konstruktory dostawców, pomocniki modeli domyślnych, dostawcy realtime
- OpenRouter: konstruktor dostawcy oraz pomocniki onboardingu/konfiguracji
Jeśli pomocnik jest przydatny tylko w jednym dołączonym pakiecie dostawcy, trzymaj go na tym
seam katalogu głównego pakietu zamiast promować go do openclaw/plugin-sdk/*.
Niektóre wygenerowane pomocnicze seam openclaw/plugin-sdk/<bundled-id> nadal istnieją na potrzeby
utrzymania dołączonych pluginów, gdy mają śledzone użycie właściciela. Traktuj je jako
powierzchnie zarezerwowane, a nie jako domyślny wzorzec dla nowych pluginów innych firm.
Lista kontrolna przed przesłaniem
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
package.json ma poprawne metadane openclaw
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s Manifest openclaw.plugin.json jest obecny i prawidłowy OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
Punkt wejścia używa defineChannelPluginEntry albo definePluginEntry
OPENCLAW_DOCS_MARKER:calloutClose:
OPENCLAW_DOCS_MARKER:calloutOpen:Q2hlY2s
Wszystkie importy używają skoncentrowanych ścieżek plugin-sdk/<subpath>
OPENCLAW_DOCS_MARKER:calloutClose: