Créer des plugins de fournisseur
Ce guide explique pas à pas comment créer un plugin de fournisseur qui ajoute un fournisseur de modèles (LLM) à OpenClaw. À la fin, vous aurez un fournisseur avec un catalogue de modèles, une auth par clé API et une résolution dynamique des modèles.Si vous n’avez encore jamais créé de plugin OpenClaw, lisez d’abord
Premiers pas pour la structure de base du package
et la configuration du manifeste.
Guide pas à pas
Package et manifeste
providerAuthEnvVars afin qu’OpenClaw puisse détecter
les identifiants sans charger le runtime de votre plugin. 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 runtime n’existent. Si vous publiez le
fournisseur sur ClawHub, ces champs openclaw.compat et openclaw.build
sont obligatoires dans package.json.Enregistrer le fournisseur
Un fournisseur minimal a besoin d’un C’est un fournisseur fonctionnel. Les utilisateurs peuvent maintenant
exécuter Si votre flux d’auth doit aussi patcher
id, label, auth, et catalog :index.ts
openclaw onboard --acme-ai-api-key <key> et sélectionner
acme-ai/acme-large comme modèle.Pour les fournisseurs intégrés qui n’enregistrent qu’un seul fournisseur texte avec une auth par clé API
plus un seul runtime adossé à un catalogue, préférez le helper plus étroit
defineSingleProviderPluginEntry(...) :models.providers.*, les alias, et
le modèle par défaut de l’agent pendant l’onboarding, utilisez les helpers prédéfinis de
openclaw/plugin-sdk/provider-onboard. Les helpers les plus étroits sont
createDefaultModelPresetAppliers(...),
createDefaultModelsPresetAppliers(...), et
createModelCatalogPresetAppliers(...).Lorsqu’un point de terminaison natif du fournisseur prend en charge les blocs d’usage streamés sur le
transport normal openai-completions, préférez les helpers de catalogue partagés de
openclaw/plugin-sdk/provider-catalog-shared plutôt que de coder en dur des vérifications d’ID 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 puissent encore activer cette compatibilité même lorsqu’un plugin utilise un ID fournisseur personnalisé.Ajouter la résolution dynamique des modèles
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 à nouveau après sa fin.Ajouter des hooks runtime (si nécessaire)
La plupart des fournisseurs n’ont besoin que de Familles de relecture disponibles aujourd’hui :
Exemples intégrés réels :
Exemples intégrés réels :
catalog + resolveDynamicModel. Ajoutez les hooks
progressivement à mesure que votre fournisseur en a besoin.Des builders de helpers partagés couvrent maintenant les familles les plus courantes de relecture/compatibilité d’outils,
de sorte que les plugins n’ont généralement plus besoin de câbler chaque hook un par un :| Famille | Ce qu’elle câble |
|---|---|
openai-compatible | Politique partagée de relecture de style OpenAI pour les transports compatibles OpenAI, y compris la sanitation des tool-call-id, les correctifs d’ordre assistant-first, et la validation générique des tours Gemini lorsque le transport en a besoin |
anthropic-by-model | Politique de relecture adaptée à Claude choisie par modelId, de sorte que les transports de messages Anthropic ne reçoivent le nettoyage des thinking-blocks spécifique à Claude que lorsque le modèle résolu est réellement un identifiant Claude |
google-gemini | Politique native de relecture Gemini plus sanitation de bootstrap replay et mode de sortie de raisonnement tagué |
passthrough-gemini | Sanitation des thought-signatures Gemini pour les modèles Gemini exécutés via des transports proxy compatibles OpenAI ; n’active pas la validation native de relecture Gemini ni les réécritures de bootstrap |
hybrid-anthropic-openai | Politique hybride pour les fournisseurs qui mélangent des surfaces de modèles Anthropics-message et compatibles OpenAI dans un seul plugin ; l’abandon facultatif des thinking-blocks uniquement pour Claude reste limité au côté Anthropic |
googleetgoogle-gemini-cli:google-geminiopenrouter,kilocode,opencode, etopencode-go:passthrough-geminiamazon-bedrocketanthropic-vertex:anthropic-by-modelminimax:hybrid-anthropic-openaimoonshot,ollama,xai, etzai:openai-compatible
| Famille | Ce qu’elle câble |
|---|---|
google-thinking | Normalisation des charges utiles de thinking Gemini sur le chemin de stream partagé |
kilocode-thinking | Enveloppe de raisonnement Kilo sur le chemin de stream proxy partagé, avec kilo/auto et les identifiants de raisonnement proxy non pris en charge qui ignorent l’injection de thinking |
moonshot-thinking | Mappage de charge utile native-thinking binaire Moonshot depuis la config + niveau /think |
minimax-fast-mode | Réécriture de modèle fast-mode MiniMax sur le chemin de stream partagé |
openai-responses-defaults | Enveloppes Responses natives partagées OpenAI/Codex : en-têtes d’attribution, /fast/serviceTier, verbosité texte, recherche web native Codex, façonnage de charge utile de compatibilité de raisonnement, et gestion du contexte Responses |
openrouter-thinking | Enveloppe de raisonnement OpenRouter pour les routes proxy, avec gestion centralisée des modèles non pris en charge/du mode auto |
tool-stream-default-on | Enveloppe tool_stream activée par défaut pour les fournisseurs comme Z.AI qui veulent le streaming des outils sauf désactivation explicite |
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’enum des familles de relecture
ainsi que les helpers partagés à partir desquels ces familles sont construites. Les
exports publics courants incluent :ProviderReplayFamilybuildProviderReplayFamilyHooks(...)- des builders de relecture partagés tels que
buildOpenAICompatibleReplayPolicy(...),buildAnthropicReplayPolicyForModel(...),buildGoogleGeminiReplayPolicy(...), etbuildHybridAnthropicOrOpenAIReplayPolicy(...) - des helpers de relecture Gemini comme
sanitizeGoogleGeminiReplayHistory(...)etresolveTaggedReasoningOutputMode() - des helpers endpoint/modèle comme
resolveProviderEndpoint(...),normalizeProviderId(...),normalizeGooglePreviewModelId(...), etnormalizeNativeXaiModelId(...)
openclaw/plugin-sdk/provider-stream expose à la fois le builder de famille et
les helpers publics d’enveloppe réutilisés par ces familles. Les exports publics
courants incluent :ProviderStreamFamilybuildProviderStreamFamilyHooks(...)composeProviderStreamWrappers(...)- des enveloppes partagées OpenAI/Codex comme
createOpenAIAttributionHeadersWrapper(...),createOpenAIFastModeWrapper(...),createOpenAIServiceTierWrapper(...),createOpenAIResponsesContextManagementWrapper(...), etcreateCodexNativeWebSearchWrapper(...) - des enveloppes partagées proxy/fournisseur comme
createOpenRouterWrapper(...),createToolStreamWrapper(...), etcreateMinimaxFastModeWrapper(...)
@openclaw/anthropic-provider exporte
wrapAnthropicProviderStream, resolveAnthropicBetas,
resolveAnthropicFastMode, resolveAnthropicServiceTier, et les
builders Anthropic de plus bas niveau depuis sa couture publique api.ts /
contract-api.ts. Ces helpers restent spécifiques à Anthropic parce
qu’ils encodent aussi la gestion du bêta OAuth Claude et le contrôle context1m.D’autres fournisseurs intégrés gardent également des enveloppes spécifiques au transport en local lorsque
le comportement ne se partage pas proprement entre familles. Exemple actuel : le
plugin xAI intégré garde la mise en forme native xAI Responses dans son propre
wrapStreamFn, y compris les réécritures d’alias /fast, le tool_stream
activé par défaut, le nettoyage des strict-tool non pris en charge, et la suppression
des charges utiles de raisonnement spécifiques à xAI.openclaw/plugin-sdk/provider-tools expose actuellement une seule famille partagée
de schéma d’outils plus des helpers de schéma/compatibilité partagés :ProviderToolCompatFamilydocumente l’inventaire partagé des familles aujourd’hui.buildProviderToolCompatFamilyHooks("gemini")câble le nettoyage- les diagnostics des schémas Gemini pour les fournisseurs qui ont besoin de schémas d’outils compatibles Gemini.
normalizeGeminiToolSchemas(...)etinspectGeminiToolSchemas(...)sont les helpers publics sous-jacents pour les schémas Gemini.resolveXaiModelCompatPatch()renvoie le patch de compatibilité xAI intégré :toolSchemaProfile: "xai", mots-clés de schéma non pris en charge, prise en charge native deweb_search, et décodage des arguments d’appel d’outil avec entités HTML.applyXaiModelCompat(model)applique ce même patch de compatibilité xAI à un modèle résolu avant qu’il n’atteigne l’exécuteur.
normalizeResolvedModel plus
contributeResolvedModelCompat pour garder ces métadonnées de compatibilité
détenues par le fournisseur au lieu de coder en dur des règles xAI dans le cœur.Ce même motif à la racine du package alimente aussi d’autres fournisseurs intégrés :@openclaw/openai-provider:api.tsexporte les builders de fournisseur, les helpers de modèle par défaut, et les builders de fournisseur realtime@openclaw/openrouter-provider:api.tsexporte le builder de fournisseur ainsi que les helpers d’onboarding/configuration
- Échange de jeton
- En-têtes personnalisés
- Identité de transport native
- Usage 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 :
Remarques sur le repli runtime :
| # | Hook | Quand l’utiliser |
|---|---|---|
| 1 | catalog | Catalogue de modèles ou valeurs par défaut de baseUrl |
| 2 | applyConfigDefaults | Valeurs par défaut globales détenues par le fournisseur lors de la matérialisation de la config |
| 3 | normalizeModelId | Nettoyage des alias d’identifiants de modèle hérités/preview avant la recherche |
| 4 | normalizeTransport | Nettoyage api / baseUrl de la famille de fournisseur avant l’assemblage générique du modèle |
| 5 | normalizeConfig | Normaliser la configuration models.providers.<id> |
| 6 | applyNativeStreamingUsageCompat | Réécritures de compatibilité d’usage streamé natif pour les fournisseurs de config |
| 7 | resolveConfigApiKey | Résolution d’auth à marqueur env détenue par le fournisseur |
| 8 | resolveSyntheticAuth | Auth synthétique locale/self-hosted ou adossée à la config |
| 9 | shouldDeferSyntheticProfileAuth | Reléguer les espaces réservés de profils stockés synthétiques derrière l’auth env/config |
| 10 | resolveDynamicModel | Accepter des ID de modèle amont arbitraires |
| 11 | prepareDynamicModel | Récupération asynchrone de métadonnées avant résolution |
| 12 | normalizeResolvedModel | Réécritures de transport avant l’exécuteur |
normalizeConfigvérifie d’abord le fournisseur correspondant, puis les autres plugins de fournisseur capables de hook jusqu’à ce que l’un modifie effectivement la config. Si aucun hook de fournisseur ne réécrit une entrée de config de famille Google prise en charge, le normaliseur de config Google intégré s’applique tout de même.resolveConfigApiKeyutilise le hook du fournisseur lorsqu’il est exposé. Le chemin intégréamazon-bedrockpossède aussi un résolveur intégré de marqueur env AWS ici, même si l’auth runtime Bedrock elle-même utilise toujours la chaîne par défaut du SDK AWS. | 13 |contributeResolvedModelCompat| Drapeaux de compatibilité pour les modèles d’un fournisseur derrière un autre transport compatible | | 14 |capabilities| Sac statique de capacités hérité ; compatibilité uniquement | | 15 |normalizeToolSchemas| Nettoyage des schémas d’outils détenu par le fournisseur avant enregistrement | | 16 |inspectToolSchemas| Diagnostics de schémas d’outils détenus par le fournisseur | | 17 |resolveReasoningOutputMode| Contrat de sortie de raisonnement tagué vs natif | | 18 |prepareExtraParams| Paramètres de requête par défaut | | 19 |createStreamFn| Transport StreamFn entièrement personnalisé | | 20 |wrapStreamFn| Enveloppes d’en-têtes/corps personnalisées sur le chemin de stream normal | | 21 |resolveTransportTurnState| En-têtes/métadonnées natifs par tour | | 22 |resolveWebSocketSessionPolicy| En-têtes/cooldown de session WS natifs | | 23 |formatApiKey| Format personnalisé du jeton runtime | | 24 |refreshOAuth| Rafraîchissement OAuth personnalisé | | 25 |buildAuthDoctorHint| Conseils de réparation d’auth | | 26 |matchesContextOverflowError| Détection de dépassement détenue par le fournisseur | | 27 |classifyFailoverReason| Classification de limite de débit/surcharge détenue par le fournisseur | | 28 |isCacheTtlEligible| Contrôle TTL du cache de prompt | | 29 |buildMissingAuthMessage| Indice personnalisé d’auth manquante | | 30 |suppressBuiltInModel| Masquer des lignes amont obsolètes | | 31 |augmentModelCatalog| Lignes synthétiques de compatibilité ascendante | | 32 |isBinaryThinking| Thinking binaire activé/désactivé | | 33 |supportsXHighThinking| Prise en charge du raisonnementxhigh| | 34 |resolveDefaultThinkingLevel| Politique/thinkpar défaut | | 35 |isModernModelRef| Correspondance live/smoke des modèles | | 36 |prepareRuntimeAuth| Échange de jeton avant l’inférence | | 37 |resolveUsageAuth| Analyse personnalisée des identifiants d’usage | | 38 |fetchUsageSnapshot| Point de terminaison d’usage personnalisé | | 39 |createEmbeddingProvider| Adaptateur d’embedding détenu par le fournisseur pour mémoire/recherche | | 40 |buildReplayPolicy| Politique personnalisée de relecture/compaction de transcription | | 41 |sanitizeReplayHistory| Réécritures spécifiques au fournisseur après nettoyage générique | | 42 |validateReplayTurns| Validation stricte des tours de relecture avant l’exécuteur embarqué | | 43 |onModelSelected| Callback post-sélection (par ex. télémétrie) |
Ajouter des capacités supplémentaires (facultatif)
Un plugin de fournisseur peut enregistrer la synthèse vocale, la transcription temps réel, la voix temps réel,
la compréhension média, la génération d’image, la génération de vidéo, la récupération web,
et la recherche web en plus de l’inférence texte :OpenClaw classe cela comme un plugin hybrid-capability. C’est le
modèle recommandé pour les plugins d’entreprise (un plugin par fournisseur). Voir
Internals: Propriété des capacités.
Publier sur ClawHub
Les plugins de fournisseur se publient comme n’importe quel autre plugin de code externe :clawhub package publish.
Structure de fichiers
Référence de l’ordre de catalogue
catalog.order contrôle quand votre catalogue est fusionné par rapport aux
fournisseurs intégrés :
| Ordre | Quand | Cas d’usage |
|---|---|---|
simple | Premier passage | Fournisseurs simples à clé API |
profile | Après simple | Fournisseurs filtrés par profils d’auth |
paired | Après profile | Synthétiser plusieurs entrées liées |
late | Dernier passage | Remplacer des fournisseurs existants (gagne en cas de collision) |
Étapes suivantes
- Plugins de canal — si votre plugin fournit aussi un canal
- SDK Runtime — helpers
api.runtime(TTS, recherche, sous-agent) - Vue d’ensemble du SDK — référence complète des imports par sous-chemin
- Internals des plugins — détails des hooks et exemples intégrés