Co się zmienia
Stary system pluginów udostępniał dwie bardzo szerokie powierzchnie, które pozwalały pluginom importować wszystko, czego potrzebowały, z jednego punktu wejścia:openclaw/plugin-sdk/compat- pojedynczy import, który ponownie eksportował dziesiątki helperów. Został wprowadzony, aby starsze pluginy oparte na hookach nadal działały, gdy budowano nową architekturę pluginów.openclaw/plugin-sdk/infra-runtime- szeroki barrel helperów uruchomieniowych, który mieszał zdarzenia systemowe, stan heartbeat, kolejki dostarczania, helpery fetch/proxy, helpery plików, typy zatwierdzeń i niepowiązane narzędzia.openclaw/plugin-sdk/config-runtime- szeroki barrel zgodności konfiguracji, który wciąż przenosi przestarzałe bezpośrednie helpery ładowania/zapisu w okresie migracji.openclaw/extension-api- most, który dawał pluginom bezpośredni dostęp do helperów po stronie hosta, takich jak osadzony runner agenta.api.registerEmbeddedExtensionFactory(...)- usunięty hook bundled extension tylko dla osadzonego runnera, który mógł obserwować zdarzenia osadzonego runnera, takie jaktool_result.
Dlaczego to się zmieniło
Stare podejście powodowało problemy:- Powolny startup - import jednego helpera ładował dziesiątki niepowiązanych modułów
- Zależności cykliczne - szerokie ponowne eksporty ułatwiały tworzenie cykli importu
- Niejasna powierzchnia API - nie było sposobu, aby stwierdzić, które eksporty były stabilne, a które wewnętrzne
openclaw/plugin-sdk/\<subpath\>)
jest małym, samodzielnym modułem o jasnym przeznaczeniu i udokumentowanym kontrakcie.
Starsze wygodne seamy providerów dla bundled kanałów również zniknęły.
Helper seamy oznaczone marką kanału były prywatnymi skrótami mono-repo, a nie stabilnymi
kontraktami pluginów. Zamiast tego używaj wąskich, ogólnych podścieżek SDK. Wewnątrz bundled
przestrzeni roboczej pluginów trzymaj helpery należące do providera we własnym api.ts lub
runtime-api.ts tego pluginu.
Aktualne przykłady bundled providerów:
- Anthropic trzyma helpery strumieni specyficzne dla Claude we własnym seamie
api.ts/contract-api.ts - OpenAI trzyma buildery providerów, helpery modeli domyślnych i buildery providerów realtime
we własnym
api.ts - OpenRouter trzyma builder providera oraz helpery onboardingu/konfiguracji we własnym
api.ts
Plan migracji Talk i głosu realtime
Kod głosu realtime, telefonii, spotkań i przeglądarkowego Talk jest przenoszony z lokalnego dla powierzchni księgowania tur do współdzielonego kontrolera sesji Talk eksportowanego przezopenclaw/plugin-sdk/realtime-voice. Nowy kontroler odpowiada za wspólną kopertę
zdarzeń Talk, stan aktywnej tury, stan przechwytywania, stan dźwięku wyjściowego, ostatnią
historię zdarzeń i odrzucanie przestarzałych tur. Pluginy providerów powinny nadal odpowiadać za
sesje realtime specyficzne dla dostawcy; pluginy powierzchni powinny nadal odpowiadać za przechwytywanie,
odtwarzanie, telefonię i osobliwości spotkań.
Ta migracja Talk jest celowo czysto łamiąca:
- Utrzymaj współdzielony kontroler/prymitywy runtime w
plugin-sdk/realtime-voice. - Przenieś bundled powierzchnie na współdzielony kontroler: przekaźnik przeglądarkowy, przekazanie managed-room, realtime połączeń głosowych, strumieniowe STT połączeń głosowych, realtime Google Meet oraz natywne push-to-talk.
- Zastąp stare rodziny RPC Talk docelowym API
talk.session.*italk.client.*. - Ogłaszaj jeden aktywny kanał zdarzeń Talk w Gateway
hello-ok.features.events:talk.event. - Usuń stary endpoint HTTP realtime i każdą ścieżkę nadpisywania instrukcji w czasie żądania.
createTalkEventSequencer(...) bezpośrednio, chyba że
implementuje niskopoziomowy adapter lub fixture testowy. Preferuj współdzielony kontroler,
aby zdarzenia ograniczone do tury nie mogły być emitowane bez id tury, przestarzałe wywołania turnEnd /
turnCancel nie mogły wyczyścić nowszej aktywnej tury, a zdarzenia cyklu życia
dźwięku wyjściowego pozostawały spójne w telefonii, spotkaniach, przekaźniku przeglądarkowym, przekazaniu
managed-room i natywnych klientach Talk.
Docelowy kształt publicznego API to:
talk.client.create,
ponieważ przeglądarka odpowiada za negocjację providera i transport mediów, podczas gdy
Gateway odpowiada za poświadczenia, instrukcje i politykę narzędzi. talk.session.* jest
wspólną powierzchnią zarządzaną przez Gateway dla realtime gateway-relay, transkrypcji
gateway-relay i sesji STT/TTS natywnych managed-room.
Starsze konfiguracje, które umieszczały selektory realtime obok talk.provider /
talk.providers, powinny zostać naprawione przez openclaw doctor --fix; runtime Talk
nie interpretuje ponownie konfiguracji providera speech/TTS jako konfiguracji providera realtime.
Obsługiwane kombinacje talk.session.create są celowo niewielkie:
Zasady zgodności
Dla zewnętrznych pluginów prace nad zgodnością przebiegają w tej kolejności:- dodaj nowy kontrakt
- zachowaj stare zachowanie podłączone przez adapter zgodności
- emituj diagnostykę lub ostrzeżenie, które wskazuje starą ścieżkę i zamiennik
- pokryj obie ścieżki testami
- udokumentuj wycofanie i ścieżkę migracji
- usuń dopiero po ogłoszonym oknie migracji, zwykle w wydaniu major
pnpm plugins:boundary-report. Użyj pnpm plugins:boundary-report:summary dla
zwartych zliczeń, --owner <id> dla jednego pluginu lub właściciela zgodności oraz
pnpm plugins:boundary-report:ci, gdy bramka CI ma kończyć się niepowodzeniem przy zaległych
rekordach zgodności, zastrzeżonych importach SDK między właścicielami albo nieużywanych zastrzeżonych
podścieżkach SDK. Raport grupuje przestarzałe
rekordy zgodności według daty usunięcia, zlicza lokalne odwołania w kodzie/dokumentacji,
ujawnia zastrzeżone importy SDK między właścicielami i podsumowuje prywatny
most SDK memory-host, aby sprzątanie zgodności pozostawało jawne zamiast
polegać na doraźnych wyszukiwaniach. Zastrzeżone podścieżki SDK muszą mieć śledzone użycie przez właścicieli;
nieużywane zastrzeżone eksporty pomocnicze należy usunąć z publicznego SDK.
Jeśli pole manifestu jest nadal akceptowane, autorzy pluginów mogą go dalej używać, dopóki
dokumentacja i diagnostyka nie powiedzą inaczej. Nowy kod powinien preferować udokumentowany
zamiennik, ale istniejące pluginy nie powinny psuć się podczas zwykłych wydań minor.
Jak migrować
Migrate runtime config load/write helpers
api.runtime.config.loadConfig() i
api.runtime.config.writeConfigFile(...) bezpośrednio. Preferuj konfigurację, która została
już przekazana do aktywnej ścieżki wywołania. Długotrwałe handlery, które potrzebują
bieżącego zrzutu procesu, mogą użyć api.runtime.config.current(). Długotrwałe
narzędzia agenta powinny używać ctx.getRuntimeConfig() z kontekstu narzędzia wewnątrz
execute, aby narzędzie utworzone przed zapisem konfiguracji nadal widziało odświeżoną
konfigurację runtime.Zapisy konfiguracji muszą przechodzić przez pomocniki transakcyjne i wybrać
zasadę po zapisie:afterWrite: { mode: "restart", reason: "..." }, gdy wywołujący wie,
że zmiana wymaga czystego restartu gateway, oraz
afterWrite: { mode: "none", reason: "..." } tylko wtedy, gdy wywołujący odpowiada za
dalsze działania i celowo chce pominąć planner przeładowania.
Wyniki mutacji zawierają typowane podsumowanie followUp dla testów i logowania;
gateway pozostaje odpowiedzialny za zastosowanie lub zaplanowanie restartu.
loadConfig i writeConfigFile pozostają jako przestarzałe pomocniki zgodności
dla zewnętrznych pluginów w trakcie okna migracji i ostrzegają raz z
kodem zgodności runtime-config-load-write. Dołączone pluginy i kod runtime
repozytorium są chronione przez zabezpieczenia skanera w
pnpm check:deprecated-api-usage i
pnpm check:no-runtime-action-load-config: nowe użycie produkcyjnego pluginu
kończy się bezpośrednim niepowodzeniem, bezpośrednie zapisy konfiguracji zawodzą, metody serwera gateway muszą używać
zrzutu runtime żądania, pomocniki wysyłki/akcji/klienta kanału runtime
muszą otrzymywać konfigurację ze swojej granicy, a długotrwałe moduły runtime mają
zero dozwolonych otaczających wywołań loadConfig().Nowy kod pluginu powinien także unikać importowania szerokiego
barrela zgodności openclaw/plugin-sdk/config-runtime. Użyj wąskiej
podścieżki SDK dopasowanej do zadania:Migrate embedded tool-result extensions to middleware
api.registerEmbeddedExtensionFactory(...) przeznaczone tylko dla embedded-runnera
neutralnym wobec runtime middleware.contracts.agentToolResultMiddleware. Niezadeklarowane rejestracje zainstalowanego middleware
są odrzucane.Migrate approval-native handlers to capability facts
approvalCapability.nativeRuntime oraz współdzielony rejestr kontekstu runtime.Kluczowe zmiany:- Zastąp
approvalCapability.handler.loadRuntime(...)przezapprovalCapability.nativeRuntime - Przenieś autoryzację/dostarczanie specyficzne dla zatwierdzeń ze starego okablowania
plugin.auth/plugin.approvalsnaapprovalCapability ChannelPlugin.approvalszostało usunięte z publicznego kontraktu pluginu kanału; przenieś pola delivery/native/render naapprovalCapabilityplugin.authpozostaje tylko dla przepływów logowania/wylogowania kanału; hooki autoryzacji zatwierdzeń w tym miejscu nie są już odczytywane przez rdzeń- Rejestruj obiekty runtime należące do kanału, takie jak klienci, tokeny lub aplikacje Bolt,
przez
openclaw/plugin-sdk/channel-runtime-context - Nie wysyłaj powiadomień o przekierowaniu należących do pluginu z natywnych handlerów zatwierdzeń; rdzeń odpowiada teraz za powiadomienia o skierowaniu gdzie indziej na podstawie rzeczywistych wyników dostarczenia
- Przekazując
channelRuntimedocreateChannelManager(...), zapewnij rzeczywistą powierzchnięcreatePluginRuntime().channel. Częściowe stuby są odrzucane.
/plugins/sdk-channel-plugins, aby poznać bieżący układ capability zatwierdzeń.Audit Windows wrapper fallback behavior
openclaw/plugin-sdk/windows-spawn, nierozwiązane wrappery Windows
.cmd/.bat teraz zawodzą w trybie zamkniętym, chyba że jawnie przekażesz
allowShellFallback: true.allowShellFallback i zamiast tego obsłuż rzucony błąd.Find deprecated imports
Replace with focused imports
Replace broad infra-runtime imports
openclaw/plugin-sdk/infra-runtime nadal istnieje na potrzeby zgodności
zewnętrznej, ale nowy kod powinien importować zawężoną powierzchnię pomocniczą,
której faktycznie potrzebuje:infra-runtime, więc kod repozytorium
nie może cofnąć się do szerokiego barrela.Migrate channel route helpers
openclaw/plugin-sdk/channel-route.
Starsze nazwy klucza trasy i porównywalnego celu pozostają aliasami zgodności
w okresie migracji, ale nowe pluginy powinny używać nazw tras,
które bezpośrednio opisują zachowanie:{ channel, to, accountId, threadId }
w natywnych zatwierdzeniach, tłumieniu odpowiedzi, deduplikacji przychodzącej,
dostarczaniu Cron i routingu sesji.Nie dodawaj nowych użyć ChannelMessagingAdapter.parseExplicitTarget ani
pomocników załadowanych tras opartych na parserze (parseExplicitTargetForLoadedChannel
lub resolveRouteTargetForLoadedChannel) ani
resolveChannelRouteTargetWithParser(...) z plugin-sdk/channel-route.
Te hooki są przestarzałe i pozostają tylko dla starszych pluginów w okresie
migracji. Nowe pluginy kanałów powinny używać
messaging.targetResolver.resolveTarget(...) do normalizacji identyfikatora celu
i awaryjnej obsługi chybienia katalogu, messaging.inferTargetChatType(...), gdy core
potrzebuje wczesnego rodzaju peera, oraz messaging.resolveOutboundSessionRoute(...)
dla natywnej dla dostawcy sesji i tożsamości wątku.Build and test
Odwołanie do ścieżek importu
Common import path table
Common import path table
scripts/lib/plugin-sdk-entrypoints.json; eksporty pakietu są generowane z
publicznego podzbioru.
Zarezerwowane pomocnicze styki dla dołączonych plugins zostały wycofane z
publicznej mapy eksportów SDK z wyjątkiem jawnie udokumentowanych fasad
zgodności, takich jak przestarzały shim plugin-sdk/discord zachowany dla
opublikowanego pakietu @openclaw/discord@2026.3.13. Pomocniki specyficzne
dla właściciela znajdują się w pakiecie właścicielskiego plugin; wspólne
zachowanie hosta powinno przechodzić przez ogólne kontrakty SDK, takie jak
plugin-sdk/gateway-runtime, plugin-sdk/security-runtime i
plugin-sdk/plugin-config-runtime.
Użyj najwęższego importu pasującego do zadania. Jeśli nie możesz znaleźć
eksportu, sprawdź źródło w src/plugin-sdk/ albo zapytaj maintainerów, który
ogólny kontrakt powinien go posiadać.
Aktywne wycofania
Węższe wycofania, które mają zastosowanie w całym SDK plugin, kontrakcie providera, powierzchni runtime i manifeście. Każde z nich nadal działa dzisiaj, ale zostanie usunięte w przyszłej wersji major. Wpis pod każdym elementem mapuje stare API na jego kanoniczny zamiennik.Konstruktory pomocy command-auth → command-status
Konstruktory pomocy command-auth → command-status
openclaw/plugin-sdk/command-auth): buildCommandsMessage,
buildCommandsMessagePaginated, buildHelpMessage.Nowe (openclaw/plugin-sdk/command-status): te same sygnatury, te
same eksporty - tylko importowane z węższej podścieżki. command-auth
reeksportuje je jako stuby zgodności.Pomocniki bramkowania wzmianek → resolveInboundMentionDecision
Pomocniki bramkowania wzmianek → resolveInboundMentionDecision
resolveInboundMentionRequirement({ facts, policy }) i
shouldDropInboundForMention(...) z
openclaw/plugin-sdk/channel-inbound albo
openclaw/plugin-sdk/channel-mention-gating.Nowe: resolveInboundMentionDecision({ facts, policy }) - zwraca
pojedynczy obiekt decyzji zamiast dwóch rozdzielonych wywołań.Niżej położone plugins kanałów (Slack, Discord, Matrix, MS Teams) już się
przełączyły.Shim runtime kanału i pomocniki akcji kanału
Shim runtime kanału i pomocniki akcji kanału
openclaw/plugin-sdk/channel-runtime to shim zgodności dla starszych
plugins kanałów. Nie importuj go w nowym kodzie; użyj
openclaw/plugin-sdk/channel-runtime-context do rejestrowania obiektów
runtime.Pomocniki channelActions* w openclaw/plugin-sdk/channel-actions są
przestarzałe wraz z surowymi eksportami kanału “actions”. Udostępniaj
capabilities przez semantyczną powierzchnię presentation zamiast tego -
plugins kanałów deklarują, co renderują (karty, przyciski, selecty), a nie
które surowe nazwy akcji akceptują.Pomocnik providerów wyszukiwania w sieci tool() → createTool() w plugin
Pomocnik providerów wyszukiwania w sieci tool() → createTool() w plugin
tool() z openclaw/plugin-sdk/provider-web-search.Nowe: zaimplementuj createTool(...) bezpośrednio w plugin providera.
OpenClaw nie potrzebuje już pomocnika SDK do rejestrowania wrappera
narzędzia.Koperty kanałów w plaintext → BodyForAgent
Koperty kanałów w plaintext → BodyForAgent
formatInboundEnvelope(...) (i
ChannelMessageForAgent.channelEnvelope) do budowania płaskiej koperty
promptu w plaintext z przychodzących wiadomości kanału.Nowe: BodyForAgent oraz ustrukturyzowane bloki kontekstu użytkownika.
Plugins kanałów dołączają metadane routingu (wątek, temat, odpowiedź-do,
reakcje) jako typowane pola zamiast konkatenować je w ciąg promptu. Pomocnik
formatAgentEnvelope(...) nadal jest obsługiwany dla syntetyzowanych
kopert kierowanych do asystenta, ale przychodzące koperty w plaintext są
wycofywane.Dotknięte obszary: inbound_claim, message_received i każdy niestandardowy
plugin kanału, który przetwarzał tekst channelEnvelope po fakcie.Hook deactivate → gateway_stop
Hook deactivate → gateway_stop
api.on("deactivate", handler).Nowe: api.on("gateway_stop", handler). Zdarzenie i kontekst są tym
samym kontraktem sprzątania przy zamykaniu; zmienia się tylko nazwa hooka.deactivate pozostaje podłączone jako przestarzały alias zgodności do
czasu po 2026-08-16.Hook subagent_spawning → powiązanie wątku w core
Hook subagent_spawning → powiązanie wątku w core
api.on("subagent_spawning", handler) zwracające
threadBindingReady albo deliveryOrigin.Nowe: pozwól core przygotować powiązania subagentów thread: true
przez adapter powiązań sesji kanału. Używaj
api.on("subagent_spawned", handler) wyłącznie do obserwacji po
uruchomieniu.subagent_spawning, PluginHookSubagentSpawningEvent,
PluginHookSubagentSpawningResult i
SubagentLifecycleHookRunner.runSubagentSpawning(...) pozostają wyłącznie
jako przestarzałe powierzchnie zgodności, gdy zewnętrzne plugins migrują.Typy wykrywania providerów → typy katalogu providerów
Typy wykrywania providerów → typy katalogu providerów
ProviderCapabilities - plugins
providerów powinny używać jawnych hooków providera, takich jak
buildReplayPolicy, normalizeToolSchemas i wrapStreamFn, zamiast
statycznego obiektu.Hooki zasad Thinking → resolveThinkingProfile
Hooki zasad Thinking → resolveThinkingProfile
ProviderThinkingPolicy):
isBinaryThinking(ctx), supportsXHighThinking(ctx) i
resolveDefaultThinkingLevel(ctx).Nowe: pojedyncze resolveThinkingProfile(ctx), które zwraca
ProviderThinkingProfile z kanonicznym id, opcjonalnym label i
rankingowaną listą poziomów. OpenClaw automatycznie obniża nieaktualne
zapisane wartości według rangi profilu.Kontekst obejmuje provider, modelId, opcjonalnie scalone reasoning
oraz opcjonalnie scalone fakty compat modelu. Plugins providerów mogą
używać tych faktów katalogu, aby ujawniać profil specyficzny dla modelu
tylko wtedy, gdy skonfigurowany kontrakt żądania go obsługuje.Zaimplementuj jeden hook zamiast trzech. Starsze hooki nadal działają w
oknie wycofywania, ale nie są komponowane z wynikiem profilu.Zewnętrzni providerzy uwierzytelniania → contracts.externalAuthProviders
Zewnętrzni providerzy uwierzytelniania → contracts.externalAuthProviders
contracts.externalAuthProviders w manifeście plugin
oraz zaimplementuj resolveExternalAuthProfiles(...).Wyszukiwanie zmiennych env providera → setup.providers[].envVars
Wyszukiwanie zmiennych env providera → setup.providers[].envVars
providerAuthEnvVars: { anthropic: ["ANTHROPIC_API_KEY"] }.Nowe: odzwierciedl to samo wyszukiwanie zmiennych env w
setup.providers[].envVars w manifeście. Konsoliduje to metadane env dla
setup/status w jednym miejscu i unika uruchamiania runtime plugin tylko po
to, aby odpowiedzieć na zapytania o zmienne env.providerAuthEnvVars pozostaje obsługiwane przez adapter zgodności, dopóki
okno wycofywania się nie zamknie.Rejestracja plugin pamięci → registerMemoryCapability
Rejestracja plugin pamięci → registerMemoryCapability
api.registerMemoryPromptSection(...),
api.registerMemoryFlushPlan(...),
api.registerMemoryRuntime(...).Nowe: jedno wywołanie w API memory-state -
registerMemoryCapability(pluginId, { promptBuilder, flushPlanResolver, runtime }).Te same sloty, pojedyncze wywołanie rejestracji. Addytywne pomocniki promptu
i korpusu (registerMemoryPromptSupplement, registerMemoryCorpusSupplement)
nie są dotknięte.API providera embeddingów pamięci
API providera embeddingów pamięci
api.registerMemoryEmbeddingProvider(...) plus
contracts.memoryEmbeddingProviders.Nowe: api.registerEmbeddingProvider(...) plus
contracts.embeddingProviders.Ogólny kontrakt providera embeddingów jest wielokrotnego użytku poza
pamięcią i stanowi obsługiwaną ścieżkę dla nowych providerów. Specyficzne
dla pamięci API rejestracji pozostaje podłączone jako przestarzała zgodność,
gdy istniejący providerzy migrują. Inspekcja plugin zgłasza użycie poza
dołączonymi plugins jako dług zgodności.Zmieniono nazwy typów wiadomości sesji subagentów
Zmieniono nazwy typów wiadomości sesji subagentów
src/plugins/runtime/types.ts:readSession jest przestarzała na rzecz
getSessionMessages. Ta sama sygnatura; stara metoda wywołuje nową.runtime.tasks.flow → runtime.tasks.managedFlows
runtime.tasks.flow → runtime.tasks.managedFlows
runtime.tasks.flow (liczba pojedyncza) zwracało aktywny akcesor
przepływu zadań.Nowe: runtime.tasks.managedFlows utrzymuje zarządzany runtime mutacji
TaskFlow dla plugins, które tworzą, aktualizują, anulują lub uruchamiają
zadania podrzędne z przepływu. Użyj runtime.tasks.flows, gdy plugin
potrzebuje tylko odczytów opartych na DTO.Osadzone fabryki rozszerzeń → middleware wyników narzędzi agenta
Osadzone fabryki rozszerzeń → middleware wyników narzędzi agenta
api.registerEmbeddedExtensionFactory(...) dostępna tylko
dla osadzonego runnera została zastąpiona przez
api.registerAgentToolResultMiddleware(...) z jawną listą runtime w
contracts.agentToolResultMiddleware.Alias OpenClawSchemaType → OpenClawConfig
Alias OpenClawSchemaType → OpenClawConfig
OpenClawSchemaType reeksportowany z openclaw/plugin-sdk jest teraz
jednowierszowym aliasem dla OpenClawConfig. Preferuj kanoniczną nazwę.extensions/) są śledzone w ich własnych barrelach api.ts i
runtime-api.ts. Nie wpływają one na kontrakty plugins firm trzecich i nie są
tutaj wymienione. Jeśli korzystasz bezpośrednio z lokalnego barrela dołączonego
plugin, przeczytaj komentarze o wycofaniach w tym barrelu przed aktualizacją.Harmonogram usuwania
Tymczasowe wyciszanie ostrzeżeń
Ustaw te zmienne środowiskowe podczas pracy nad migracją:Powiązane
- Pierwsze kroki - zbuduj swój pierwszy plugin
- Omówienie SDK - pełna referencja importów podścieżek
- Pluginy kanałów - budowanie pluginów kanałów
- Pluginy dostawców - budowanie pluginów dostawców
- Wnętrze pluginów - szczegółowe omówienie architektury
- Manifest pluginu - referencja schematu manifestu