Skip to main content
OpenClaw è passato da un ampio livello di compatibilità all’indietro a una moderna architettura a Plugin con import mirati e documentati. Se il tuo Plugin è stato creato prima della nuova architettura, questa guida ti aiuta a migrare.

Cosa cambia

Il vecchio sistema di Plugin forniva due superfici molto aperte che permettevano ai Plugin di importare qualsiasi cosa servisse da un singolo punto di ingresso:
  • openclaw/plugin-sdk/compat - un singolo import che riesportava decine di helper. È stato introdotto per mantenere funzionanti i Plugin più vecchi basati su hook mentre veniva costruita la nuova architettura a Plugin.
  • openclaw/plugin-sdk/infra-runtime - un ampio barrel di helper runtime che combinava eventi di sistema, stato Heartbeat, code di consegna, helper fetch/proxy, helper per file, tipi di approvazione e utilità non correlate.
  • openclaw/plugin-sdk/config-runtime - un ampio barrel di compatibilità per la configurazione che durante la finestra di migrazione contiene ancora helper diretti deprecati per caricamento/scrittura.
  • openclaw/extension-api - un bridge che dava ai Plugin accesso diretto a helper lato host come il runner agente incorporato.
  • api.registerEmbeddedExtensionFactory(...) - un hook per estensioni in bundle rimosso e riservato all’embedded runner che poteva osservare eventi dell’embedded runner come tool_result.
Le ampie superfici di import sono ora deprecate. Continuano a funzionare a runtime, ma i nuovi Plugin non devono usarle, e i Plugin esistenti dovrebbero migrare prima che la prossima release maggiore le rimuova. L’API di registrazione della factory di estensioni riservata all’embedded runner è stata rimossa; usa invece il middleware per i risultati degli strumenti. OpenClaw non rimuove né reinterpreta un comportamento documentato dei Plugin nello stesso cambiamento che introduce una sostituzione. Le modifiche che rompono un contratto devono prima passare attraverso un adattatore di compatibilità, diagnostica, documentazione e una finestra di deprecazione. Questo vale per import dell’SDK, campi del manifest, API di setup, hook e comportamento di registrazione runtime.
Il livello di compatibilità all’indietro verrà rimosso in una futura release maggiore. I Plugin che importano ancora da queste superfici si romperanno quando accadrà. Le registrazioni legacy delle factory di estensioni incorporate già non vengono più caricate.

Perché è cambiato

Il vecchio approccio causava problemi:
  • Avvio lento - importare un helper caricava decine di moduli non correlati
  • Dipendenze circolari - le ampie riesportazioni rendevano facile creare cicli di import
  • Superficie API poco chiara - non c’era modo di distinguere quali export fossero stabili rispetto a quelli interni
Il moderno SDK per Plugin risolve questo problema: ogni percorso di import (openclaw/plugin-sdk/\<subpath\>) è un modulo piccolo e autonomo con uno scopo chiaro e un contratto documentato. Sono sparite anche le vecchie cuciture di comodità per provider per i canali in bundle. Le cuciture helper brandizzate per canale erano scorciatoie private del monorepo, non contratti stabili per Plugin. Usa invece sottopercorsi SDK generici e ristretti. All’interno del workspace dei Plugin in bundle, mantieni gli helper di proprietà del provider nel suo api.ts o runtime-api.ts. Esempi attuali di provider in bundle:
  • Anthropic mantiene gli helper di stream specifici per Claude nella propria cucitura api.ts / contract-api.ts
  • OpenAI mantiene provider builder, helper per modello predefinito e builder per provider realtime nel proprio api.ts
  • OpenRouter mantiene provider builder e helper di onboarding/configurazione nel proprio api.ts

Piano di migrazione per Talk e voce realtime

Il codice Talk per voce realtime, telefonia, riunioni e browser sta passando dalla contabilità dei turni locale alla superficie a un controller di sessione Talk condiviso esportato da openclaw/plugin-sdk/realtime-voice. Il nuovo controller possiede l’envelope comune degli eventi Talk, lo stato del turno attivo, lo stato di cattura, lo stato dell’audio in uscita, la cronologia recente degli eventi e il rifiuto dei turni obsoleti. I Plugin provider dovrebbero continuare a possedere le sessioni realtime specifiche del vendor; i Plugin di superficie dovrebbero continuare a possedere cattura, riproduzione, telefonia e particolarità delle riunioni. Questa migrazione di Talk è intenzionalmente breaking-clean:
  1. Mantieni le primitive condivise di controller/runtime in plugin-sdk/realtime-voice.
  2. Sposta le superfici in bundle sul controller condiviso: relay browser, handoff managed-room, realtime voice-call, STT streaming voice-call, realtime Google Meet e push-to-talk nativo.
  3. Sostituisci le vecchie famiglie RPC Talk con l’API finale talk.session.* e talk.client.*.
  4. Pubblicizza un solo canale di eventi Talk live in Gateway hello-ok.features.events: talk.event.
  5. Elimina il vecchio endpoint HTTP realtime e qualsiasi percorso di override delle istruzioni al momento della richiesta.
Il nuovo codice non dovrebbe chiamare direttamente createTalkEventSequencer(...) a meno che stia implementando un adapter di basso livello o una fixture di test. Preferisci il controller condiviso così gli eventi con scope di turno non possono essere emessi senza un id di turno, le chiamate obsolete turnEnd / turnCancel non possono cancellare un turno attivo più recente, e gli eventi del ciclo di vita dell’audio in uscita restano coerenti tra telefonia, riunioni, relay browser, handoff managed-room e client Talk nativi. La forma dell’API pubblica target è:
Le sessioni WebRTC/provider-websocket di proprietà del browser usano talk.client.create, perché il browser possiede la negoziazione del provider e il trasporto dei media mentre il Gateway possiede credenziali, istruzioni e policy degli strumenti. talk.session.* è la superficie comune gestita dal Gateway per realtime gateway-relay, trascrizione gateway-relay e sessioni STT/TTS native managed-room. Le configurazioni legacy che collocavano i selettori realtime accanto a talk.provider / talk.providers dovrebbero essere riparate con openclaw doctor --fix; a runtime Talk non reinterpreta la configurazione provider speech/TTS come configurazione provider realtime. Le combinazioni supportate di talk.session.create sono intenzionalmente poche: Mappa dei metodi rimossi: Anche il vocabolario di controllo unificato è deliberatamente ristretto: Non introdurre casi speciali per provider o piattaforma nel core per farlo funzionare. Il core possiede la semantica delle sessioni Talk. I Plugin provider possiedono la configurazione delle sessioni vendor. Le chiamate vocali e Google Meet possiedono gli adattatori di telefonia/riunione. Browser e app native possiedono l’UX di acquisizione/riproduzione del dispositivo.

Criterio di compatibilità

Per i Plugin esterni, il lavoro di compatibilità segue questo ordine:
  1. aggiungere il nuovo contratto
  2. mantenere il vecchio comportamento collegato tramite un adattatore di compatibilità
  3. emettere una diagnostica o un avviso che nomini il vecchio percorso e il sostituto
  4. coprire entrambi i percorsi nei test
  5. documentare la deprecazione e il percorso di migrazione
  6. rimuovere solo dopo la finestra di migrazione annunciata, di solito in una release principale
I manutentori possono verificare la coda di migrazione corrente con pnpm plugins:boundary-report. Usa pnpm plugins:boundary-report:summary per conteggi compatti, --owner <id> per un Plugin o proprietario della compatibilità, e pnpm plugins:boundary-report:ci quando un gate CI deve fallire su record di compatibilità scaduti, import SDK riservati tra proprietari o sottopercorsi SDK riservati non usati. Il report raggruppa i record di compatibilità deprecati per data di rimozione, conta i riferimenti locali di codice/documentazione, espone gli import SDK riservati tra proprietari e riepiloga il bridge SDK privato memory-host, così la pulizia della compatibilità rimane esplicita invece di dipendere da ricerche ad hoc. I sottopercorsi SDK riservati devono avere utilizzo del proprietario tracciato; gli export helper riservati inutilizzati devono essere rimossi dall’SDK pubblico. Se un campo del manifest è ancora accettato, gli autori di Plugin possono continuare a usarlo finché documentazione e diagnostica non indicano diversamente. Il nuovo codice dovrebbe preferire il sostituto documentato, ma i Plugin esistenti non dovrebbero rompersi durante le normali release minori.

Come migrare

1

Migrate runtime config load/write helpers

I Plugin inclusi dovrebbero smettere di chiamare api.runtime.config.loadConfig() e api.runtime.config.writeConfigFile(...) direttamente. Preferisci la configurazione che è stata già passata nel percorso di chiamata attivo. Gli handler di lunga durata che hanno bisogno dello snapshot del processo corrente possono usare api.runtime.config.current(). I tool agente di lunga durata dovrebbero usare ctx.getRuntimeConfig() del contesto del tool dentro execute, così un tool creato prima di una scrittura della configurazione vede comunque la configurazione runtime aggiornata.Le scritture della configurazione devono passare dagli helper transazionali e scegliere un criterio post-scrittura:
Usa afterWrite: { mode: "restart", reason: "..." } quando il chiamante sa che la modifica richiede un riavvio pulito del gateway, e afterWrite: { mode: "none", reason: "..." } solo quando il chiamante possiede il follow-up e vuole deliberatamente sopprimere il pianificatore di reload. I risultati della mutazione includono un riepilogo followUp tipizzato per test e logging; il gateway rimane responsabile dell’applicazione o pianificazione del riavvio. loadConfig e writeConfigFile rimangono helper di compatibilità deprecati per i Plugin esterni durante la finestra di migrazione e avvisano una volta con il codice di compatibilità runtime-config-load-write. I Plugin inclusi e il codice runtime del repository sono protetti da guardrail di scanner in pnpm check:deprecated-api-usage e pnpm check:no-runtime-action-load-config: il nuovo uso di Plugin di produzione fallisce direttamente, le scritture dirette della configurazione falliscono, i metodi del server gateway devono usare lo snapshot runtime della richiesta, gli helper runtime di invio/azione/client del canale devono ricevere la configurazione dal loro confine, e i moduli runtime di lunga durata hanno zero chiamate ambientali loadConfig() consentite.Il nuovo codice Plugin dovrebbe anche evitare di importare il barrel di compatibilità ampio openclaw/plugin-sdk/config-runtime. Usa il sottopercorso SDK ristretto che corrisponde al compito:I Plugin inclusi e i loro test sono protetti dallo scanner contro il barrel ampio, così import e mock rimangono locali al comportamento di cui hanno bisogno. Il barrel ampio esiste ancora per la compatibilità esterna, ma il nuovo codice non dovrebbe dipendere da esso.
2

Migrate embedded tool-result extensions to middleware

I Plugin inclusi devono sostituire gli handler dei risultati tool api.registerEmbeddedExtensionFactory(...) solo per embedded-runner con middleware neutrali rispetto al runtime.
Aggiorna il manifest del Plugin allo stesso tempo:
I Plugin installati possono anche registrare middleware dei risultati tool quando sono abilitati esplicitamente e dichiarano ogni runtime mirato in contracts.agentToolResultMiddleware. Le registrazioni di middleware installati non dichiarate vengono rifiutate.
3

Migrate approval-native handlers to capability facts

I Plugin di canale con capacità di approvazione ora espongono il comportamento di approvazione nativo tramite approvalCapability.nativeRuntime più il registro condiviso del contesto runtime.Modifiche chiave:
  • Sostituisci approvalCapability.handler.loadRuntime(...) con approvalCapability.nativeRuntime
  • Sposta auth/consegna specifici dell’approvazione dal cablaggio legacy plugin.auth / plugin.approvals a approvalCapability
  • ChannelPlugin.approvals è stato rimosso dal contratto pubblico dei Plugin di canale; sposta i campi delivery/native/render su approvalCapability
  • plugin.auth rimane solo per i flussi di login/logout del canale; gli hook auth di approvazione lì non vengono più letti dal core
  • Registra oggetti runtime di proprietà del canale come client, token o app Bolt tramite openclaw/plugin-sdk/channel-runtime-context
  • Non inviare avvisi di reinstradamento di proprietà del Plugin dagli handler di approvazione nativi; il core ora possiede gli avvisi instradati altrove dai risultati di consegna effettivi
  • Quando passi channelRuntime in createChannelManager(...), fornisci una superficie createPluginRuntime().channel reale. Gli stub parziali vengono rifiutati.
Vedi /plugins/sdk-channel-plugins per il layout corrente della capacità di approvazione.
4

Audit Windows wrapper fallback behavior

Se il tuo Plugin usa openclaw/plugin-sdk/windows-spawn, i wrapper Windows .cmd/.bat non risolti ora falliscono in modo chiuso a meno che tu non passi esplicitamente allowShellFallback: true.
Se il tuo chiamante non si affida intenzionalmente al fallback shell, non impostare allowShellFallback e gestisci invece l’errore generato.
5

Find deprecated imports

Cerca nel tuo Plugin import da una delle superfici deprecate:
6

Replace with focused imports

Ogni export dalla vecchia superficie mappa a uno specifico percorso di import moderno:
Per gli helper lato host, usa il runtime Plugin iniettato invece di importare direttamente:
Lo stesso modello si applica agli altri helper bridge legacy:
7

Sostituire le importazioni infra-runtime ampie

openclaw/plugin-sdk/infra-runtime esiste ancora per la compatibilità esterna, ma il nuovo codice dovrebbe importare la superficie di helper mirata di cui ha effettivamente bisogno:I plugin in bundle sono protetti da scanner contro infra-runtime, quindi il codice del repo non può regredire al barrel ampio.
8

Migrare gli helper delle route di canale

Il nuovo codice delle route di canale dovrebbe usare openclaw/plugin-sdk/channel-route. I nomi route-key e comparable-target più vecchi rimangono come alias di compatibilità durante la finestra di migrazione, ma i nuovi plugin dovrebbero usare i nomi di route che descrivono direttamente il comportamento:Gli helper di route moderni normalizzano { channel, to, accountId, threadId } in modo coerente tra approvazioni native, soppressione delle risposte, deduplicazione in ingresso, recapito Cron e routing delle sessioni.Non aggiungere nuovi usi di ChannelMessagingAdapter.parseExplicitTarget o degli helper loaded-route basati su parser (parseExplicitTargetForLoadedChannel o resolveRouteTargetForLoadedChannel) né di resolveChannelRouteTargetWithParser(...) da plugin-sdk/channel-route. Questi hook sono deprecati e rimangono solo per i plugin più vecchi durante la finestra di migrazione. I nuovi plugin di canale dovrebbero usare messaging.targetResolver.resolveTarget(...) per la normalizzazione dell’id del target e il fallback in caso di mancata corrispondenza nella directory, messaging.inferTargetChatType(...) quando il core ha bisogno di un tipo di peer anticipato, e messaging.resolveOutboundSessionRoute(...) per l’identità di sessione e thread nativa del provider.
9

Compilare e testare

Riferimento dei percorsi di importazione

Questa tabella è intenzionalmente il sottoinsieme comune per la migrazione, non l’intera superficie dell’SDK. L’inventario degli entrypoint del compilatore si trova in scripts/lib/plugin-sdk-entrypoints.json; gli export dei pacchetti vengono generati dal sottoinsieme pubblico. Le seam helper riservate dei plugin in bundle sono state ritirate dalla mappa degli export dell’SDK pubblico, tranne le facade di compatibilità documentate esplicitamente come lo shim deprecato plugin-sdk/discord mantenuto per il pacchetto pubblicato @openclaw/discord@2026.3.13. Gli helper specifici del proprietario risiedono nel pacchetto del plugin proprietario; il comportamento host condiviso dovrebbe passare attraverso contratti SDK generici come plugin-sdk/gateway-runtime, plugin-sdk/security-runtime e plugin-sdk/plugin-config-runtime. Usa l’import più ristretto adatto al compito. Se non riesci a trovare un export, controlla il sorgente in src/plugin-sdk/ o chiedi ai maintainer quale contratto generico dovrebbe possederlo.

Deprecazioni attive

Deprecazioni più ristrette che si applicano a tutto l’SDK dei plugin, al contratto dei provider, alla superficie runtime e al manifest. Ognuna funziona ancora oggi, ma sarà rimossa in una futura release major. La voce sotto ogni elemento mappa la vecchia API alla sua sostituzione canonica.
Vecchio (openclaw/plugin-sdk/command-auth): buildCommandsMessage, buildCommandsMessagePaginated, buildHelpMessage.Nuovo (openclaw/plugin-sdk/command-status): stesse firme, stessi export - solo importati dal sottopercorso più ristretto. command-auth li riesporta come stub di compatibilità.
Vecchio: resolveInboundMentionRequirement({ facts, policy }) e shouldDropInboundForMention(...) da openclaw/plugin-sdk/channel-inbound o openclaw/plugin-sdk/channel-mention-gating.Nuovo: resolveInboundMentionDecision({ facts, policy }) - restituisce un singolo oggetto decisionale invece di due chiamate separate.I plugin di canale downstream (Slack, Discord, Matrix, MS Teams) sono già passati al nuovo approccio.
openclaw/plugin-sdk/channel-runtime è uno shim di compatibilità per i plugin di canale più vecchi. Non importarlo nel nuovo codice; usa openclaw/plugin-sdk/channel-runtime-context per registrare gli oggetti runtime.Gli helper channelActions* in openclaw/plugin-sdk/channel-actions sono deprecati insieme agli export di canale “actions” grezzi. Esponi invece le capability tramite la superficie semantica presentation - i plugin di canale dichiarano cosa renderizzano (schede, pulsanti, selezioni) invece di quali nomi di azioni grezze accettano.
Vecchio: factory tool() da openclaw/plugin-sdk/provider-web-search.Nuovo: implementa createTool(...) direttamente sul plugin provider. OpenClaw non ha più bisogno dell’helper SDK per registrare il wrapper dello strumento.
Vecchio: formatInboundEnvelope(...) (e ChannelMessageForAgent.channelEnvelope) per costruire un envelope prompt piatto in testo semplice dai messaggi di canale in ingresso.Nuovo: BodyForAgent più blocchi strutturati di contesto utente. I plugin di canale allegano i metadati di routing (thread, argomento, risposta a, reazioni) come campi tipizzati invece di concatenarli in una stringa prompt. L’helper formatAgentEnvelope(...) è ancora supportato per envelope sintetizzati rivolti all’assistente, ma gli envelope in ingresso in testo semplice sono in via di rimozione.Aree interessate: inbound_claim, message_received e qualsiasi plugin di canale personalizzato che post-elaborava il testo channelEnvelope.
Vecchio: api.on("deactivate", handler).Nuovo: api.on("gateway_stop", handler). L’evento e il contesto sono lo stesso contratto di pulizia allo spegnimento; cambia solo il nome dell’hook.
deactivate rimane collegato come alias di compatibilità deprecato fino a dopo il 2026-08-16.
Vecchio: api.on("subagent_spawning", handler) che restituisce threadBindingReady o deliveryOrigin.Nuovo: lascia che il core prepari i binding dei sottoagenti thread: true tramite l’adapter di binding della sessione di canale. Usa api.on("subagent_spawned", handler) solo per l’osservazione post-avvio.
subagent_spawning, PluginHookSubagentSpawningEvent, PluginHookSubagentSpawningResult e SubagentLifecycleHookRunner.runSubagentSpawning(...) restano solo come superfici di compatibilità deprecate mentre i plugin esterni migrano.
Quattro alias di tipo di discovery sono ora wrapper sottili sui tipi dell’era del catalogo:Inoltre, il vecchio contenitore statico ProviderCapabilities - i plugin provider dovrebbero usare hook provider espliciti come buildReplayPolicy, normalizeToolSchemas e wrapStreamFn invece di un oggetto statico.
Vecchio (tre hook separati su ProviderThinkingPolicy): isBinaryThinking(ctx), supportsXHighThinking(ctx) e resolveDefaultThinkingLevel(ctx).Nuovo: un unico resolveThinkingProfile(ctx) che restituisce un ProviderThinkingProfile con id canonico, label opzionale e lista dei livelli ordinata per rango. OpenClaw declassa automaticamente i valori archiviati obsoleti in base al rango del profilo.Il contesto include provider, modelId, reasoning unito opzionale e fatti compat del modello uniti opzionali. I plugin provider possono usare questi fatti di catalogo per esporre un profilo specifico del modello solo quando il contratto di richiesta configurato lo supporta.Implementa un hook invece di tre. Gli hook legacy continuano a funzionare durante la finestra di deprecazione, ma non vengono composti con il risultato del profilo.
Vecchio: implementare hook di autenticazione esterna senza dichiarare il provider nel manifest del plugin.Nuovo: dichiara contracts.externalAuthProviders nel manifest del plugin e implementa resolveExternalAuthProfiles(...).
Vecchio campo manifest: providerAuthEnvVars: { anthropic: ["ANTHROPIC_API_KEY"] }.Nuovo: rispecchia lo stesso lookup delle variabili d’ambiente in setup.providers[].envVars sul manifest. Questo consolida in un unico punto i metadati di ambiente di setup/stato ed evita di avviare il runtime del plugin solo per rispondere ai lookup delle variabili d’ambiente.providerAuthEnvVars rimane supportato tramite un adapter di compatibilità finché la finestra di deprecazione non si chiude.
Vecchio: tre chiamate separate - api.registerMemoryPromptSection(...), api.registerMemoryFlushPlan(...), api.registerMemoryRuntime(...).Nuovo: una chiamata sull’API dello stato della memoria - registerMemoryCapability(pluginId, { promptBuilder, flushPlanResolver, runtime }).Stessi slot, singola chiamata di registrazione. Gli helper additivi per prompt e corpus (registerMemoryPromptSupplement, registerMemoryCorpusSupplement) non sono interessati.
Vecchio: api.registerMemoryEmbeddingProvider(...) più contracts.memoryEmbeddingProviders.Nuovo: api.registerEmbeddingProvider(...) più contracts.embeddingProviders.Il contratto generico del provider di embedding è riutilizzabile fuori dalla memoria ed è il percorso supportato per i nuovi provider. L’API di registrazione specifica della memoria rimane collegata come compatibilità deprecata mentre i provider esistenti migrano. I report di ispezione dei plugin segnalano l’uso non in bundle come debito di compatibilità.
Due alias di tipo legacy ancora esportati da src/plugins/runtime/types.ts:Il metodo runtime readSession è deprecato a favore di getSessionMessages. Stessa firma; il vecchio metodo inoltra la chiamata al nuovo.
Vecchio: runtime.tasks.flow (singolare) restituiva un accessor task-flow live.Nuovo: runtime.tasks.managedFlows mantiene il runtime di mutazione TaskFlow gestito per i plugin che creano, aggiornano, annullano o eseguono attività figlie da un flusso. Usa runtime.tasks.flows quando al plugin servono solo letture basate su DTO.
Coperto in “Come migrare → Migrare le estensioni incorporate dei risultati degli strumenti al middleware” sopra. Incluso qui per completezza: il percorso solo per runner incorporato rimosso api.registerEmbeddedExtensionFactory(...) è sostituito da api.registerAgentToolResultMiddleware(...) con una lista runtime esplicita in contracts.agentToolResultMiddleware.
OpenClawSchemaType riesportato da openclaw/plugin-sdk è ora un alias di una riga per OpenClawConfig. Preferisci il nome canonico.
Le deprecazioni a livello di estensione (dentro i plugin di canale/provider in bundle sotto extensions/) sono tracciate nei loro barrel api.ts e runtime-api.ts. Non influenzano i contratti dei plugin di terze parti e non sono elencate qui. Se consumi direttamente il barrel locale di un plugin in bundle, leggi i commenti di deprecazione in quel barrel prima di aggiornare.

Tempistica di rimozione

Tutti i plugin core sono già stati migrati. I plugin esterni devono migrare prima della prossima major release.

Sopprimere temporaneamente gli avvisi

Imposta queste variabili d’ambiente mentre lavori alla migrazione:
Questo è un meccanismo temporaneo di uscita, non una soluzione permanente.

Correlati