Si vous n’avez encore créé aucun plugin OpenClaw, lisez d’abord
Bien démarrer pour comprendre la structure de package
de base et la configuration du manifeste.
Procédure pas à pas
Package et manifeste
Étape 1 : Package et manifeste
setup.providers[].envVars afin qu’OpenClaw puisse détecter
les identifiants sans charger l’exécution de votre plugin. Ajoutez providerAuthAliases
lorsqu’une variante de fournisseur doit réutiliser l’authentification de l’id d’un autre fournisseur. modelSupport
est facultatif et permet à OpenClaw de charger automatiquement votre plugin fournisseur à partir d’identifiants
de modèle abrégés comme acme-large avant que les hooks d’exécution existent. Si vous publiez le
fournisseur sur ClawHub, ces champs openclaw.compat et openclaw.build
sont requis dans package.json.Enregistrer le fournisseur
Un fournisseur de texte minimal nécessite un Utilisez
id, un label, une auth et un catalog.
catalog est le hook d’exécution/configuration détenu par le fournisseur ; il peut appeler des
API fournisseur en direct et retourne des entrées models.providers.index.ts
registerModelCatalogProvider est la nouvelle surface de catalogue du plan de contrôle
pour l’interface de liste/aide/sélection. Utilisez-la pour les lignes de texte, de génération d’images,
de génération de vidéos et de génération de musique. Gardez les appels aux points de terminaison fournisseur et
le mappage des réponses dans le plugin ; OpenClaw possède la forme de ligne partagée, les libellés
de source et le rendu de l’aide.Il s’agit d’un fournisseur fonctionnel. Les utilisateurs peuvent maintenant exécuter
openclaw onboard --acme-ai-api-key <key> et sélectionner
acme-ai/acme-large comme modèle.Découverte de modèles en direct
Si votre fournisseur expose une API de type/models, conservez le point de terminaison
spécifique au fournisseur et la projection des lignes dans votre plugin, puis utilisez
openclaw/plugin-sdk/provider-catalog-live-runtime pour le cycle de vie de récupération partagé.
L’assistant vous donne des récupérations HTTP protégées, des en-têtes d’authentification fournisseur,
des erreurs HTTP structurées, une mise en cache TTL et un comportement de repli statique sans
placer la politique fournisseur dans le cœur d’OpenClaw.Utilisez buildLiveModelProviderConfig lorsque l’API en direct vous indique uniquement quelles
lignes du catalogue statique détenu par le fournisseur sont actuellement disponibles :index.ts
getCachedLiveProviderModelRows lorsque l’API du fournisseur retourne des
métadonnées plus riches et que le plugin doit lui-même projeter les lignes dans les
définitions de modèles OpenClaw :index.ts
run doit rester protégé par l’authentification et retourner null lorsqu’aucun identifiant utilisable
n’est disponible. Conservez un staticRun hors ligne ou un repli statique afin que les surfaces de configuration,
de documentation, de tests et de sélection ne dépendent pas d’un accès réseau en direct. Utilisez un TTL
adapté à la fraîcheur de la liste des modèles, évitez l’interrogation du système de fichiers au moment des requêtes,
et passez un readRows / readModelId spécifique au fournisseur uniquement lorsque la
réponse en amont n’est pas une forme compatible OpenAI { data: [{ id, object }] }.Si le fournisseur en amont utilise des jetons de contrôle différents de ceux d’OpenClaw, ajoutez une
petite transformation de texte bidirectionnelle au lieu de remplacer le chemin de flux :input réécrit le prompt système final et le contenu des messages texte avant
le transport. output réécrit les deltas de texte de l’assistant et le texte final avant
qu’OpenClaw analyse ses propres marqueurs de contrôle ou la livraison au canal.Pour les fournisseurs groupés qui enregistrent uniquement un fournisseur de texte avec une authentification
par clé API et une seule exécution adossée à un catalogue, préférez l’assistant plus étroit
defineSingleProviderPluginEntry(...) :buildProvider est le chemin de catalogue en direct utilisé quand OpenClaw peut résoudre une véritable
authentification de fournisseur. Il peut effectuer une découverte propre au fournisseur. Utilisez
buildStaticProvider uniquement pour les lignes hors ligne qui peuvent être affichées sans risque avant que l’authentification
soit configurée ; il ne doit pas exiger d’identifiants ni effectuer de requêtes réseau.
L’affichage models list --all d’OpenClaw exécute actuellement les catalogues statiques
uniquement pour les plugins de fournisseurs intégrés, avec une configuration vide, un environnement vide et aucun
chemin d’agent/espace de travail.Si votre flux d’authentification doit aussi corriger models.providers.*, les alias et
le modèle par défaut de l’agent pendant l’onboarding, utilisez les assistants de préréglage de
openclaw/plugin-sdk/provider-onboard. Les assistants les plus ciblés sont
createDefaultModelPresetAppliers(...),
createDefaultModelsPresetAppliers(...) et
createModelCatalogPresetAppliers(...).Quand l’endpoint natif d’un fournisseur prend en charge les blocs d’utilisation en streaming sur le
transport openai-completions normal, préférez les assistants de catalogue partagés dans
openclaw/plugin-sdk/provider-catalog-shared plutôt que de coder en dur des vérifications
d’identifiant de fournisseur. supportsNativeStreamingUsageCompat(...) et
applyProviderNativeStreamingUsageCompat(...) détectent la prise en charge à partir de la
carte des capacités d’endpoint, de sorte que les endpoints natifs de style Moonshot/DashScope
s’activent toujours même lorsqu’un plugin utilise un identifiant de fournisseur personnalisé.Les exemples de découverte en direct ci-dessus couvrent les API de fournisseur de style /models. Gardez
cette découverte dans catalog.run, protégée par une authentification utilisable, et gardez
staticRun sans réseau pour la génération de catalogue hors ligne.Ajouter la résolution dynamique de modèle
Si votre fournisseur accepte des ID de modèle arbitraires (comme un proxy ou un routeur),
ajoutez Si la résolution nécessite un appel réseau, utilisez
resolveDynamicModel :prepareDynamicModel pour un préchauffage
asynchrone - resolveDynamicModel s’exécute de nouveau une fois celui-ci terminé.Ajouter des hooks d’exécution (si nécessaire)
La plupart des fournisseurs n’ont besoin que de Familles de replay disponibles aujourd’hui :
Familles de flux disponibles aujourd’hui :
catalog + resolveDynamicModel. Ajoutez des hooks
progressivement, selon les besoins de votre fournisseur.Les constructeurs d’assistants partagés couvrent désormais les familles de replay/compatibilité d’outils
les plus courantes, de sorte que les plugins n’ont généralement pas besoin de câbler chaque hook un par un :| Famille | Ce que cela connecte | Exemples intégrés |
|---|---|---|
openai-compatible | Politique de replay partagée de style OpenAI pour les transports compatibles OpenAI, incluant l’assainissement des ID d’appels d’outils, les corrections d’ordre assistant-first et la validation générique des tours Gemini là où le transport en a besoin | moonshot, ollama, xai, zai |
anthropic-by-model | Politique de replay compatible Claude choisie par modelId, afin que les transports de messages Anthropic n’obtiennent le nettoyage des blocs de réflexion propre à Claude que lorsque le modèle résolu est réellement un ID Claude | amazon-bedrock, anthropic-vertex |
google-gemini | Politique de replay Gemini native plus assainissement du replay d’amorçage. La famille partagée garde le CLI Gemini à sortie texte sur le raisonnement balisé ; le fournisseur direct google remplace resolveReasoningOutputMode par native, car la réflexion de l’API Gemini arrive sous forme de parties de pensée natives. | google, google-gemini-cli |
passthrough-gemini | Assainissement des signatures de pensée Gemini pour les modèles Gemini exécutés via des transports proxy compatibles OpenAI ; n’active pas la validation native de replay Gemini ni les réécritures d’amorçage | openrouter, kilocode, opencode, opencode-go |
hybrid-anthropic-openai | Politique hybride pour les fournisseurs qui mélangent des surfaces de modèles de messages Anthropic et compatibles OpenAI dans un même plugin ; la suppression optionnelle des blocs de réflexion réservée à Claude reste limitée au côté Anthropic | minimax |
| Famille | Ce que cela connecte | Exemples intégrés |
|---|---|---|
google-thinking | Normalisation de la charge utile de réflexion Gemini sur le chemin de flux partagé | google, google-gemini-cli |
kilocode-thinking | Enveloppe de raisonnement Kilo sur le chemin de flux proxy partagé, avec kilo/auto et les ID de raisonnement proxy non pris en charge ignorant la réflexion injectée | kilocode |
moonshot-thinking | Mappage de charge utile native-thinking binaire Moonshot depuis la configuration + le niveau /think | moonshot |
minimax-fast-mode | Réécriture de modèle en mode rapide MiniMax sur le chemin de flux partagé | minimax, minimax-portal |
openai-responses-defaults | Enveloppes Responses natives OpenAI/Codex partagées : en-têtes d’attribution, /fast/serviceTier, verbosité du texte, recherche web native Codex, mise en forme de charge utile compatible raisonnement et gestion du contexte Responses | openai |
openrouter-thinking | Enveloppe de raisonnement OpenRouter pour les routes proxy, avec les exclusions de modèles non pris en charge/auto gérées de manière centralisée | openrouter |
tool-stream-default-on | Enveloppe tool_stream activée par défaut pour les fournisseurs comme Z.AI qui veulent le streaming d’outils sauf désactivation explicite | zai |
Seams SDK qui alimentent les constructeurs de familles
Seams SDK qui alimentent les constructeurs de familles
Chaque constructeur de famille est composé à partir d’assistants publics de plus bas niveau exportés par le même package, que vous pouvez utiliser quand un fournisseur doit sortir du schéma commun :
openclaw/plugin-sdk/provider-model-shared-ProviderReplayFamily,buildProviderReplayFamilyHooks(...)et les constructeurs de replay bruts (buildOpenAICompatibleReplayPolicy,buildAnthropicReplayPolicyForModel,buildGoogleGeminiReplayPolicy,buildHybridAnthropicOrOpenAIReplayPolicy). Exporte aussi les assistants de replay Gemini (sanitizeGoogleGeminiReplayHistory,resolveTaggedReasoningOutputMode) et les assistants d’endpoint/modèle (resolveProviderEndpoint,normalizeProviderId,normalizeGooglePreviewModelId).openclaw/plugin-sdk/provider-stream-ProviderStreamFamily,buildProviderStreamFamilyHooks(...),composeProviderStreamWrappers(...), ainsi que les enveloppes OpenAI/Codex partagées (createOpenAIAttributionHeadersWrapper,createOpenAIFastModeWrapper,createOpenAIServiceTierWrapper,createOpenAIResponsesContextManagementWrapper,createCodexNativeWebSearchWrapper), l’enveloppe compatible OpenAI DeepSeek V4 (createDeepSeekV4OpenAICompatibleThinkingWrapper), le nettoyage de préremplissage de réflexion Anthropic Messages (createAnthropicThinkingPrefillPayloadWrapper), la compatibilité d’appels d’outils en texte brut (createPlainTextToolCallCompatWrapper) et les enveloppes proxy/fournisseur partagées (createOpenRouterWrapper,createToolStreamWrapper,createMinimaxFastModeWrapper).openclaw/plugin-sdk/provider-stream-shared- enveloppes légères de charge utile et d’événements pour les chemins de fournisseurs critiques, incluantcreateOpenAICompatibleCompletionsThinkingOffWrapper,createPayloadPatchStreamWrapper,createPlainTextToolCallCompatWrapper,normalizeOpenAICompatibleReasoningPayload(...)etsetQwenChatTemplateThinking(...).openclaw/plugin-sdk/provider-tools-ProviderToolCompatFamily,buildProviderToolCompatFamilyHooks("deepseek" | "gemini" | "openai")et les assistants de schéma de fournisseur sous-jacents.
native, afin qu’OpenClaw consomme les parties de pensée natives sans ajouter de directives de prompt
<think> / <final>. Les backends de style CLI Gemini à texte seul
qui analysent une réponse finale JSON/texte peuvent conserver le contrat balisé
google-gemini partagé.Certains assistants de flux restent volontairement locaux au fournisseur. @openclaw/anthropic-provider garde wrapAnthropicProviderStream, resolveAnthropicBetas, resolveAnthropicFastMode, resolveAnthropicServiceTier et les constructeurs d’enveloppes Anthropic de plus bas niveau dans son propre seam public api.ts / contract-api.ts, car ils encodent la gestion des bêtas OAuth Claude et le contrôle de context1m. Le plugin xAI garde de même la mise en forme native xAI Responses dans son propre wrapStreamFn (alias /fast, tool_stream par défaut, nettoyage strict-tool non pris en charge, suppression de charge utile de raisonnement propre à xAI).Le même schéma de racine de package prend aussi en charge @openclaw/openai-provider (constructeurs de fournisseur, assistants de modèle par défaut, constructeurs de fournisseur realtime) et @openclaw/openrouter-provider (constructeur de fournisseur plus assistants d’onboarding/configuration).- Échange de jeton
- En-têtes personnalisés
- Identité de transport native
- Utilisation et facturation
Pour les fournisseurs qui ont besoin d’un échange de jeton avant chaque appel d’inférence :
Tous les hooks de fournisseur disponibles
Tous les hooks de fournisseur disponibles
OpenClaw appelle les hooks dans cet ordre. La plupart des fournisseurs n’en utilisent que 2 ou 3 :
les champs de fournisseur réservés à la compatibilité qu’OpenClaw n’appelle plus, tels que
Notes sur la solution de repli du runtime :
ProviderPlugin.capabilities et suppressBuiltInModel, ne sont pas répertoriés
ici.| # | Hook | Quand l’utiliser |
|---|---|---|
| 1 | catalog | Catalogue de modèles ou valeurs par défaut de l’URL de base |
| 2 | applyConfigDefaults | Valeurs globales par défaut détenues par le fournisseur lors de la matérialisation de la configuration |
| 3 | normalizeModelId | Nettoyage des alias d’ID de modèle hérités/en préversion avant la recherche |
| 4 | normalizeTransport | Nettoyage de api / baseUrl pour une famille de fournisseurs avant l’assemblage générique du modèle |
| 5 | normalizeConfig | Normaliser la configuration models.providers.<id> |
| 6 | applyNativeStreamingUsageCompat | Réécritures de compatibilité d’utilisation en streaming natif pour les fournisseurs de configuration |
| 7 | resolveConfigApiKey | Résolution d’authentification par marqueur d’environnement détenue par le fournisseur |
| 8 | resolveSyntheticAuth | Authentification synthétique locale/auto-hébergée ou adossée à la configuration |
| 9 | shouldDeferSyntheticProfileAuth | Abaisser les espaces réservés de profils stockés synthétiques derrière l’authentification par environnement/configuration |
| 10 | resolveDynamicModel | Accepter des ID de modèle amont arbitraires |
| 11 | prepareDynamicModel | Récupération asynchrone des métadonnées avant la résolution |
| 12 | normalizeResolvedModel | Réécritures de transport avant l’exécuteur |
| 13 | normalizeToolSchemas | Nettoyage des schémas d’outils détenu par le fournisseur avant l’enregistrement |
| 14 | inspectToolSchemas | Diagnostics des schémas d’outils détenus par le fournisseur |
| 15 | resolveReasoningOutputMode | Contrat de sortie de raisonnement balisée ou native |
| 16 | prepareExtraParams | Paramètres de requête par défaut |
| 17 | createStreamFn | Transport StreamFn entièrement personnalisé |
| 19 | wrapStreamFn | Enveloppes d’en-têtes/corps personnalisées sur le chemin de flux normal |
| 20 | resolveTransportTurnState | En-têtes/métadonnées natifs par tour |
| 21 | resolveWebSocketSessionPolicy | En-têtes de session WS natifs/temps de récupération |
| 22 | formatApiKey | Forme personnalisée du jeton d’exécution |
| 23 | refreshOAuth | Actualisation OAuth personnalisée |
| 24 | buildAuthDoctorHint | Conseils de réparation d’authentification |
| 25 | matchesContextOverflowError | Détection de dépassement détenue par le fournisseur |
| 26 | classifyFailoverReason | Classification des limites de débit/surcharges détenue par le fournisseur |
| 27 | isCacheTtlEligible | Contrôle du TTL du cache de prompts |
| 28 | buildMissingAuthMessage | Indication personnalisée d’authentification manquante |
| 29 | augmentModelCatalog | Lignes synthétiques de compatibilité ascendante |
| 30 | resolveThinkingProfile | Ensemble d’options /think propre au modèle |
| 31 | isBinaryThinking | Compatibilité de réflexion binaire activée/désactivée |
| 32 | supportsXHighThinking | Compatibilité de prise en charge du raisonnement xhigh |
| 33 | resolveDefaultThinkingLevel | Compatibilité de la stratégie /think par défaut |
| 34 | isModernModelRef | Correspondance de modèle en direct/smoke |
| 35 | prepareRuntimeAuth | Échange de jeton avant l’inférence |
| 36 | resolveUsageAuth | Analyse personnalisée des identifiants d’utilisation |
| 37 | fetchUsageSnapshot | Point de terminaison d’utilisation personnalisé |
| 38 | createEmbeddingProvider | Adaptateur d’embeddings détenu par le fournisseur pour la mémoire/recherche |
| 39 | buildReplayPolicy | Stratégie personnalisée de relecture/compaction de transcript |
| 40 | sanitizeReplayHistory | Réécritures de relecture propres au fournisseur après le nettoyage générique |
| 41 | validateReplayTurns | Validation stricte des tours de relecture avant l’exécuteur intégré |
| 42 | onModelSelected | Rappel après sélection, par exemple pour la télémétrie |
normalizeConfigvérifie d’abord le fournisseur correspondant, puis les autres plugins de fournisseur capables d’exposer ce hook jusqu’à ce que l’un d’eux modifie réellement la configuration. Si aucun hook de fournisseur ne réécrit une entrée de configuration prise en charge de la famille Google, le normalisateur de configuration Google intégré s’applique quand même.resolveConfigApiKeyutilise le hook du fournisseur lorsqu’il est exposé. Amazon Bedrock conserve la résolution des marqueurs d’environnement AWS dans son plugin de fournisseur ; l’authentification du runtime elle-même utilise toujours la chaîne par défaut du SDK AWS lorsqu’elle est configurée avecauth: "aws-sdk".resolveThinkingProfile(ctx)reçoit leprovidersélectionné,modelId, l’indication facultative de cataloguereasoningfusionnée, et les faitscompatfacultatifs du modèle fusionnés. Utilisezcompatuniquement pour sélectionner l’interface ou le profil de réflexion du fournisseur.resolveSystemPromptContributionpermet à un fournisseur d’injecter des conseils de prompt système compatibles avec le cache pour une famille de modèles. Préférez-le àbefore_prompt_buildlorsque le comportement appartient à un fournisseur ou une famille de modèles et doit préserver la séparation stable/dynamique du cache.
Ajouter des capacités supplémentaires (facultatif)
Étape 5 : Ajouter des capacités supplémentaires
Un plugin de fournisseur peut enregistrer des embeddings, la synthèse vocale, la transcription en temps réel, la voix en temps réel, la compréhension des médias, la génération d’images, la génération de vidéos, la récupération web et la recherche web en plus de l’inférence de texte. OpenClaw classe cela comme un plugin à capacité hybride - le modèle recommandé pour les plugins d’entreprise (un plugin par fournisseur). Consultez Internes : propriété des capacités.Enregistrez chaque capacité dansregister(api) à côté de votre appel
api.registerProvider(...) existant. Choisissez uniquement les onglets dont vous avez besoin :- Synthèse vocale (TTS)
- Transcription en temps réel
- Voix en temps réel
- Media understanding
- Embeddings
- Image and video generation
- Web fetch and search
assertOkOrThrowProviderError(...) pour les échecs HTTP du fournisseur afin que
les plugins partagent des lectures plafonnées des corps d’erreur, l’analyse des erreurs JSON et
les suffixes d’ID de requête.Test
Étape 6 : tester
src/provider.test.ts
Publier sur ClawHub
Les Plugins de fournisseurs se publient de la même manière que n’importe quel autre Plugin de code externe :clawhub package publish.
Structure des fichiers
Référence d’ordre du catalogue
catalog.order contrôle le moment où votre catalogue est fusionné par rapport aux fournisseurs
intégrés :
| Ordre | Quand | Cas d’utilisation |
|---|---|---|
simple | Premier passage | Fournisseurs simples à clé API |
profile | Après simple | Fournisseurs soumis aux profils d’authentification |
paired | Après profile | Synthétiser plusieurs entrées liées |
late | Dernier passage | Remplacer des fournisseurs existants (gagne en cas de collision) |
Prochaines étapes
- Plugins de canaux - si votre Plugin fournit également un canal
- SDK Runtime - assistants
api.runtime(TTS, recherche, sous-agent) - Vue d’ensemble du SDK - référence complète des imports de sous-chemins
- Internes du Plugin - détails des hooks et exemples intégrés