Création de plugins de fournisseur
Ce guide vous accompagne dans la création d’un plugin de fournisseur qui ajoute un fournisseur de modèles (LLM) à OpenClaw. À la fin, vous disposerez d’un fournisseur avec un catalogue de modèles, une authentification par clé API et une résolution dynamique des modèles.Si vous n’avez encore créé aucun plugin OpenClaw, lisez d’abord
Getting Started pour la structure de package de base
et la configuration du manifeste.
Procédure pas à pas
Package et manifeste
providerAuthEnvVars 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 d’un autre identifiant de fournisseur. modelSupport
est facultatif et permet à OpenClaw de charger automatiquement votre plugin de fournisseur à partir
d’identifiants de modèle abrégés comme acme-large avant que les hooks d’exécution n’existent. Si vous publiez le
fournisseur sur ClawHub, les champs openclaw.compat et openclaw.build
sont requis dans package.json.Enregistrer le fournisseur
Un fournisseur minimal a besoin de C’est un fournisseur fonctionnel. Les utilisateurs peuvent désormais exécuter
Si votre flux d’authentification doit aussi corriger
id, label, auth et catalog :index.ts
openclaw onboard --acme-ai-api-key <key> et sélectionner
acme-ai/acme-large comme modèle.Si le fournisseur 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 l’invite système finale 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 n’analyse ses propres marqueurs de contrôle ou la livraison au canal.Pour les fournisseurs intégrés qui enregistrent seulement un fournisseur de texte avec authentification
par clé API plus une seule exécution adossée à un catalogue, préférez l’assistant plus étroit
defineSingleProviderPluginEntry(...) :models.providers.*, les alias et
le modèle par défaut de l’agent pendant l’intégration, utilisez les assistants prédéfinis de
openclaw/plugin-sdk/provider-onboard. Les assistants les plus ciblés sont
createDefaultModelPresetAppliers(...),
createDefaultModelsPresetAppliers(...) et
createModelCatalogPresetAppliers(...).Lorsqu’un point de terminaison natif de fournisseur prend en charge les blocs d’utilisation en streaming sur le
transport normal openai-completions, préférez les assistants de catalogue partagés dans
openclaw/plugin-sdk/provider-catalog-shared au lieu 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 du point de terminaison, de sorte que les points de terminaison natifs de type Moonshot/DashScope continuent
d’être activés même lorsqu’un plugin utilise un identifiant de fournisseur personnalisé.Ajouter la résolution dynamique des modèles
Si votre fournisseur accepte des identifiants 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 après son achèvement.Ajouter des hooks d’exécution (si nécessaire)
La plupart des fournisseurs n’ont besoin que de Familles de rejeu disponibles aujourd’hui :
Exemples intégrés réels :
Exemples intégrés réels :
catalog + resolveDynamicModel. Ajoutez des hooks
progressivement selon les besoins de votre fournisseur.Les constructeurs d’assistants partagés couvrent désormais les familles de rejeu/compatibilité des outils
les plus courantes, de sorte que les plugins n’ont généralement pas besoin de câbler chaque hook à la main :| Famille | Ce qu’elle câble |
|---|---|
openai-compatible | Politique de rejeu partagée de style OpenAI pour les transports compatibles OpenAI, y compris l’assainissement des identifiants d’appel d’outil, les corrections d’ordre assistant-en-premier et la validation générique des tours Gemini lorsque le transport en a besoin |
anthropic-by-model | Politique de rejeu sensible à Claude choisie par modelId, de sorte que les transports de messages Anthropic n’obtiennent le nettoyage des blocs de réflexion propres à Claude que lorsque le modèle résolu est réellement un identifiant Claude |
google-gemini | Politique de rejeu Gemini native plus assainissement du rejeu d’amorçage et mode de sortie du raisonnement balisé |
passthrough-gemini | Assainissement de la signature de pensée Gemini pour les modèles Gemini exécutés via des transports proxy compatibles OpenAI ; n’active pas la validation native du rejeu Gemini ni les réécritures d’amorçage |
hybrid-anthropic-openai | Politique hybride pour les fournisseurs qui mélangent dans un même plugin des surfaces de modèles de messages Anthropic et de compatibilité OpenAI ; la suppression facultative des blocs de réflexion réservés à Claude reste limitée au côté Anthropic |
googleetgoogle-gemini-cli:google-geminiopenrouter,kilocode,opencodeetopencode-go:passthrough-geminiamazon-bedrocketanthropic-vertex:anthropic-by-modelminimax:hybrid-anthropic-openaimoonshot,ollama,xaietzai:openai-compatible
| Famille | Ce qu’elle câble |
|---|---|
google-thinking | Normalisation de la charge utile de réflexion Gemini sur le chemin de flux partagé |
kilocode-thinking | Wrapper de raisonnement Kilo sur le chemin de flux proxy partagé, avec kilo/auto et les identifiants de raisonnement proxy non pris en charge qui ignorent la réflexion injectée |
moonshot-thinking | Mappage de la charge utile native de réflexion binaire Moonshot à partir de la configuration + du niveau /think |
minimax-fast-mode | Réécriture du modèle en mode rapide MiniMax sur le chemin de flux partagé |
openai-responses-defaults | Wrappers natifs partagés OpenAI/Codex Responses : en-têtes d’attribution, /fast/serviceTier, verbosité du texte, recherche web Codex native, façonnage de charge utile de compatibilité de raisonnement et gestion du contexte Responses |
openrouter-thinking | Wrapper de raisonnement OpenRouter pour les routes proxy, avec les sauts pour modèles non pris en charge/auto gérés de manière centralisée |
tool-stream-default-on | Wrapper tool_stream activé par défaut pour les fournisseurs comme Z.AI qui veulent le streaming d’outils sauf s’il est explicitement désactivé |
googleetgoogle-gemini-cli:google-thinkingkilocode:kilocode-thinkingmoonshot:moonshot-thinkingminimaxetminimax-portal:minimax-fast-modeopenaietopenai-codex:openai-responses-defaultsopenrouter:openrouter-thinkingzai:tool-stream-default-on
openclaw/plugin-sdk/provider-model-shared exporte aussi l’énumération des familles de rejeu
ainsi que les assistants partagés à partir desquels ces familles sont construites. Les
exports publics courants comprennent :ProviderReplayFamilybuildProviderReplayFamilyHooks(...)- des constructeurs de rejeu partagés tels que
buildOpenAICompatibleReplayPolicy(...),buildAnthropicReplayPolicyForModel(...),buildGoogleGeminiReplayPolicy(...)etbuildHybridAnthropicOrOpenAIReplayPolicy(...) - des assistants de rejeu Gemini tels que
sanitizeGoogleGeminiReplayHistory(...)etresolveTaggedReasoningOutputMode() - des assistants de point de terminaison/modèle tels que
resolveProviderEndpoint(...),normalizeProviderId(...),normalizeGooglePreviewModelId(...)etnormalizeNativeXaiModelId(...)
openclaw/plugin-sdk/provider-stream expose à la fois le constructeur de famille et
les assistants de wrapper publics réutilisés par ces familles. Les exports publics
courants comprennent :ProviderStreamFamilybuildProviderStreamFamilyHooks(...)composeProviderStreamWrappers(...)- des wrappers OpenAI/Codex partagés tels que
createOpenAIAttributionHeadersWrapper(...),createOpenAIFastModeWrapper(...),createOpenAIServiceTierWrapper(...),createOpenAIResponsesContextManagementWrapper(...)etcreateCodexNativeWebSearchWrapper(...) - des wrappers proxy/fournisseur partagés tels que
createOpenRouterWrapper(...),createToolStreamWrapper(...)etcreateMinimaxFastModeWrapper(...)
@openclaw/anthropic-provider exporte
wrapAnthropicProviderStream, resolveAnthropicBetas,
resolveAnthropicFastMode, resolveAnthropicServiceTier et les
constructeurs de wrappers Anthropic de plus bas niveau depuis sa surface publique api.ts /
contract-api.ts. Ces assistants restent spécifiques à Anthropic, car
ils encodent aussi la gestion des bêtas Claude OAuth et le contrôle context1m.D’autres fournisseurs intégrés gardent aussi des wrappers spécifiques au transport en local lorsque
le comportement n’est pas proprement partageable entre familles. Exemple actuel : le
plugin xAI intégré conserve le façonnage natif xAI Responses dans son propre
wrapStreamFn, y compris les réécritures d’alias /fast, le tool_stream par défaut,
le nettoyage strict des outils non pris en charge et la suppression
de la charge utile de raisonnement spécifique à xAI.openclaw/plugin-sdk/provider-tools expose actuellement une famille partagée
de schémas d’outil ainsi que des assistants partagés de schéma/compatibilité :ProviderToolCompatFamilydocumente aujourd’hui l’inventaire partagé des familles.buildProviderToolCompatFamilyHooks("gemini")câble le nettoyage des schémas Gemini- les diagnostics pour les fournisseurs qui ont besoin de schémas d’outil sûrs pour Gemini.
normalizeGeminiToolSchemas(...)etinspectGeminiToolSchemas(...)sont les assistants publics sous-jacents pour les schémas Gemini.resolveXaiModelCompatPatch()renvoie le correctif de compatibilité xAI intégré :toolSchemaProfile: "xai", mots-clés de schéma non pris en charge, prise en charge native deweb_searchet décodage des arguments d’appel d’outil avec entités HTML.applyXaiModelCompat(model)applique ce même correctif de compatibilité xAI à un modèle résolu avant qu’il n’atteigne le runner.
normalizeResolvedModel plus
contributeResolvedModelCompat pour que ces métadonnées de compatibilité restent
gérées par le fournisseur au lieu de coder en dur les règles xAI dans le cœur.Le même modèle de racine de package soutient aussi d’autres fournisseurs intégrés :@openclaw/openai-provider:api.tsexporte des constructeurs de fournisseur, des assistants de modèle par défaut et des constructeurs de fournisseur temps réel@openclaw/openrouter-provider:api.tsexporte le constructeur de fournisseur ainsi que des assistants d’intégration/configuration
- Échange de jetons
- En-têtes personnalisés
- Identité de transport native
- Utilisation et facturation
Pour les fournisseurs qui nécessitent 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 :
Remarques sur le repli à l’exécution :
| # | Hook | Quand l’utiliser |
|---|---|---|
| 1 | catalog | Catalogue de modèles ou valeurs par défaut d’URL de base |
| 2 | applyConfigDefaults | Valeurs par défaut globales gérées par le fournisseur pendant la matérialisation de la configuration |
| 3 | normalizeModelId | Nettoyage des alias d’identifiant de modèle hérités/de préversion avant la recherche |
| 4 | normalizeTransport | Nettoyage de la famille de fournisseur api / baseUrl 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 gérée par le fournisseur |
| 8 | resolveSyntheticAuth | Authentification synthétique locale/autohébergée ou adossée à la configuration |
| 9 | shouldDeferSyntheticProfileAuth | Placer les espaces réservés de profil stockés synthétiques derrière l’authentification d’environnement/de configuration |
| 10 | resolveDynamicModel | Accepter des identifiants de modèle amont arbitraires |
| 11 | prepareDynamicModel | Récupération asynchrone de métadonnées avant la résolution |
| 12 | normalizeResolvedModel | Réécritures de transport avant le runner |
-
normalizeConfigvérifie d’abord le fournisseur correspondant, puis les autres plugins de fournisseur compatibles avec les hooks 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 normaliseur de configuration Google intégré s’applique encore. -
resolveConfigApiKeyutilise le hook du fournisseur lorsqu’il est exposé. Le chemin intégréamazon-bedrockdispose aussi ici d’un résolveur intégré de marqueur d’environnement AWS, même si l’authentification d’exécution Bedrock elle-même utilise toujours la chaîne par défaut du SDK AWS. | 13 |contributeResolvedModelCompat| Drapeaux de compatibilité pour les modèles fournisseur derrière un autre transport compatible | | 14 |capabilities| Ancien ensemble statique de capacités ; compatibilité uniquement | | 15 |normalizeToolSchemas| Nettoyage des schémas d’outil géré par le fournisseur avant l’enregistrement | | 16 |inspectToolSchemas| Diagnostics de schémas d’outil gérés par le fournisseur | | 17 |resolveReasoningOutputMode| Contrat de sortie de raisonnement balisé ou natif | | 18 |prepareExtraParams| Paramètres de requête par défaut | | 19 |createStreamFn| Transport StreamFn entièrement personnalisé | | 20 |wrapStreamFn| Wrappers personnalisés d’en-têtes/corps sur le chemin de flux normal | | 21 |resolveTransportTurnState| En-têtes/métadonnées natives par tour | | 22 |resolveWebSocketSessionPolicy| En-têtes de session WS natives/refroidissement | | 23 |formatApiKey| Forme personnalisée du jeton d’exécution | | 24 |refreshOAuth| Actualisation OAuth personnalisée | | 25 |buildAuthDoctorHint| Indications de réparation d’authentification | | 26 |matchesContextOverflowError| Détection de dépassement gérée par le fournisseur | | 27 |classifyFailoverReason| Classification de limitation de débit/surcharge gérée par le fournisseur | | 28 |isCacheTtlEligible| Contrôle TTL du cache d’invite | | 29 |buildMissingAuthMessage| Indication personnalisée d’authentification manquante | | 30 |suppressBuiltInModel| Masquer les lignes amont obsolètes | | 31 |augmentModelCatalog| Lignes synthétiques de compatibilité anticipée | | 32 |isBinaryThinking| Réflexion binaire activée/désactivée | | 33 |supportsXHighThinking| Prise en charge du raisonnementxhigh| | 34 |resolveDefaultThinkingLevel| Politique/thinkpar défaut | | 35 |isModernModelRef| Correspondance des modèles en direct/en test de fumée | | 36 |prepareRuntimeAuth| Échange de jeton avant l’inférence | | 37 |resolveUsageAuth| Analyse personnalisée des identifiants d’utilisation | | 38 |fetchUsageSnapshot| Point de terminaison d’utilisation personnalisé | | 39 |createEmbeddingProvider| Adaptateur d’embedding géré par le fournisseur pour la mémoire/la recherche | | 40 |buildReplayPolicy| Politique personnalisée de rejeu/compaction de transcription | | 41 |sanitizeReplayHistory| Réécritures de rejeu spécifiques au fournisseur après le nettoyage générique | | 42 |validateReplayTurns| Validation stricte des tours de rejeu avant le runner intégré | | 43 |onModelSelected| Callback après sélection (par exemple télémétrie) | Remarque sur l’ajustement des prompts :resolveSystemPromptContributionpermet à un fournisseur d’injecter des indications d’invite système tenant compte du cache pour une famille de modèles. Préférez-le àbefore_prompt_buildlorsque le comportement appartient à un fournisseur/une famille de modèles et doit préserver la séparation stable/dynamique du cache.
Ajouter des capacités supplémentaires (facultatif)
Un plugin de fournisseur peut enregistrer la parole, la transcription temps réel, la voix en temps réel,
la compréhension multimédia, la génération d’images, la génération vidéo, la récupération web
et la recherche web en plus de l’inférence de texte :OpenClaw classe cela comme un plugin à capacités hybrides. C’est le
modèle recommandé pour les plugins d’entreprise (un plugin par fournisseur). Voir
Internals: Capability Ownership.Pour la génération vidéo, privilégiez la forme de capacités sensible au mode montrée ci-dessus :
generate, imageToVideo et videoToVideo. Les champs agrégés plats tels
que maxInputImages, maxInputVideos et maxDurationSeconds ne
suffisent pas à annoncer proprement la prise en charge des modes de transformation ou les modes désactivés.Les fournisseurs de génération musicale doivent suivre le même modèle :
generate pour la génération à partir de prompt seul et edit pour la génération
basée sur une image de référence. Les champs agrégés plats tels que maxInputImages,
supportsLyrics et supportsFormat ne suffisent pas à annoncer la prise en charge de la modification ;
des blocs explicites generate / edit sont le contrat attendu.Publier sur ClawHub
Les plugins de fournisseur se publient comme n’importe quel autre plugin de code externe :clawhub package publish.
Structure des fichiers
Référence de l’ordre des catalogues
catalog.order contrôle le moment où votre catalogue est fusionné par rapport aux
fournisseurs intégrés :
| Ordre | Moment | Cas d’usage |
|---|---|---|
simple | Première passe | Fournisseurs simples à clé API |
profile | Après simple | Fournisseurs conditionnés par des profils d’authentification |
paired | Après profile | Synthétiser plusieurs entrées liées |
late | Dernière passe | Remplacer des fournisseurs existants (gagne en cas de collision) |
Étapes suivantes
- Plugins de canal — si votre plugin fournit aussi un canal
- SDK Runtime — assistants
api.runtime(TTS, recherche, sous-agent) - Vue d’ensemble du SDK — référence complète des importations de sous-chemins
- Internes des plugins — détails des hooks et exemples intégrés