Passer au contenu principal

Créer des plugins

Les plugins étendent OpenClaw avec de nouvelles capacités : canaux, fournisseurs de modèles, parole, transcription en temps réel, voix en temps réel, compréhension des médias, génération d’images, génération de vidéo, récupération web, recherche web, outils d’agent, ou toute combinaison. Vous n’avez pas besoin d’ajouter votre plugin au dépôt OpenClaw. Publiez-le sur ClawHub ou npm, puis les utilisateurs l’installent avec openclaw plugins install <package-name>. OpenClaw essaie d’abord ClawHub et revient automatiquement à npm en cas d’échec.

Prérequis

  • Node >= 22 et un gestionnaire de paquets (npm ou pnpm)
  • Connaissance de TypeScript (ESM)
  • Pour les plugins dans le dépôt : dépôt cloné et pnpm install exécuté

Quel type de plugin ?

Plugin de canal

Connectez OpenClaw à une plateforme de messagerie (Discord, IRC, etc.)

Plugin de fournisseur

Ajoutez un fournisseur de modèles (LLM, proxy ou point de terminaison personnalisé)

Plugin d'outil / hook

Enregistrez des outils d’agent, des hooks d’événements ou des services — la suite ci-dessous
Si un plugin de canal est facultatif et peut ne pas être installé au moment de l’onboarding/de la configuration, utilisez createOptionalChannelSetupSurface(...) depuis openclaw/plugin-sdk/channel-setup. Cela produit une paire adaptateur + assistant de configuration qui annonce l’exigence d’installation et échoue de manière fermée sur les vraies écritures de configuration tant que le plugin n’est pas installé.

Démarrage rapide : plugin d’outil

Ce guide crée un plugin minimal qui enregistre un outil d’agent. Les plugins de canal et de fournisseur ont des guides dédiés liés ci-dessus.
1

Créer le package et le manifeste

{
  "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"
    }
  }
}
Chaque plugin a besoin d’un manifeste, même sans configuration. Voir Manifeste pour le schéma complet. Les extraits canoniques de publication ClawHub se trouvent dans docs/snippets/plugin-publish/.
2

Écrire le point d'entrée

// 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 est destiné aux plugins non liés à un canal. Pour les canaux, utilisez defineChannelPluginEntry — voir Plugins de canal. Pour toutes les options du point d’entrée, voir Points d’entrée.
3

Tester et publier

Plugins externes : validez et publiez avec ClawHub, puis installez :
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
openclaw plugins install clawhub:@myorg/openclaw-my-plugin
OpenClaw vérifie aussi ClawHub avant npm pour les spécifications de package nues comme @myorg/openclaw-my-plugin.Plugins dans le dépôt : placez-les dans l’arborescence de workspace des plugins intégrés — détection automatique.
pnpm test -- <bundled-plugin-root>/my-plugin/

Capacités des plugins

Un même plugin peut enregistrer n’importe quel nombre de capacités via l’objet api :
CapacitéMéthode d’enregistrementGuide détaillé
Inférence texte (LLM)api.registerProvider(...)Plugins de fournisseur
Backend d’inférence CLIapi.registerCliBackend(...)Backends CLI
Canal / messagerieapi.registerChannel(...)Plugins de canal
Parole (TTS/STT)api.registerSpeechProvider(...)Plugins de fournisseur
Transcription en temps réelapi.registerRealtimeTranscriptionProvider(...)Plugins de fournisseur
Voix en temps réelapi.registerRealtimeVoiceProvider(...)Plugins de fournisseur
Compréhension des médiasapi.registerMediaUnderstandingProvider(...)Plugins de fournisseur
Génération d’imagesapi.registerImageGenerationProvider(...)Plugins de fournisseur
Génération de musiqueapi.registerMusicGenerationProvider(...)Plugins de fournisseur
Génération de vidéoapi.registerVideoGenerationProvider(...)Plugins de fournisseur
Récupération webapi.registerWebFetchProvider(...)Plugins de fournisseur
Recherche webapi.registerWebSearchProvider(...)Plugins de fournisseur
Outils d’agentapi.registerTool(...)Ci-dessous
Commandes personnaliséesapi.registerCommand(...)Points d’entrée
Hooks d’événementsapi.registerHook(...)Points d’entrée
Routes HTTPapi.registerHttpRoute(...)Internals
Sous-commandes CLIapi.registerCli(...)Points d’entrée
Pour l’API d’enregistrement complète, voir Vue d’ensemble du SDK. Si votre plugin enregistre des méthodes RPC de passerelle personnalisées, gardez-les sur un préfixe spécifique au plugin. Les espaces de noms d’administration du cœur (config.*, exec.approvals.*, wizard.*, update.*) restent réservés et sont toujours résolus vers operator.admin, même si un plugin demande une portée plus étroite. Sémantique des gardes de hook à garder à l’esprit :
  • before_tool_call: { block: true } est terminal et arrête les gestionnaires de priorité inférieure.
  • before_tool_call: { block: false } est traité comme aucune décision.
  • before_tool_call: { requireApproval: true } met en pause l’exécution de l’agent et demande l’approbation de l’utilisateur via la superposition d’approbation exec, les boutons Telegram, les interactions Discord ou la commande /approve sur n’importe quel canal.
  • before_install: { block: true } est terminal et arrête les gestionnaires de priorité inférieure.
  • before_install: { block: false } est traité comme aucune décision.
  • message_sending: { cancel: true } est terminal et arrête les gestionnaires de priorité inférieure.
  • message_sending: { cancel: false } est traité comme aucune décision.
La commande /approve gère à la fois les approbations exec et plugin avec un repli borné : lorsqu’un ID d’approbation exec n’est pas trouvé, OpenClaw réessaie le même ID via les approbations de plugin. Le transfert d’approbation de plugin peut être configuré indépendamment via approvals.plugin dans la configuration. Si une logique d’approbation personnalisée doit détecter ce même cas de repli borné, préférez isApprovalNotFoundError depuis openclaw/plugin-sdk/error-runtime au lieu de faire correspondre manuellement des chaînes d’expiration d’approbation. Voir Sémantique des décisions de hook dans la vue d’ensemble du SDK pour les détails.

Enregistrement des outils d’agent

Les outils sont des fonctions typées que le LLM peut appeler. Ils peuvent être requis (toujours disponibles) ou facultatifs (activation par l’utilisateur) :
register(api) {
  // Outil requis — toujours disponible
  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 }] };
    },
  });

  // Outil facultatif — l'utilisateur doit l'ajouter à la liste d'autorisation
  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 },
  );
}
Les utilisateurs activent les outils facultatifs dans la configuration :
{
  tools: { allow: ["workflow_tool"] },
}
  • Les noms d’outils ne doivent pas entrer en conflit avec les outils du cœur (les conflits sont ignorés)
  • Utilisez optional: true pour les outils avec effets de bord ou exigences binaires supplémentaires
  • Les utilisateurs peuvent activer tous les outils d’un plugin en ajoutant l’ID du plugin à tools.allow

Conventions d’importation

Importez toujours depuis des chemins ciblés openclaw/plugin-sdk/<subpath> :
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";

// Incorrect : racine monolithique (obsolète, sera supprimée)
import { ... } from "openclaw/plugin-sdk";
Pour la référence complète des sous-chemins, voir Vue d’ensemble du SDK. À l’intérieur de votre plugin, utilisez des fichiers barrel locaux (api.ts, runtime-api.ts) pour les importations internes — n’importez jamais votre propre plugin via son chemin SDK. Pour les plugins de fournisseur, conservez les helpers spécifiques au fournisseur dans ces barrels à la racine du package, sauf si le point d’extension est réellement générique. Exemples intégrés actuels :
  • Anthropic : wrappers de flux Claude et helpers service_tier / beta
  • OpenAI : constructeurs de fournisseurs, helpers de modèles par défaut, fournisseurs realtime
  • OpenRouter : constructeur de fournisseur plus helpers d’onboarding/configuration
Si un helper n’est utile qu’à l’intérieur d’un package de fournisseur intégré, gardez-le sur ce point d’extension à la racine du package au lieu de le promouvoir dans openclaw/plugin-sdk/*. Certains points d’extension helpers générés openclaw/plugin-sdk/<bundled-id> existent encore pour la maintenance et la compatibilité des plugins intégrés, par exemple plugin-sdk/feishu-setup ou plugin-sdk/zalo-setup. Traitez-les comme des surfaces réservées, et non comme le modèle par défaut pour les nouveaux plugins tiers.

Liste de contrôle avant soumission

package.json a les métadonnées openclaw correctes
Le manifeste openclaw.plugin.json est présent et valide
Le point d’entrée utilise defineChannelPluginEntry ou definePluginEntry
Toutes les importations utilisent des chemins ciblés plugin-sdk/<subpath>
Les importations internes utilisent des modules locaux, pas des auto-importations SDK
Les tests réussissent (pnpm test -- <bundled-plugin-root>/my-plugin/)
pnpm check réussit (plugins dans le dépôt)

Test des versions bêta

  1. Surveillez les tags de version GitHub sur openclaw/openclaw et abonnez-vous via Watch > Releases. Les tags bêta ressemblent à v2026.3.N-beta.1. Vous pouvez aussi activer les notifications pour le compte X officiel OpenClaw @openclaw pour les annonces de version.
  2. Testez votre plugin contre le tag bêta dès son apparition. La fenêtre avant la version stable est généralement de seulement quelques heures.
  3. Publiez dans le fil de votre plugin dans le canal Discord plugin-forum après le test avec soit all good, soit ce qui s’est cassé. Si vous n’avez pas encore de fil, créez-en un.
  4. Si quelque chose casse, ouvrez ou mettez à jour une issue intitulée Beta blocker: <plugin-name> - <summary> et appliquez le label beta-blocker. Mettez le lien de l’issue dans votre fil.
  5. Ouvrez une PR vers main intitulée fix(<plugin-id>): beta blocker - <summary> et liez l’issue à la fois dans la PR et dans votre fil Discord. Les contributeurs ne peuvent pas appliquer de labels aux PR, donc le titre est le signal côté PR pour les mainteneurs et l’automatisation. Les bloqueurs avec une PR sont fusionnés ; les bloqueurs sans PR peuvent quand même être livrés. Les mainteneurs surveillent ces fils pendant les tests bêta.
  6. Le silence signifie que tout est vert. Si vous manquez la fenêtre, votre correction arrivera probablement dans le cycle suivant.

Étapes suivantes

Plugins de canal

Créer un plugin de canal de messagerie

Plugins de fournisseur

Créer un plugin de fournisseur de modèles

Vue d'ensemble du SDK

Référence de la table d’importation et de l’API d’enregistrement

Helpers d'exécution

TTS, recherche, sous-agent via api.runtime

Tests

Utilitaires et modèles de test

Manifeste du plugin

Référence complète du schéma du manifeste

Liens associés