Aller au contenu

Aperçu du SDK de plugin

Le SDK de plugin constitue le contrat typé entre les plugins et le cœur du système. Cette page est la référence pour ce qu’il faut importer et ce que vous pouvez enregistrer.

Importez toujours depuis un sous-chemin spécifique :

import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";

Chaque sous-chemin est un petit module autonome. Cela permet un démarrage rapide et évite les problèmes de dépendances circulaires. Pour les assistants d’entrée/build spécifiques au canal, privilégiez openclaw/plugin-sdk/channel-core ; gardez openclaw/plugin-sdk/core pour la surface globale plus large et les assistants partagés tels que buildChannelConfigSchema.

Pour la configuration du canal, publiez le schéma JSON détenu par le canal via openclaw.plugin.json#channelConfigs. Le sous-chemin plugin-sdk/channel-config-schemaOpenClaw est destiné aux primitives de schéma partagées et au générateur générique. Les plugins d’OpenClaw utilisent plugin-sdk/bundled-channel-config-schema pour les schémas de canal groupés conservés. Les exportations de compatibilité obsolètes restent sur plugin-sdk/channel-config-schema-legacy ; aucun sous-chemin de schéma groupé n’est un modèle pour les nouveaux plugins.

The plugin SDK is exposed as a set of narrow subpaths grouped by area (plugin entry, channel, provider, auth, runtime, capability, memory, and reserved bundled-plugin helpers). For the full catalog — grouped and linked — see Plugin SDK subpaths.

L’inventaire des points d’entrée du compilateur réside dans scripts/lib/plugin-sdk-entrypoints.json; les exportations du package sont générées à partir du sous-ensemble public après soustraction des sous-chemins de test interne locaux au dépôt répertoriés dans scripts/lib/plugin-sdk-private-local-only-subpaths.json. Exécutez pnpm plugin-sdk:surface pour auditer le nombre d’exportations publiques. Les sous-chemins publics dépréciés assez anciens et non utilisés par le code de production des extensions groupées sont suivis dans scripts/lib/plugin-sdk-deprecated-public-subpaths.json; les de ré-exportation dépréciés larges sont suivis dans scripts/lib/plugin-sdk-deprecated-barrel-subpaths.json.

Le rappel register(api) reçoit un objet OpenClawPluginApi avec ces méthodes :

MéthodeCe qu’il enregistre
api.registerProvider(...)Inférence de texte (LLM)
api.registerAgentHarness(...)Exécuteur d’agent de bas niveau expérimental
api.registerCliBackend(...)Backend d’inférence CLI local
api.registerChannel(...)Canal de messagerie
api.registerEmbeddingProvider(...)Reusable vector embedding provider
api.registerSpeechProvider(...)Text-to-speech / STT synthesis
api.registerRealtimeTranscriptionProvider(...)Streaming realtime transcription
api.registerRealtimeVoiceProvider(...)Duplex realtime voice sessions
api.registerMediaUnderstandingProvider(...)Image/audio/video analysis
api.registerImageGenerationProvider(...)Image generation
api.registerMusicGenerationProvider(...)Music generation
api.registerVideoGenerationProvider(...)Video generation
api.registerWebFetchProvider(...)Web fetch / scrape provider
api.registerWebSearchProvider(...)Web search

Les providers d’embeddings enregistrés avec api.registerEmbeddingProvider(...) doivent également être répertoriés dans contracts.embeddingProviders dans le manifeste du plugin. Il s’agit de la surface d’embedding générique pour la génération de vecteurs réutilisables. La recherche dans la mémoire peut consommer cette surface de provider générique. L’ancienne jonction api.registerMemoryEmbeddingProvider(...) et contracts.memoryEmbeddingProviders est une compatibilité obsolète pendant que les fournisseurs existants spécifiques à la mémoire migrent.

Utilisez defineToolPlugin pour les plugins simples composés uniquement d’outils avec des noms d’outils fixes. Utilisez api.registerTool(...) directement pour les plugins mixtes ou l’enregistrement d’outils entièrement dynamique.

MéthodeCe qu’il enregistre
api.registerTool(tool, opts?)Outil d’agent (obligatoire ou { optional: true })
api.registerCommand(def)Commande personnalisée (contourne le LLM)

Les commandes de plugin peuvent définir agentPromptGuidance lorsque l’agent a besoin d’un indice de routage court et owned par la commande. Gardez ce texte concernant la commande elle-même ; n’ajoutez pas de stratégie spécifique au fournisseur ou au plugin aux constructeurs de prompt principaux.

Les entrées de guidage peuvent être des chaînes héritées, qui s’appliquent à chaque surface de prompt, ou des entrées structurées :

agentPromptGuidance: ["Global command hint.", { text: "Only show this in the main OpenClaw prompt.", surfaces: ["openclaw_main"] }];

Les surfaces structurés peuvent inclure openclaw_main, codex_app_server, cli_backend, acp_backend, ou subagent. pi_main reste un alias obsolète pour openclaw_main. Omettez surfaces pour une guidance intentionnelle sur toutes les surfaces. Ne passez pas un tableau surfaces vide ; il est rejeté afin qu’une perte accidentelle de portée ne devienne pas un texte d’invite global.

Les instructions du développeur pour le serveur d’application native Codex sont plus strictes que pour les autres surfaces d’invite : seule la guidance explicitement délimitée à codex_app_server est promue dans cette voie à priorité plus élevée. La guidance sous forme de chaîne héritée et la guidance structurée non délimitée restent disponibles pour les surfaces d’invite non-Codex pour compatibilité.

MéthodeCe qu’il enregistre
api.registerHook(events, handler, opts?)Hook d’événement
api.registerHttpRoute(params)Point de terminaison HTTP Gateway
api.registerGatewayMethod(name, handler)Méthode Gateway RPC
api.registerGatewayDiscoveryService(service)Annonceur de découverte Gateway local
api.registerCli(registrar, opts?)Sous-commande CLI
api.registerNodeCliFeature(registrar, opts?)Fonctionnalité de nœud CLI sous openclaw nodes
api.registerService(service)Service d’arrière-plan
api.registerInteractiveHandler(registration)Gestionnaire interactif
api.registerAgentToolResultMiddleware(...)Middleware de résultat d’outil à l’exécution
api.registerMemoryPromptSupplement(builder)Section de prompt additive adjacente à la mémoire
api.registerMemoryCorpusSupplement(adapter)Corpus de recherche/lecture de mémoire additive

Les hôtes de crochet sont les points de liaison du SDK pour les plugins qui doivent participer au cycle de vie de l’hôte plutôt que de simplement ajouter un fournisseur, un canal ou un outil. Ce sont des contrats génériques ; le mode Plan peut les utiliser, tout comme les workflows d’approbation, les portes de stratégie d’espace de travail, les moniteurs en arrière-plan, les assistants de configuration et les plugins compagnons d’interface utilisateur.

MéthodeContrat dont il est propriétaire
api.session.state.registerSessionExtension(...)État de session compatible JSON et propriété du plugin, projeté via les sessions Gateway
api.session.workflow.enqueueNextTurnInjection(...)Contexte durable exactement une fois injecté dans le prochain tour d’agent pour une session
api.registerTrustedToolPolicy(...)Stratégie d’outil pré-plugin groupée/approuvée capable de bloquer ou de réécrire les paramètres d’outil
api.registerToolMetadata(...)Métadonnées d’affichage du catalogue d’outils sans modifier l’implémentation de l’outil
api.registerCommand(...)Commandes de plugin délimitées ; les résultats des commandes peuvent définir continueAgent: true ; les commandes natives Discord prennent en charge descriptionLocalizations
api.session.controls.registerControlUiDescriptor(...)Descripteurs de contribution d’interface utilisateur de contrôle pour les surfaces de session, d’outil, d’exécution ou de paramètres
api.lifecycle.registerRuntimeLifecycle(...)Rappels de nettoyage pour les ressources d’exécution appartenant au plugin sur les chemins de réinitialisation/suppression/rechargement
api.agent.events.registerAgentEventSubscription(...)Abonnements aux événements nettoyés pour l’état du workflow et les moniteurs
api.runContext.setRunContext(...) / getRunContext(...) / clearRunContext(...)État de brouillon du plugin par exécution effacé lors du cycle de vie d’exécution terminal
api.session.workflow.registerSessionSchedulerJob(...)Métadonnées de nettoyage pour les tâches du planificateur appartenant au plugin ; ne planifie pas de travail ni ne crée d’enregistrements de tâches
api.session.workflow.sendSessionAttachment(...)Livraison de pièces jointes de fichiers médiées par l’hôte, uniquement groupées, vers la route de session sortante directe active
api.session.workflow.scheduleSessionTurn(...) / unscheduleSessionTurnsByTag(...)Tours de session planifiés basés sur Cron, uniquement groupés, plus un nettoyage basé sur des balises
api.session.controls.registerSessionAction(...)Actions de session typées que les clients peuvent dispatcher via le Gateway

Utilisez les espaces de noms groupés pour le nouveau code de plugin :

  • api.session.state.registerSessionExtension(...)
  • api.session.workflow.enqueueNextTurnInjection(...)
  • api.session.workflow.registerSessionSchedulerJob(...)
  • api.session.workflow.sendSessionAttachment(...)
  • api.session.workflow.scheduleSessionTurn(...)
  • api.session.workflow.unscheduleSessionTurnsByTag(...)
  • api.session.controls.registerSessionAction(...)
  • api.session.controls.registerControlUiDescriptor(...)
  • api.agent.events.registerAgentEventSubscription(...)
  • api.agent.events.emitAgentEvent(...)
  • api.runContext.setRunContext(...) / getRunContext(...) / clearRunContext(...)
  • api.lifecycle.registerRuntimeLifecycle(...)

Les méthodes plates équivalentes restent disponibles en tant qu’alias de compatibilité obsolètes pour les plugins existants. N’ajoutez pas de nouveau code de plugin qui appelle directement api.registerSessionExtension, api.enqueueNextTurnInjection, api.registerControlUiDescriptor, api.registerRuntimeLifecycle, api.registerAgentEventSubscription, api.emitAgentEvent, api.setRunContext, api.getRunContext, api.clearRunContext, api.registerSessionSchedulerJob, api.registerSessionAction, api.sendSessionAttachment, api.scheduleSessionTurn ou api.unscheduleSessionTurnsByTag.

scheduleSessionTurn(...) est une commodité à portée de session par rapport au planificateur Cron du Gateway. Cron gère le minutage et crée l’enregistrement de tâche en arrière-plan lorsque le tour s’exécute ; le Plugin SDK ne contraint que la session cible, la dénomination appartenant au plugin et le nettoyage. Utilisez api.runtime.tasks.managedFlows à l’intérieur du tour planifié lorsque le travail lui-même nécessite un état durable de flux de tâches en plusieurs étapes.

Les contrats divisent intentionnellement l’autorité :

  • Les plugins externes peuvent posséder des extensions de session, descripteurs d’interface utilisateur, commandes, métadonnées de tool, injections de tour suivant et hooks normaux.
  • Les stratégies de de confiance s’exécutent avant les hooks before_tool_call ordinaires et sont uniquement groupées car elles participent à la stratégie de sécurité de l’hôte.
  • La propriété de commande réservée est réservée aux bundles. Les plugins externes doivent utiliser leurs propres noms ou alias de commande.
  • allowPromptInjection=false désactive les hooks de modification de prompt, notamment agent_turn_prepare, before_prompt_build, heartbeat_prompt_contribution, les champs de prompt de l’ancien before_agent_start, et enqueueNextTurnInjection.

Exemples de consommateurs non-Plan :

Archétype de pluginHooks utilisés
Workflow d’approbationExtension de session, continuation de commande, injection de tour suivant, descripteur d’interface utilisateur
Porte de stratégie budgétaire/d’espace de travailStratégie d’outil de confiance, métadonnées d’outil, projection de session
Moniteur du cycle de vie en arrière-planNettoyage du cycle de vie d’exécution, abonnement aux événements de l’agent, possession/nettoyage de l’ordonnanceur de session, contribution au prompt de pulsation, descripteur d’interface utilisateur
Assistant de configuration ou d’intégrationExtension de session, commandes délimitées, descripteur de l’interface utilisateur de contrôle

Quand utiliser le middleware de résultat d'outil

Les plugins groupés peuvent utiliser api.registerAgentToolResultMiddleware(...) lorsqu’ils ont besoin de réécrire un résultat d’outil après l’exécution et avant que le runtime ne renvoie ce résultat dans le modèle. Il s’agit de la jonction neutre par rapport au runtime de confiance pour les réducteurs de sortie asynchrones tels que tokenjuice.

Les plugins groupés doivent déclarer contracts.agentToolResultMiddleware pour chaque cible de runtime, par exemple ["openclaw", "codex"]OpenClaw. Les plugins externes ne peuvent pas enregistrer ce middleware ; conservez les hooks de plugin OpenClaw normaux pour le travail qui ne nécessite pas de timing pré-modèle pour les résultats d’outils. L’ancien chemin d’enregistrement de fabrique d’extension uniquement pour l’exécuteur intégré a été supprimé.

api.registerGatewayDiscoveryService(...)Gateway permet à un plugin d’annoncer le Gateway actif sur un transport de découverte local tel que mDNS/Bonjour. OpenClawGatewayGateway appelle le service lors du démarrage du Gateway lorsque la découverte locale est activée, transmet les ports actuels du Gateway et les données de suggestion TXT non secrètes, et appelle le gestionnaire stopGateway retourné lors de l’arrêt du Gateway.

api.registerGatewayDiscoveryService({
id: "my-discovery",
async advertise(ctx) {
const handle = await startMyAdvertiser({
gatewayPort: ctx.gatewayPort,
tls: ctx.gatewayTlsEnabled,
displayName: ctx.machineDisplayName,
});
return { stop: () => handle.stop() };
},
});

Les plugins de découverte Gateway ne doivent pas traiter les valeurs TXT annoncées comme des secrets ou comme une authentification. La découverte est une indication de routage ; l’authentification Gateway et le épinglage TLS (TLS pinning) conservent toujours la confiance.

api.registerCli(registrar, opts?) accepte deux types de métadonnées de commande :

  • commands : noms de commande explicites détenus par le registrant
  • descriptors : descripteurs de commande au moment de l’analyse utilisés pour l’aide du CLI, le routage et l’enregistrement différé du plugin CLI
  • parentPath : chemin de commande parent facultatif pour les groupes de commandes imbriqués, tel que ["nodes"]

Pour les fonctionnalités de nœuds couplés, privilégiez api.registerNodeCliFeature(registrar, opts?). C’est un petit wrapper autour de api.registerCli(..., { parentPath: ["nodes"] }) qui rend des commandes comme openclaw nodes canvas des fonctionnalités de nœud explicitement détenues par le plugin.

Si vous souhaitez qu’une commande de plugin reste chargée à la demande dans le chemin racine du CLI normal, fournissez descriptors qui couvrent chaque racine de commande de premier niveau exposée par ce registre.

api.registerCli(
async ({ program }) => {
const { registerMatrixCli } = await import("./src/cli.js");
registerMatrixCli({ program });
},
{
descriptors: [
{
name: "matrix",
description: "Manage Matrix accounts, verification, devices, and profile state",
hasSubcommands: true,
},
],
},
);

Les commandes imbriquées reçoivent la commande parente résolue sous forme de program :

api.registerCli(
async ({ program }) => {
const { registerNodesCanvasCommands } = await import("./src/cli.js");
registerNodesCanvasCommands(program);
},
{
parentPath: ["nodes"],
descriptors: [
{
name: "canvas",
description: "Capture or render canvas content from a paired node",
hasSubcommands: true,
},
],
},
);

Utilisez commands seul uniquement lorsque vous n’avez pas besoin de l’enregistrement racine du CLI à la demande. Ce chemin de compatibilité rapide reste pris en charge, mais il n’installe pas d’espaces réservés basés sur des descripteurs pour le chargement à la demande au moment de l’analyse.

api.registerCliBackend(...) permet à un plugin de posséder la configuration par défaut d’un backend local d’CLI IA tel que claude-cli ou my-cli.

  • Le id du backend devient le préfixe du fournisseur dans les références de modèle comme my-cli/gpt-5.
  • Le config du backend utilise la même forme que agents.defaults.cliBackends.<id>.
  • La configuration de l’utilisateur l’emporte toujours. OpenClaw fusionne agents.defaults.cliBackends.<id> par-dessus la valeur par défaut du plugin avant d’exécuter le CLI.
  • Utilisez normalizeConfig lorsqu’un backend a besoin de réécritures de compatibilité après la fusion (par exemple, pour normaliser les anciennes formes de drapeaux).
  • Utilisez resolveExecutionArgs pour les réécritures argv limitées à la demande qui appartiennent au dialecte du CLI, comme le mappage des niveaux de réflexion de OpenClaw vers un drapeau d’effort natif.

Pour un guide de création de bout en bout, consultez plugins de backend CLI.

MéthodeCe qu’il enregistre
api.registerContextEngine(id, factory)Moteur de contexte (un actif à la fois). Le rappel assemble() reçoit availableTools et citationsMode afin que le moteur puisse adapter les ajouts de prompt.
api.registerMemoryCapability(capability)Capacité de mémoire unifiée
api.registerMemoryPromptSection(builder)Générateur de section de prompt mémoire
api.registerMemoryFlushPlan(resolver)Résolveur de plan de vidage de mémoire
api.registerMemoryRuntime(runtime)Adaptateur d’exécution de mémoire

Adaptateurs d’intégration de mémoire obsolètes

Section intitulée « Adaptateurs d’intégration de mémoire obsolètes »
MéthodeCe qu’il enregistre
api.registerMemoryEmbeddingProvider(adapter)Adaptateur d’intégration de mémoire pour le plugin actif
  • registerMemoryCapability est l’API API de plugin de mémoire exclusive préférée.
  • registerMemoryCapability peut également exposer publicArtifacts.listArtifacts(...) afin que les plugins compagnons puissent consommer les artefacts de mémoire exportés via openclaw/plugin-sdk/memory-host-core au lieu d’accéder à la structure privée d’un plugin de mémoire spécifique.
  • registerMemoryPromptSection, registerMemoryFlushPlan et registerMemoryRuntime sont des API de plugin de mémoire exclusives compatibles avec l’héritage.
  • MemoryFlushPlan.model peut épingler le tour de vidage (flush turn) à une référence provider/model exacte, telle que ollama/qwen3:8b, sans hériter de la chaîne de repli (fallback) active.
  • registerMemoryEmbeddingProvider est obsolète. Les nouveaux fournisseurs d’intégrations doivent utiliser api.registerEmbeddingProvider(...) et contracts.embeddingProviders.
  • Les fournisseurs existants spécifiques à la mémoire continuent de fonctionner pendant la fenêtre de migration, mais l’inspection des plugins signale ceci comme une dette de compatibilité pour les plugins non groupés.
MéthodeCe qu’elle fait
api.on(hookName, handler, opts?)Hook de cycle de vie typé
api.onConversationBindingResolved(handler)Rappel de liaison de conversation

Voir Plugin hooks pour des exemples, des noms de hook courants et la sémantique de garde.

  • before_tool_call : renvoyer { block: true } est terminal. Une fois qu’un gestionnaire l’a défini, les gestionnaires de moindre priorité sont ignorés.
  • before_tool_call : renvoyer { block: false } est traité comme l’absence de décision (identique à l’omission de block), et non comme une substitution.
  • before_install : renvoyer { block: true } est terminal. Une fois qu’un gestionnaire l’a défini, les gestionnaires de moindre priorité sont ignorés.
  • before_install : renvoyer { block: false } est traité comme l’absence de décision (identique à l’omission de block), et non comme une substitution.
  • reply_dispatch : renvoyer { handled: true, ... } est terminal. Une fois qu’un gestionnaire réclame le dispatch, les gestionnaires de moindre priorité et le chemin de dispatch par défaut du modèle sont ignorés.
  • message_sending : renvoyer { cancel: true } est terminal. Une fois qu’un gestionnaire l’a défini, les gestionnaires de moindre priorité sont ignorés.
  • message_sending : renvoyer { cancel: false } est traité comme l’absence de décision (identique à l’omission de cancel), et non comme une substitution.
  • message_received : utilisez le champ typé threadId lorsque vous avez besoin d’un routage entrant de fil/discussion. Conservez metadata pour les éléments spécifiques au canal.
  • message_sending : utilisez les champs de routage typés replyToId / threadId avant de revenir aux metadata spécifiques au canal.
  • gateway_start : utilisez ctx.config , ctx.workspaceDir et ctx.getCron?.() pour l’état de démarrage propriétaire de la passerelle au lieu de vous fier aux hooks internes gateway:startup .
  • cron_changed : observez les changements du cycle de vie cron propriétaires de la passerelle. Utilisez event.job?.state?.nextRunAtMs et ctx.getCron?.() lors de la synchronisation de planificateurs de réveil externes, et gardez OpenClaw comme source de vérité pour les vérifications d’échéance et l’exécution.
ChampTypeDescription
api.idstringID du plugin
api.namestringNom d’affichage
api.versionstring?Version du plugin (facultatif)
api.descriptionstring?Description du plugin (facultatif)
api.sourcestringChemin source du plugin
api.rootDirstring?Répertoire racine du plugin (facultatif)
api.configOpenClawConfigInstantané de la configuration actuelle (instantané d’exécution en mémoire actif lorsqu’il est disponible)
api.pluginConfigRecord<string, unknown>Configuration spécifique au plugin provenant de plugins.entries.<id>.config
api.runtimePluginRuntimeAssistants d’exécution
api.loggerPluginLoggerEnregistreur délimité ( debug , info , warn , error )
api.registrationModePluginRegistrationModeMode de chargement actuel ; "setup-runtime" est la fenêtre légère de pré-démarrage/configuration avant l’entrée complète
api.resolvePath(input)(string) => stringRésoudre le chemin relatif à la racine du plugin

Au sein de votre plugin, utilisez des fichiers barrel locaux pour les importations internes :

my-plugin/
api.ts # Public exports for external consumers
runtime-api.ts # Internal-only runtime exports
index.ts # Plugin entry point
setup-entry.ts # Lightweight setup-only entry (optional)

Les surfaces publiques des plugins regroupés chargés par façade (api.ts, runtime-api.ts, index.ts, setup-entry.ts, et fichiers d’entrée publics similaires) préfèrent l’instantané actif de la configuration d’exécution lorsque OpenClaw est déjà en cours d’exécution. Si aucun instantané d’exécution n’existe encore, ils reviennent au fichier de configuration résolu sur le disque. Les façades de plugins regroupés empaquetés doivent être chargées via les chargeurs de façade de plugins de OpenClaw ; les importations directes depuis dist/extensions/... contournent le manifeste et les vérifications du sidecar d’exécution que les installations empaquetées utilisent pour le code appartenant au plugin.

Les plugins de fournisseur peuvent exposer un contrat étroit local au plugin via un fichier barrel lorsqu’une assistant est intentionnellement spécifique au fournisseur et n’appartient pas encore à un sous-chemin générique du SDK. Exemples regroupés :

  • Anthropic : jointure publique api.ts / contract-api.ts pour Claude beta-header et assistants de flux service_tier.
  • @openclaw/openai-provider : api.ts exporte des constructeurs de fournisseur, des assistants de modèle par défaut, et des constructeurs de fournisseur en temps réel.
  • @openclaw/openrouter-provider : api.ts exporte le constructeur de fournisseur ainsi que des assistants d’onboarding/de configuration.
Points d'entrée

Options definePluginEntry et defineChannelPluginEntry.

Assistants d'exécution

Référence complète de l’espace de noms api.runtime.

Configuration et installation

Conditionnement, manifestes et schémas de configuration.

Tests

Utilitaires de test et règles de linting.

Migration du SDK

Migration depuis des interfaces dépréciées.

Fonctionnement interne des plugins

Architecture approfondie et modèle de capacité.