Plugin-Interna
Dies ist die Referenz für die tiefgehende Architektur. Praktische Anleitungen finden Sie hier:
- Plugins installieren und verwenden — Benutzerleitfaden
- Erste Schritte — erstes Plugin-Tutorial
- Kanal-Plugins — einen Messaging-Kanal erstellen
- Provider-Plugins — einen Modellanbieter erstellen
- SDK-Überblick — Importzuordnung und Registrierungs-API
Öffentliches Fähigkeitsmodell
Fähigkeiten sind das öffentliche Modell für native Plugins innerhalb von OpenClaw. Jedes native OpenClaw-Plugin registriert sich für einen oder mehrere Fähigkeitstypen:| Fähigkeit | Registrierungsmethode | Beispiel-Plugins |
|---|---|---|
| Textinferenz | api.registerProvider(...) | openai, anthropic |
| CLI-Inferenz-Backend | api.registerCliBackend(...) | openai, anthropic |
| Sprache | api.registerSpeechProvider(...) | elevenlabs, microsoft |
| Echtzeit-Transkription | api.registerRealtimeTranscriptionProvider(...) | openai |
| Echtzeit-Sprache | api.registerRealtimeVoiceProvider(...) | openai |
| Medienverständnis | api.registerMediaUnderstandingProvider(...) | openai, google |
| Bildgenerierung | api.registerImageGenerationProvider(...) | openai, google, fal, minimax |
| Musikgenerierung | api.registerMusicGenerationProvider(...) | google, minimax |
| Videogenerierung | api.registerVideoGenerationProvider(...) | qwen |
| Web-Abruf | api.registerWebFetchProvider(...) | firecrawl |
| Websuche | api.registerWebSearchProvider(...) | google |
| Kanal / Messaging | api.registerChannel(...) | msteams, matrix |
Haltung zur externen Kompatibilität
Das Fähigkeitsmodell ist im Kernsystem eingeführt und wird heute von gebündelten/nativen Plugins verwendet, aber für die Kompatibilität externer Plugins braucht es weiterhin eine strengere Messlatte als „es ist exportiert, also ist es eingefroren“. Aktuelle Richtlinien:- bestehende externe Plugins: halten Sie hook-basierte Integrationen funktionsfähig; behandeln Sie dies als Kompatibilitäts-Basislinie
- neue gebündelte/native Plugins: bevorzugen Sie explizite Fähigkeitsregistrierung statt anbieterspezifischer Eingriffe oder neuer Hook-only-Designs
- externe Plugins, die Fähigkeitsregistrierung übernehmen: erlaubt, aber behandeln Sie fähigkeitsspezifische Helferoberflächen als weiterentwickelbar, sofern die Dokumentation einen Vertrag nicht ausdrücklich als stabil kennzeichnet
- APIs zur Fähigkeitsregistrierung sind die vorgesehene Richtung
- Legacy-Hooks bleiben während des Übergangs der sicherste Weg ohne Inkompatibilitäten für externe Plugins
- exportierte Helper-Subpaths sind nicht alle gleich; bevorzugen Sie den schmalen dokumentierten Vertrag, nicht beiläufig exportierte Helfer
Plugin-Formen
OpenClaw klassifiziert jedes geladene Plugin anhand seines tatsächlichen Registrierungsverhaltens in eine Form (nicht nur anhand statischer Metadaten):- plain-capability — registriert genau einen Fähigkeitstyp (zum Beispiel ein
reines Provider-Plugin wie
mistral) - hybrid-capability — registriert mehrere Fähigkeitstypen (zum Beispiel
openaibesitzt Textinferenz, Sprache, Medienverständnis und Bild- generierung) - hook-only — registriert nur Hooks (typisiert oder benutzerdefiniert), keine Fähigkeiten, Tools, Befehle oder Services
- non-capability — registriert Tools, Befehle, Services oder Routen, aber keine Fähigkeiten
openclaw plugins inspect <id>, um die Form und die Aufschlüsselung der
Fähigkeiten eines Plugins anzuzeigen. Details finden Sie in der CLI-Referenz.
Legacy-Hooks
Der Hookbefore_agent_start bleibt als Kompatibilitätspfad für
Hook-only-Plugins unterstützt. Bestehende Plugins aus der Praxis hängen weiterhin davon ab.
Ausrichtung:
- funktionsfähig halten
- als Legacy dokumentieren
before_model_resolvefür Arbeiten an Modell-/Provider-Überschreibungen bevorzugenbefore_prompt_buildfür Arbeiten an Prompt-Mutationen bevorzugen- erst entfernen, wenn die reale Nutzung sinkt und die Abdeckung durch Fixtures eine sichere Migration belegt
Kompatibilitätssignale
Wenn Sieopenclaw doctor oder openclaw plugins inspect <id> ausführen, sehen Sie möglicherweise
eines dieser Labels:
| Signal | Bedeutung |
|---|---|
| config valid | Konfiguration wird korrekt geparst und Plugins werden aufgelöst |
| compatibility advisory | Plugin verwendet ein unterstütztes, aber älteres Muster (z. B. hook-only) |
| legacy warning | Plugin verwendet before_agent_start, das veraltet ist |
| hard error | Konfiguration ist ungültig oder Plugin konnte nicht geladen werden |
hook-only noch before_agent_start machen Ihr Plugin heute kaputt —
hook-only ist ein Hinweis, und before_agent_start löst nur eine Warnung aus. Diese
Signale erscheinen auch in openclaw status --all und openclaw plugins doctor.
Architekturüberblick
Das Plugin-System von OpenClaw hat vier Ebenen:- Manifest + Discovery
OpenClaw findet potenzielle Plugins aus konfigurierten Pfaden, Workspace-Wurzeln,
globalen Extension-Wurzeln und gebündelten Extensions. Discovery liest zuerst native
openclaw.plugin.json-Manifeste sowie unterstützte Bundle-Manifeste. - Aktivierung + Validierung Der Kern entscheidet, ob ein entdecktes Plugin aktiviert, deaktiviert, blockiert oder für einen exklusiven Slot wie Speicher ausgewählt wird.
- Laufzeitladen Native OpenClaw-Plugins werden über jiti im Prozess geladen und registrieren Fähigkeiten in einer zentralen Registry. Kompatible Bundles werden in Registry-Einträge normalisiert, ohne Laufzeitcode zu importieren.
- Oberflächennutzung Der Rest von OpenClaw liest die Registry, um Tools, Kanäle, Provider- Einrichtung, Hooks, HTTP-Routen, CLI-Befehle und Services bereitzustellen.
- Parse-Zeit-Metadaten kommen aus
registerCli(..., { descriptors: [...] }) - das eigentliche Plugin-CLI-Modul kann lazy bleiben und sich erst beim ersten Aufruf registrieren
- Discovery + Konfigurationsvalidierung sollten anhand von Manifest-/Schema-Metadaten funktionieren, ohne Plugin-Code auszuführen
- natives Laufzeitverhalten kommt aus dem Pfad
register(api)des Plugin-Moduls
Kanal-Plugins und das gemeinsame message-Tool
Kanal-Plugins müssen für normale Chat-Aktionen kein separates Tool zum Senden/Bearbeiten/Reagieren registrieren.
OpenClaw behält ein gemeinsames message-Tool im Kern, und
Kanal-Plugins besitzen die kanalspezifische Discovery und Ausführung dahinter.
Die aktuelle Grenze ist:
- der Kern besitzt den gemeinsamen
message-Tool-Host, Prompt-Verdrahtung, Sitzungs-/Thread- Buchführung und Ausführungs-Dispatch - Kanal-Plugins besitzen Scoped-Action-Discovery, Fähigkeits-Discovery und beliebige kanalspezifische Schemafragmente
- Kanal-Plugins besitzen anbieterspezifische Sitzungs-/Unterhaltungsgrammatik, etwa wie Unterhaltungs-IDs Thread-IDs kodieren oder von Elternunterhaltungen erben
- Kanal-Plugins führen die endgültige Aktion über ihren Action-Adapter aus
ChannelMessageActionAdapter.describeMessageTool(...). Dieser einheitliche Discovery-
Aufruf erlaubt es einem Plugin, seine sichtbaren Aktionen, Fähigkeiten und Schema-
Beiträge zusammen zurückzugeben, damit diese Teile nicht auseinanderdriften.
Der Kern übergibt den Laufzeitkontext in diesen Discovery-Schritt. Wichtige Felder sind:
accountIdcurrentChannelIdcurrentThreadTscurrentMessageIdsessionKeysessionIdagentId- vertrauenswürdige eingehende
requesterSenderId
message-Tool fest zu verdrahten.
Deshalb sind Änderungen am Embedded-Runner-Routing weiterhin Plugin-Arbeit: Der Runner ist
dafür verantwortlich, die aktuelle Chat-/Sitzungsidentität in die Plugin-
Discovery-Grenze weiterzuleiten, damit das gemeinsame message-Tool die richtige, dem Kanal gehörende
Oberfläche für den aktuellen Turn bereitstellt.
Für kanaleigene Ausführungshelfer sollten gebündelte Plugins die Ausführungs-
Laufzeit innerhalb ihrer eigenen Extension-Module behalten. Der Kern besitzt nicht mehr die Laufzeiten
für Discord-, Slack-, Telegram- oder WhatsApp-Nachrichtenaktionen unter src/agents/tools.
Wir veröffentlichen keine separaten plugin-sdk/*-action-runtime-Subpaths, und gebündelte
Plugins sollten ihren eigenen lokalen Laufzeitcode direkt aus ihren
Extension-eigenen Modulen importieren.
Dieselbe Grenze gilt allgemein für providerbenannte SDK-Seams: Der Kern sollte
keine kanalspezifischen Convenience-Barrels für Slack, Discord, Signal,
WhatsApp oder ähnliche Extensions importieren. Wenn der Kern ein Verhalten benötigt, dann entweder
über das eigene Barrel api.ts / runtime-api.ts des gebündelten Plugins oder durch Anheben
dieses Bedarfs in eine schmale generische Fähigkeit im gemeinsamen SDK.
Speziell für Umfragen gibt es zwei Ausführungspfade:
outbound.sendPollist die gemeinsame Basis für Kanäle, die zum gemeinsamen Umfragemodell passenactions.handleAction("poll")ist der bevorzugte Pfad für kanalspezifische Umfragesemantik oder zusätzliche Umfrageparameter
Ownership-Modell für Fähigkeiten
OpenClaw behandelt ein natives Plugin als Ownership-Grenze für ein Unternehmen oder ein Feature, nicht als Sammelsurium unabhängiger Integrationen. Das bedeutet:- ein Unternehmens-Plugin sollte normalerweise alle OpenClaw-seitigen Oberflächen dieses Unternehmens besitzen
- ein Feature-Plugin sollte normalerweise die gesamte von ihm eingeführte Feature-Oberfläche besitzen
- Kanäle sollten gemeinsame Kernfähigkeiten konsumieren, statt Provider-Verhalten ad hoc neu zu implementieren
- das gebündelte Plugin
openaibesitzt das OpenAI-Modellprovider-Verhalten und OpenAI- Verhalten für Sprache + Echtzeit-Sprache + Medienverständnis + Bildgenerierung - das gebündelte Plugin
elevenlabsbesitzt das ElevenLabs-Sprachverhalten - das gebündelte Plugin
microsoftbesitzt das Microsoft-Sprachverhalten - das gebündelte Plugin
googlebesitzt das Google-Modellprovider-Verhalten sowie Google- Verhalten für Medienverständnis + Bildgenerierung + Websuche - das gebündelte Plugin
firecrawlbesitzt das Firecrawl-Web-Abruf-Verhalten - die gebündelten Plugins
minimax,mistral,moonshotundzaibesitzen ihre Backends für Medienverständnis - das Plugin
voice-callist ein Feature-Plugin: Es besitzt Anruftransport, Tools, CLI, Routen und Twilio-Medienstrom-Bridging, nutzt aber gemeinsame Sprach- sowie Echtzeit-Transkriptions- und Echtzeit-Sprach-Fähigkeiten, statt Anbieter-Plugins direkt zu importieren
- OpenAI lebt in einem Plugin, auch wenn es Textmodelle, Sprache, Bilder und künftig Video umfasst
- ein anderer Anbieter kann dasselbe für seinen eigenen Oberflächenbereich tun
- Kanäle ist es egal, welches Anbieter-Plugin den Provider besitzt; sie konsumieren den gemeinsamen Fähigkeitsvertrag, den der Kern bereitstellt
- Plugin = Ownership-Grenze
- Fähigkeit = Kernvertrag, den mehrere Plugins implementieren oder konsumieren können
- die fehlende Fähigkeit im Kern definieren
- sie typisiert über die Plugin-API/Laufzeit verfügbar machen
- Kanäle/Features gegen diese Fähigkeit verdrahten
- Anbieter-Plugins Implementierungen registrieren lassen
Schichtung von Fähigkeiten
Verwenden Sie dieses mentale Modell, um zu entscheiden, wohin Code gehört:- Kern-Fähigkeitsschicht: gemeinsame Orchestrierung, Richtlinien, Fallback, Konfigurations- Merge-Regeln, Bereitstellungssemantik und typisierte Verträge
- Anbieter-Plugin-Schicht: anbieterspezifische APIs, Authentifizierung, Modellkataloge, Sprach- synthese, Bildgenerierung, zukünftige Video-Backends, Nutzungsendpunkte
- Kanal-/Feature-Plugin-Schicht: Slack/Discord/voice-call/etc.-Integration, die Kernfähigkeiten konsumiert und auf einer Oberfläche präsentiert
- der Kern besitzt TTS-Richtlinien zur Antwortzeit, Fallback-Reihenfolge, Präferenzen und Kanalzustellung
openai,elevenlabsundmicrosoftbesitzen Syntheseimplementierungenvoice-callkonsumiert den Laufzeithelfer für Telefonie-TTS
Beispiel für ein Unternehmens-Plugin mit mehreren Fähigkeiten
Ein Unternehmens-Plugin sollte sich von außen kohärent anfühlen. Wenn OpenClaw gemeinsame Verträge für Modelle, Sprache, Echtzeit-Transkription, Echtzeit-Sprache, Medien- verständnis, Bildgenerierung, Videogenerierung, Web-Abruf und Websuche hat, kann ein Anbieter alle seine Oberflächen an einer Stelle besitzen:- ein Plugin besitzt die Anbieteroberfläche
- der Kern besitzt weiterhin die Fähigkeitsverträge
- Kanäle und Feature-Plugins konsumieren
api.runtime.*-Helfer, nicht Anbieter-Code - Vertragstests können prüfen, dass das Plugin die Fähigkeiten registriert hat, die es laut eigener Angabe besitzt
Fähigkeitsbeispiel: Videoverständnis
OpenClaw behandelt Bild-/Audio-/Videoverständnis bereits als eine gemeinsame Fähigkeit. Dasselbe Ownership-Modell gilt auch hier:- der Kern definiert den Vertrag für Medienverständnis
- Anbieter-Plugins registrieren je nach Bedarf
describeImage,transcribeAudiounddescribeVideo - Kanal- und Feature-Plugins konsumieren das gemeinsame Kernverhalten, statt direkt mit Anbieter-Code verdrahtet zu sein
api.registerVideoGenerationProvider(...)-Implementierungen dagegen.
Sie brauchen eine konkrete Checkliste für die Einführung? Siehe
Capability Cookbook.
Verträge und Durchsetzung
Die Oberfläche der Plugin-API ist absichtlich typisiert und inOpenClawPluginApi zentralisiert. Dieser Vertrag definiert die unterstützten Registrierungspunkte und
die Laufzeit-Helfer, auf die sich ein Plugin verlassen darf.
Warum das wichtig ist:
- Plugin-Autorinnen und -Autoren erhalten einen stabilen internen Standard
- der Kern kann doppelte Ownership ablehnen, etwa wenn zwei Plugins dieselbe Provider-ID registrieren
- beim Start können verwertbare Diagnosen für fehlerhafte Registrierungen ausgegeben werden
- Vertragstests können die Ownership gebündelter Plugins durchsetzen und stilles Driften verhindern
- Durchsetzung bei der Laufzeitregistrierung Die Plugin-Registry validiert Registrierungen während Plugins geladen werden. Beispiele: doppelte Provider-IDs, doppelte Speech-Provider-IDs und fehlerhafte Registrierungen erzeugen Plugin-Diagnosen statt undefiniertem Verhalten.
- Vertragstests Gebündelte Plugins werden in Vertrag-Registries während Testläufen erfasst, damit OpenClaw Ownership explizit prüfen kann. Heute wird dies für Modell- provider, Speech-Provider, Websuch-Provider und die Ownership gebündelter Registrierungen verwendet.
Was in einen Vertrag gehört
Gute Plugin-Verträge sind:- typisiert
- klein
- fähigkeitsspezifisch
- im Besitz des Kerns
- von mehreren Plugins wiederverwendbar
- von Kanälen/Features ohne Anbieterwissen konsumierbar
- im Kern versteckte anbieterspezifische Richtlinien
- einmalige Plugin-Escape-Hatches, die die Registry umgehen
- Kanal-Code, der direkt in eine Anbieterimplementierung greift
- ad hoc erzeugte Laufzeitobjekte, die nicht Teil von
OpenClawPluginApioderapi.runtimesind
Ausführungsmodell
Native OpenClaw-Plugins laufen im Prozess mit dem Gateway. Sie sind nicht sandboxed. Ein geladenes natives Plugin hat dieselbe Vertrauen-Grenze auf Prozessebene wie Kerncode. Auswirkungen:- ein natives Plugin kann Tools, Netzwerk-Handler, Hooks und Services registrieren
- ein Fehler in einem nativen Plugin kann das Gateway zum Absturz bringen oder destabilisieren
- ein bösartiges natives Plugin ist gleichbedeutend mit beliebiger Codeausführung innerhalb des OpenClaw-Prozesses
@openclaw/<id> oder ein genehmigtes typisiertes Suffix wie
-provider, -plugin, -speech, -sandbox oder -media-understanding, wenn
das Paket absichtlich eine engere Plugin-Rolle bereitstellt.
Wichtiger Vertrauenshinweis:
plugins.allowvertraut Plugin-IDs, nicht der Herkunft der Quelle.- Ein Workspace-Plugin mit derselben ID wie ein gebündeltes Plugin überschattet absichtlich die gebündelte Kopie, wenn dieses Workspace-Plugin aktiviert/allowlisted ist.
- Das ist normal und nützlich für lokale Entwicklung, Patch-Tests und Hotfixes.
Exportgrenze
OpenClaw exportiert Fähigkeiten, keine Implementierungs-Convenience. Halten Sie Fähigkeitsregistrierungen öffentlich. Reduzieren Sie nicht-vertragliche Helper-Exporte:- gebündelte plugin-spezifische Helper-Subpaths
- Laufzeit-Plumbing-Subpaths, die nicht als öffentliche API gedacht sind
- anbieterspezifische Convenience-Helper
- Setup-/Onboarding-Helfer, die Implementierungsdetails sind
plugin-sdk/feishu, plugin-sdk/feishu-setup, plugin-sdk/zalo,
plugin-sdk/zalo-setup und mehrere plugin-sdk/matrix*-Seams. Behandeln Sie diese als
reservierte Exporte für Implementierungsdetails, nicht als empfohlenes SDK-Muster für
neue Drittanbieter-Plugins.
Ladepipeline
Beim Start macht OpenClaw grob Folgendes:- potenzielle Plugin-Wurzeln entdecken
- native oder kompatible Bundle-Manifeste und Paketmetadaten lesen
- unsichere Kandidaten ablehnen
- Plugin-Konfiguration normalisieren (
plugins.enabled,allow,deny,entries,slots,load.paths) - Aktivierung für jeden Kandidaten entscheiden
- aktivierte native Module per jiti laden
- native Hooks
register(api)(oderactivate(api)— ein Legacy-Alias) aufrufen und Registrierungen in die Plugin-Registry einsammeln - die Registry für Befehle/Laufzeitoberflächen bereitstellen
activate ist ein Legacy-Alias für register — der Loader löst auf, was vorhanden ist (def.register ?? def.activate), und ruft es an derselben Stelle auf. Alle gebündelten Plugins verwenden register; bevorzugen Sie register für neue Plugins.Manifest-first-Verhalten
Das Manifest ist die Quelle der Wahrheit auf der Control-Plane. OpenClaw verwendet es, um:- das Plugin zu identifizieren
- deklarierte Kanäle/Skills/Konfigurationsschema oder Bundle-Fähigkeiten zu entdecken
plugins.entries.<id>.configzu validieren- Labels/Platzhalter in der Control UI zu ergänzen
- Installations-/Katalogmetadaten anzuzeigen
Was der Loader cached
OpenClaw hält kurze In-Process-Caches für:- Discovery-Ergebnisse
- Daten der Manifest-Registry
- geladene Plugin-Registries
- Setzen Sie
OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1oderOPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1, um diese Caches zu deaktivieren. - Passen Sie Cache-Fenster mit
OPENCLAW_PLUGIN_DISCOVERY_CACHE_MSundOPENCLAW_PLUGIN_MANIFEST_CACHE_MSan.
Registry-Modell
Geladene Plugins verändern nicht direkt beliebige globale Kernzustände. Sie registrieren sich in einer zentralen Plugin-Registry. Die Registry verfolgt:- Plugin-Einträge (Identität, Quelle, Herkunft, Status, Diagnosen)
- Tools
- Legacy-Hooks und typisierte Hooks
- Kanäle
- Provider
- Gateway-RPC-Handler
- HTTP-Routen
- CLI-Registrare
- Hintergrund-Services
- plugin-eigene Befehle
- Plugin-Modul -> Registry-Registrierung
- Kern-Laufzeit -> Registry-Konsum
Callbacks für Konversationsbindung
Plugins, die eine Konversation binden, können reagieren, wenn eine Genehmigung entschieden wurde. Verwenden Sieapi.onConversationBindingResolved(...), um einen Callback zu erhalten, nachdem eine Bindungs-
anfrage genehmigt oder abgelehnt wurde:
status:"approved"oder"denied"decision:"allow-once","allow-always"oder"deny"binding: die aufgelöste Bindung für genehmigte Anfragenrequest: die ursprüngliche Anforderungszusammenfassung, Detach-Hinweis, Sender-ID und Konversationsmetadaten
Provider-Laufzeit-Hooks
Provider-Plugins haben jetzt zwei Ebenen:- Manifest-Metadaten:
providerAuthEnvVarsfür günstige Provider- Env-Auth-Erkennung vor dem Laden der Laufzeit,providerAuthAliasesfür Provider-Varianten, die sich Auth teilen,channelEnvVarsfür günstige Kanal-Env-/Setup-Erkennung vor dem Laden der Laufzeit sowieproviderAuthChoicesfür günstige Labels bei Onboarding/Auth-Auswahl und CLI-Flag-Metadaten vor dem Laden der Laufzeit - Hooks zur Konfigurationszeit:
catalog/ Legacy-discoverysowieapplyConfigDefaults - Laufzeit-Hooks:
normalizeModelId,normalizeTransport,normalizeConfig,applyNativeStreamingUsageCompat,resolveConfigApiKey,resolveSyntheticAuth,resolveExternalAuthProfiles,shouldDeferSyntheticProfileAuth,resolveDynamicModel,prepareDynamicModel,normalizeResolvedModel,contributeResolvedModelCompat,capabilities,normalizeToolSchemas,inspectToolSchemas,resolveReasoningOutputMode,prepareExtraParams,createStreamFn,wrapStreamFn,resolveTransportTurnState,resolveWebSocketSessionPolicy,formatApiKey,refreshOAuth,buildAuthDoctorHint,matchesContextOverflowError,classifyFailoverReason,isCacheTtlEligible,buildMissingAuthMessage,suppressBuiltInModel,augmentModelCatalog,isBinaryThinking,supportsXHighThinking,resolveDefaultThinkingLevel,isModernModelRef,prepareRuntimeAuth,resolveUsageAuth,fetchUsageSnapshot,createEmbeddingProvider,buildReplayPolicy,sanitizeReplayHistory,validateReplayTurns,onModelSelected
providerAuthEnvVars, wenn der Provider env-basierte
Anmeldedaten hat, die generische Auth-/Status-/Modell-Picker-Pfade sehen sollen, ohne die Plugin-Laufzeit
zu laden. Verwenden Sie Manifest-providerAuthAliases, wenn eine Provider-ID die Env-Variablen,
Auth-Profile, konfigurationsgestützte Auth und die API-Key-Onboarding-Wahl einer anderen Provider-ID
wiederverwenden soll. Verwenden Sie Manifest-providerAuthChoices, wenn CLI-Oberflächen
für Onboarding/Auth-Auswahl die Choice-ID des Providers, Gruppenlabels und einfache
Auth-Verdrahtung per Einzelflag kennen sollen, ohne die Provider-Laufzeit zu laden. Behalten Sie in der Provider-Laufzeit
envVars für operatorseitige Hinweise wie Onboarding-Labels oder
Setup-Variablen für OAuth-Client-ID/Client-Secret.
Verwenden Sie Manifest-channelEnvVars, wenn ein Kanal env-gesteuerte Auth oder Einrichtung hat,
die generischer Shell-Env-Fallback, Konfigurations-/Statusprüfungen oder Setup-Prompts sehen sollen,
ohne die Kanal-Laufzeit zu laden.
Hook-Reihenfolge und Verwendung
Für Modell-/Provider-Plugins ruft OpenClaw Hooks ungefähr in dieser Reihenfolge auf. Die Spalte „Wann verwenden“ ist die schnelle Entscheidungshilfe.| # | Hook | Was er macht | Wann verwenden |
|---|---|---|---|
| 1 | catalog | Provider-Konfiguration bei der Generierung von models.json in models.providers veröffentlichen | Der Provider besitzt einen Katalog oder Standardwerte für baseUrl |
| 2 | applyConfigDefaults | plugin-eigene globale Konfigurationsstandards während der Konfigurationsmaterialisierung anwenden | Standardwerte hängen von Auth-Modus, Env oder der Semantik der Provider-Modellfamilie ab |
| — | (integrierte Modellsuche) | OpenClaw versucht zuerst den normalen Registry-/Katalog-Pfad | (kein Plugin-Hook) |
| 3 | normalizeModelId | Legacy- oder Preview-Aliase für Modell-IDs vor der Suche normalisieren | Der Provider besitzt Alias-Bereinigung vor der kanonischen Modellauflösung |
| 4 | normalizeTransport | Provider-Familien-api / baseUrl vor generischer Modellzusammenstellung normalisieren | Der Provider besitzt Transport-Bereinigung für benutzerdefinierte Provider-IDs in derselben Transportfamilie |
| 5 | normalizeConfig | models.providers.<id> vor Laufzeit-/Provider-Auflösung normalisieren | Der Provider benötigt Konfigurationsbereinigung, die beim Plugin leben sollte; gebündelte Google-Familien-Helper fangen auch unterstützte Google-Konfigurationseinträge ab |
| 6 | applyNativeStreamingUsageCompat | Native Streaming-Usage-Kompatibilitäts-Umschreibungen auf Konfigurationsprovider anwenden | Der Provider benötigt endpunktgesteuerte Korrekturen für native Streaming-Usage-Metadaten |
| 7 | resolveConfigApiKey | Env-Marker-Auth für Konfigurationsprovider vor dem Laden der Laufzeit-Auth auflösen | Der Provider besitzt eine plugin-eigene Auflösung von Env-Marker-API-Keys; amazon-bedrock hat hier ebenfalls einen eingebauten AWS-Env-Marker-Resolver |
| 8 | resolveSyntheticAuth | lokale/self-hosted oder konfigurationsgestützte Auth anzeigen, ohne Klartext zu persistieren | Der Provider kann mit einem synthetischen/lokalen Credential-Marker arbeiten |
| 9 | resolveExternalAuthProfiles | plugin-eigene externe Auth-Profile überlagern; Standard-persistence ist runtime-only für CLI-/app-eigene Credentials | Der Provider verwendet externe Auth-Credentials wieder, ohne kopierte Refresh-Tokens zu persistieren |
| 10 | shouldDeferSyntheticProfileAuth | gespeicherte synthetische Profil-Platzhalter hinter env-/konfigurationsgestützter Auth zurückstufen | Der Provider speichert synthetische Platzhalterprofile, die keine Priorität haben sollten |
| 11 | resolveDynamicModel | synchroner Fallback für plugin-eigene Modell-IDs, die noch nicht in der lokalen Registry sind | Der Provider akzeptiert beliebige Upstream-Modell-IDs |
| 12 | prepareDynamicModel | asynchrones Warm-up, dann läuft resolveDynamicModel erneut | Der Provider benötigt Netzwerkmetadaten, bevor unbekannte IDs aufgelöst werden können |
| 13 | normalizeResolvedModel | endgültige Umschreibung, bevor der Embedded-Runner das aufgelöste Modell verwendet | Der Provider benötigt Transport-Umschreibungen, verwendet aber weiterhin einen Kerntransport |
| 14 | contributeResolvedModelCompat | Kompatibilitätsflags für Anbietermodelle hinter einem anderen kompatiblen Transport beisteuern | Der Provider erkennt seine eigenen Modelle auf Proxy-Transporten, ohne den Provider zu übernehmen |
| 15 | capabilities | plugin-eigene Transkript-/Tooling-Metadaten, die von gemeinsamer Kernlogik verwendet werden | Der Provider benötigt Besonderheiten für Transkripte/Provider-Familien |
| 16 | normalizeToolSchemas | Tool-Schemas normalisieren, bevor der Embedded-Runner sie sieht | Der Provider benötigt schemaseitige Bereinigung für eine Transportfamilie |
| 17 | inspectToolSchemas | plugin-eigene Schema-Diagnosen nach der Normalisierung ausgeben | Der Provider möchte Keyword-Warnungen ausgeben, ohne dem Kern anbieterspezifische Regeln beizubringen |
| 18 | resolveReasoningOutputMode | nativen versus getaggten Vertrag für Reasoning-Ausgaben auswählen | Der Provider benötigt getaggtes Reasoning/finale Ausgabe statt nativer Felder |
| 19 | prepareExtraParams | Normalisierung von Anfrageparametern vor generischen Stream-Option-Wrappern | Der Provider benötigt Standard-Anfrageparameter oder anbieterspezifische Parameterbereinigung |
| 20 | createStreamFn | normalen Stream-Pfad vollständig durch einen benutzerdefinierten Transport ersetzen | Der Provider benötigt ein benutzerdefiniertes Wire-Protokoll, nicht nur einen Wrapper |
| 21 | wrapStreamFn | Stream-Wrapper, nachdem generische Wrapper angewendet wurden | Der Provider benötigt Wrapper für Anfrageheader/Body/Modell-Kompatibilität ohne benutzerdefinierten Transport |
| 22 | resolveTransportTurnState | native turnbezogene Transport-Header oder -Metadaten anhängen | Der Provider möchte, dass generische Transporte die providereigene Turn-Identität senden |
| 23 | resolveWebSocketSessionPolicy | native WebSocket-Header oder Richtlinien zur Session-Abkühlung anhängen | Der Provider möchte, dass generische WS-Transporte Session-Header oder Fallback-Richtlinien abstimmen |
| 24 | formatApiKey | Auth-Profil-Formatierer: gespeichertes Profil wird zur Laufzeit-Zeichenfolge apiKey | Der Provider speichert zusätzliche Auth-Metadaten und benötigt eine benutzerdefinierte Laufzeit-Tokenform |
| 25 | refreshOAuth | OAuth-Refresh-Override für benutzerdefinierte Refresh-Endpunkte oder Richtlinien bei Refresh-Fehlschlägen | Der Provider passt nicht zu den gemeinsamen pi-ai-Refreshern |
| 26 | buildAuthDoctorHint | Reparaturhinweis, der angehängt wird, wenn OAuth-Refresh fehlschlägt | Der Provider benötigt plugin-eigene Hinweise zur Auth-Reparatur nach einem Refresh-Fehler |
| 27 | matchesContextOverflowError | plugin-eigener Matcher für Überläufe des Kontextfensters | Der Provider hat rohe Overflow-Fehler, die generische Heuristiken übersehen würden |
| 28 | classifyFailoverReason | plugin-eigene Klassifizierung des Failover-Grunds | Der Provider kann rohe API-/Transportfehler auf Ratenbegrenzung/Überlast/etc. abbilden |
| 29 | isCacheTtlEligible | Richtlinie für Prompt-Cache bei Proxy-/Backhaul-Providern | Der Provider benötigt proxy-spezifisches Cache-TTL-Gating |
| 30 | buildMissingAuthMessage | Ersatz für die generische Wiederherstellungsnachricht bei fehlender Auth | Der Provider benötigt einen provider-spezifischen Hinweis zur Wiederherstellung fehlender Auth |
| 31 | suppressBuiltInModel | Unterdrückung veralteter Upstream-Modelle plus optionaler benutzerseitiger Fehlerhinweis | Der Provider muss veraltete Upstream-Zeilen ausblenden oder durch einen Anbieterhinweis ersetzen |
| 32 | augmentModelCatalog | synthetische/endgültige Katalogzeilen, die nach Discovery angehängt werden | Der Provider benötigt synthetische Vorwärtskompatibilitäts-Zeilen in models list und Pickern |
| 33 | isBinaryThinking | Ein/Aus-Reasoning-Umschaltung für Anbieter mit binärem Thinking | Der Provider bietet nur binäres Thinking an/aus an |
| 34 | supportsXHighThinking | xhigh-Reasoning-Unterstützung für ausgewählte Modelle | Der Provider möchte xhigh nur für eine Teilmenge von Modellen |
| 35 | resolveDefaultThinkingLevel | Standard-/think-Level für eine bestimmte Modellfamilie | Der Provider besitzt die Standard-/think-Richtlinie für eine Modellfamilie |
| 36 | isModernModelRef | Matcher für moderne Modelle für Live-Profil-Filter und Smoke-Auswahl | Der Provider besitzt das Matching bevorzugter Modelle für Live/Smoke |
| 37 | prepareRuntimeAuth | konfiguriertes Credential direkt vor der Inferenz in das tatsächliche Laufzeit-Token/den Schlüssel umtauschen | Der Provider benötigt einen Tokenaustausch oder kurzlebige Anfrage-Credentials |
| 38 | resolveUsageAuth | Credentials für Nutzung/Abrechnung für /usage und verwandte Statusoberflächen auflösen | Der Provider benötigt benutzerdefinierte Tokenanalyse für Nutzung/Quota oder andere Usage-Credentials |
| 39 | fetchUsageSnapshot | provider-spezifische Nutzung-/Quota-Snapshots abrufen und normalisieren, nachdem Auth aufgelöst wurde | Der Provider benötigt einen provider-spezifischen Usage-Endpunkt oder Payload-Parser |
| 40 | createEmbeddingProvider | plugin-eigenen Embedding-Adapter für Speicher/Suche bauen | Verhalten für Memory-Embeddings gehört zum Provider-Plugin |
| 41 | buildReplayPolicy | eine Replay-Richtlinie zurückgeben, die den Umgang des Providers mit Transkripten steuert | Der Provider benötigt eine benutzerdefinierte Transkript-Richtlinie (zum Beispiel Entfernen von Thinking-Blöcken) |
| 42 | sanitizeReplayHistory | Replay-Verlauf nach generischer Transkript-Bereinigung umschreiben | Der Provider benötigt provider-spezifische Replay-Umschreibungen über gemeinsame Kompaktion-Helper hinaus |
| 43 | validateReplayTurns | endgültige Validierung oder Umformung von Replay-Turns vor dem Embedded-Runner | Der Provider-Transport benötigt strengere Turn-Validierung nach generischer Bereinigung |
| 44 | onModelSelected | plugin-eigene Nebeneffekte nach Auswahl des Modells ausführen | Der Provider benötigt Telemetrie oder provider-eigenen Zustand, wenn ein Modell aktiv wird |
normalizeModelId, normalizeTransport und normalizeConfig prüfen zuerst das
zugeordnete Provider-Plugin und greifen dann auf andere hook-fähige Provider-Plugins zurück,
bis eines tatsächlich die Modell-ID oder den Transport/die Konfiguration ändert. Das hält
Alias-/Kompatibilitäts-Provider-Shims funktionsfähig, ohne vom Aufrufer zu verlangen zu wissen,
welches gebündelte Plugin die Umschreibung besitzt. Wenn kein Provider-Hook einen unterstützten
Google-Familien-Konfigurationseintrag umschreibt, greift weiterhin der gebündelte Google-Konfigurations-
Normalizer für diese Kompatibilitätsbereinigung.
Wenn der Provider ein vollständig benutzerdefiniertes Wire-Protokoll oder einen benutzerdefinierten Request-
Executor benötigt, ist das eine andere Klasse von Erweiterung. Diese Hooks sind für Provider-Verhalten gedacht,
das weiterhin auf der normalen Inferenzschleife von OpenClaw läuft.
Provider-Beispiel
Integrierte Beispiele
- Anthropic verwendet
resolveDynamicModel,capabilities,buildAuthDoctorHint,resolveUsageAuth,fetchUsageSnapshot,isCacheTtlEligible,resolveDefaultThinkingLevel,applyConfigDefaults,isModernModelRefundwrapStreamFn, weil es Vorwärtskompatibilität für Claude 4.6, Hinweise zur Provider-Familie, Anleitungen zur Auth-Reparatur, Integration von Nutzungsendpunkten, Prompt-Cache-Eignung, auth-bewusste Konfigurationsstandards, die Standard-/adaptive Thinking-Richtlinie für Claude sowie Anthropic-spezifisches Stream-Shaping für Beta-Header,/fast/serviceTierundcontext1mbesitzt. - Die Claude-spezifischen Stream-Helper von Anthropic verbleiben vorerst in der eigenen
öffentlichen Naht
api.ts/contract-api.tsdes gebündelten Plugins. Diese Paketoberfläche exportiertwrapAnthropicProviderStream,resolveAnthropicBetas,resolveAnthropicFastMode,resolveAnthropicServiceTiersowie die Low-Level- Anthropic-Wrapper-Builder, statt das generische SDK um die Beta-Header-Regeln eines einzelnen Providers zu erweitern. - OpenAI verwendet
resolveDynamicModel,normalizeResolvedModelundcapabilitiessowiebuildMissingAuthMessage,suppressBuiltInModel,augmentModelCatalog,supportsXHighThinkingundisModernModelRef, weil es Vorwärtskompatibilität für GPT-5.4, die direkte OpenAI- Normalisierungopenai-completions->openai-responses, Codex-bewusste Auth- Hinweise, Spark-Unterdrückung, synthetische OpenAI-Listenzeilen und GPT-5-Thinking-/ Live-Modell-Richtlinien besitzt; die Stream-Familieopenai-responses-defaultsbesitzt die gemeinsamen nativen OpenAI-Responses-Wrapper für Zuordnungsheader,/fast/serviceTier, Textausführlichkeit, native Codex-Websuche, Reasoning-kompatibles Payload-Shaping und Responses-Kontextverwaltung. - OpenRouter verwendet
catalogsowieresolveDynamicModelundprepareDynamicModel, weil der Provider ein Pass-through ist und neue Modell-IDs verfügbar machen kann, bevor der statische Katalog von OpenClaw aktualisiert wird; außerdem nutzt escapabilities,wrapStreamFnundisCacheTtlEligible, um provider-spezifische Request-Header, Routing-Metadaten, Reasoning-Patches und Prompt-Cache-Richtlinien aus dem Kern herauszuhalten. Seine Replay-Richtlinie stammt aus der Familiepassthrough-gemini, während die Stream-Familieopenrouter-thinkingProxy-Reasoning-Injection und das Überspringen nicht unterstützter Modelle bzw. vonautobesitzt. - GitHub Copilot verwendet
catalog,auth,resolveDynamicModelundcapabilitiessowieprepareRuntimeAuthundfetchUsageSnapshot, weil es provider-eigenes Device-Login, Modell-Fallback-Verhalten, Besonderheiten bei Claude-Transkripten, einen GitHub-Token -> Copilot-Token-Austausch und einen provider-eigenen Nutzungsendpunkt benötigt. - OpenAI Codex verwendet
catalog,resolveDynamicModel,normalizeResolvedModel,refreshOAuthundaugmentModelCatalogsowieprepareExtraParams,resolveUsageAuthundfetchUsageSnapshot, weil es weiterhin auf Kern-OpenAI-Transporten läuft, aber seine Transport-/baseUrl- Normalisierung, Richtlinien zum OAuth-Refresh-Fallback, die Standardwahl des Transports, synthetische Codex-Katalogzeilen und die Integration des ChatGPT-Nutzungsendpunkts besitzt; es teilt sich dieselbe Stream-Familieopenai-responses-defaultswie direktes OpenAI. - Google AI Studio und Gemini CLI OAuth verwenden
resolveDynamicModel,buildReplayPolicy,sanitizeReplayHistory,resolveReasoningOutputMode,wrapStreamFnundisModernModelRef, weil die Replay-Familiegoogle-geminiden Vorwärtskompatibilitäts-Fallback für Gemini 3.1, native Gemini-Replay-Validierung, Bootstrap-Replay-Säuberung, den getaggten Reasoning-Ausgabemodus und das Matching moderner Modelle besitzt, während die Stream-Familiegoogle-thinkingdie Normalisierung von Gemini-Thinking-Payloads besitzt; Gemini CLI OAuth verwendet außerdemformatApiKey,resolveUsageAuthundfetchUsageSnapshotfür Token-Formatierung, Token-Parsing und Verdrahtung des Quota-Endpunkts. - Anthropic Vertex verwendet
buildReplayPolicyüber die Replay-Familieanthropic-by-model, damit Claude-spezifische Replay-Bereinigung auf Claude-IDs beschränkt bleibt statt auf jeden Transportanthropic-messages. - Amazon Bedrock verwendet
buildReplayPolicy,matchesContextOverflowError,classifyFailoverReasonundresolveDefaultThinkingLevel, weil es Bedrock-spezifische Klassifizierung von Throttle-/Not-ready-/Context-Overflow-Fehlern für Anthropic-auf-Bedrock-Datenverkehr besitzt; seine Replay-Richtlinie teilt sich weiterhin denselben nur-für-Claude-Schutzanthropic-by-model. - OpenRouter, Kilocode, Opencode und Opencode Go verwenden
buildReplayPolicyüber die Replay-Familiepassthrough-gemini, weil sie Gemini- Modelle über OpenAI-kompatible Transporte proxien und eine Bereinigung von Gemini- Thought-Signatures ohne native Gemini-Replay-Validierung oder Bootstrap-Umschreibungen benötigen. - MiniMax verwendet
buildReplayPolicyüber die Replay-Familiehybrid-anthropic-openai, weil ein Provider sowohl Semantik für Anthropic-Nachrichten als auch OpenAI-Kompatibilität besitzt; Claude-spezifisches Entfernen von Thinking-Blöcken bleibt auf der Anthropic-Seite, während der Reasoning-Ausgabemodus zurück auf nativ gesetzt wird, und die Stream-Familieminimax-fast-modebesitzt Umschreibungen für den Fast-Modus auf dem gemeinsamen Stream-Pfad. - Moonshot verwendet
catalogsowiewrapStreamFn, weil es weiterhin den gemeinsamen OpenAI-Transport nutzt, aber provider-eigene Normalisierung von Thinking-Payloads benötigt; die Stream-Familiemoonshot-thinkingordnet Konfiguration plus/think-Zustand seiner nativen binären Thinking-Payload zu. - Kilocode verwendet
catalog,capabilities,wrapStreamFnundisCacheTtlEligible, weil es provider-eigene Request-Header, Normalisierung von Reasoning-Payloads, Hinweise für Gemini-Transkripte und Anthropic- Cache-TTL-Gating benötigt; die Stream-Familiekilocode-thinkinghält die Kilo- Thinking-Injektion auf dem gemeinsamen Proxy-Stream-Pfad, währendkilo/autound andere Proxy-Modell-IDs, die keine expliziten Reasoning-Payloads unterstützen, ausgelassen werden. - Z.AI verwendet
resolveDynamicModel,prepareExtraParams,wrapStreamFn,isCacheTtlEligible,isBinaryThinking,isModernModelRef,resolveUsageAuthundfetchUsageSnapshot, weil es GLM-5-Fallback, Standardwerte fürtool_stream, binäre Thinking-UX, Matching moderner Modelle sowie sowohl Usage-Auth als auch Quota-Abruf besitzt; die Stream-Familietool-stream-default-onhält den standardmäßig aktiviertentool_stream-Wrapper aus handgeschriebenem Glue-Code pro Provider heraus. - xAI verwendet
normalizeResolvedModel,normalizeTransport,contributeResolvedModelCompat,prepareExtraParams,wrapStreamFn,resolveSyntheticAuth,resolveDynamicModelundisModernModelRef, weil es die Normalisierung des nativen xAI-Responses-Transports, Umschreibungen von Grok- Fast-Mode-Aliassen, Standardwerte fürtool_stream, Bereinigung für strikte Tools / Reasoning-Payloads, Wiederverwendung von Fallback-Auth für plugin-eigene Tools, Vorwärtskompatibilitäts- Auflösung von Grok-Modellen und provider-eigene Kompatibilitätspatches wie xAI-Tool-Schema- Profil, nicht unterstützte Schema-Keywords, nativesweb_searchund HTML-Entity- Dekodierung für Tool-Call-Argumente besitzt. - Mistral, OpenCode Zen und OpenCode Go verwenden nur
capabilities, um Besonderheiten bei Transkripten/Tooling aus dem Kern herauszuhalten. - Nur-Katalog-gebündelte Provider wie
byteplus,cloudflare-ai-gateway,huggingface,kimi-coding,nvidia,qianfan,synthetic,together,venice,vercel-ai-gatewayundvolcengineverwenden nurcatalog. - Qwen verwendet
catalogfür seinen Textprovider sowie gemeinsame Registrierungen für Medienverständnis und Videogenerierung für seine multimodalen Oberflächen. - MiniMax und Xiaomi verwenden
catalogsowie Usage-Hooks, weil ihr/usage- Verhalten plugin-eigen ist, obwohl die Inferenz weiterhin über die gemeinsamen Transporte läuft.
Laufzeit-Helfer
Plugins können überapi.runtime auf ausgewählte Kern-Helper zugreifen. Für TTS:
textToSpeechgibt die normale Kern-TTS-Ausgabe-Nutzlast für Datei-/Voice-Note-Oberflächen zurück.- Verwendet die Kernkonfiguration
messages.ttsund Provider-Auswahl. - Gibt PCM-Audiopuffer + Samplerate zurück. Plugins müssen für Provider neu sampeln/kodieren.
listVoicesist pro Provider optional. Verwenden Sie es für anbietereigene Sprach-Auswahllisten oder Setup-Flows.- Sprachlisten können reichere Metadaten wie Gebietsschema, Geschlecht und Persönlichkeits-Tags für providerbewusste Picker enthalten.
- OpenAI und ElevenLabs unterstützen heute Telefonie. Microsoft nicht.
api.registerSpeechProvider(...) registrieren.
- Behalten Sie TTS-Richtlinien, Fallback und Antwortzustellung im Kern.
- Verwenden Sie Speech-Provider für anbietereigene Syntheseimplementierungen.
- Legacy-Microsoft-
edge-Eingabe wird auf die Provider-IDmicrosoftnormalisiert. - Das bevorzugte Ownership-Modell ist unternehmensorientiert: Ein Anbieter-Plugin kann Text-, Sprach-, Bild- und künftige Medien-Provider besitzen, wenn OpenClaw diese Fähigkeitsverträge hinzufügt.
- Behalten Sie Orchestrierung, Fallback, Konfiguration und Kanalverdrahtung im Kern.
- Behalten Sie Anbieterverhalten im Provider-Plugin.
- Additive Erweiterungen sollten typisiert bleiben: neue optionale Methoden, neue optionale Ergebnisfelder, neue optionale Fähigkeiten.
- Die Videogenerierung folgt bereits demselben Muster:
- der Kern besitzt den Fähigkeitsvertrag und den Laufzeithelfer
- Anbieter-Plugins registrieren
api.registerVideoGenerationProvider(...) - Feature-/Kanal-Plugins konsumieren
api.runtime.videoGeneration.*
api.runtime.mediaUnderstanding.*ist die bevorzugte gemeinsame Oberfläche für Bild-/Audio-/Videoverständnis.- Verwendet die Audio-Konfiguration des Kern-Medienverständnisses (
tools.media.audio) und die Provider-Fallback-Reihenfolge. - Gibt
{ text: undefined }zurück, wenn keine Transkriptionsausgabe erzeugt wird (zum Beispiel bei übersprungenen/nicht unterstützten Eingaben). api.runtime.stt.transcribeAudioFile(...)bleibt als Kompatibilitäts-Alias bestehen.
api.runtime.subagent starten:
providerundmodelsind optionale Überschreibungen pro Lauf, keine persistenten Sitzungsänderungen.- OpenClaw berücksichtigt diese Override-Felder nur für vertrauenswürdige Aufrufer.
- Für plugin-eigene Fallback-Läufe müssen Operatoren mit
plugins.entries.<id>.subagent.allowModelOverride: truezustimmen. - Verwenden Sie
plugins.entries.<id>.subagent.allowedModels, um vertrauenswürdige Plugins auf bestimmte kanonische Zieleprovider/modelzu beschränken, oder"*", um explizit jedes Ziel zu erlauben. - Läufe von Subagents durch nicht vertrauenswürdige Plugins funktionieren weiterhin, aber Override-Anfragen werden abgelehnt, statt stillschweigend zurückzufallen.
api.registerWebSearchProvider(...) registrieren.
Hinweise:
- Behalten Sie Provider-Auswahl, Auflösung von Credentials und gemeinsame Request-Semantik im Kern.
- Verwenden Sie Websuch-Provider für anbieterspezifische Suchtransporte.
api.runtime.webSearch.*ist die bevorzugte gemeinsame Oberfläche für Feature-/Kanal-Plugins, die Suchverhalten benötigen, ohne von dem Agent-Tool-Wrapper abhängig zu sein.
api.runtime.imageGeneration
generate(...): ein Bild mit der konfigurierten Kette von Bildgenerierungs-Providern erzeugen.listProviders(...): verfügbare Bildgenerierungs-Provider und ihre Fähigkeiten auflisten.
Gateway-HTTP-Routen
Plugins können HTTP-Endpunkte mitapi.registerHttpRoute(...) bereitstellen.
path: Routenpfad unter dem Gateway-HTTP-Server.auth: erforderlich. Verwenden Sie"gateway", um normale Gateway-Auth zu verlangen, oder"plugin"für pluginverwaltete Auth/Webhook-Verifikation.match: optional."exact"(Standard) oder"prefix".replaceExisting: optional. Erlaubt demselben Plugin, seine eigene bestehende Routenregistrierung zu ersetzen.handler: gibttruezurück, wenn die Route die Anfrage verarbeitet hat.
api.registerHttpHandler(...)wurde entfernt und führt zu einem Fehler beim Laden des Plugins. Verwenden Sie stattdessenapi.registerHttpRoute(...).- Plugin-Routen müssen
authexplizit deklarieren. - Exakte Konflikte von
path + matchwerden abgelehnt, außerreplaceExisting: trueist gesetzt, und ein Plugin kann keine Route eines anderen Plugins ersetzen. - Überlappende Routen mit unterschiedlichen
auth-Leveln werden abgelehnt. Halten Sieexact-/prefix-Fallthrough-Ketten nur auf derselben Auth-Stufe. - Routen mit
auth: "plugin"erhalten nicht automatisch Runtime-Scopes des Operators. Sie sind für pluginverwaltete Webhooks/Signaturprüfung gedacht, nicht für privilegierte Gateway-Helper-Aufrufe. - Routen mit
auth: "gateway"laufen innerhalb eines Gateway-Request-Runtime-Scopes, aber dieser Scope ist bewusst konservativ:- Bearer-Auth mit Shared Secret (
gateway.auth.mode = "token"/"password") hält die Runtime-Scopes von Plugin-Routen aufoperator.writefest, selbst wenn der Aufruferx-openclaw-scopessendet - vertrauenswürdige HTTP-Modi mit identitätstragenden Daten (zum Beispiel
trusted-proxyodergateway.auth.mode = "none"an einem privaten Ingress) beachtenx-openclaw-scopesnur, wenn der Header ausdrücklich vorhanden ist - wenn
x-openclaw-scopesbei solchen identitätstragenden Plugin-Routenanfragen fehlt, fällt der Runtime-Scope aufoperator.writezurück
- Bearer-Auth mit Shared Secret (
- Praktische Regel: Gehen Sie nicht davon aus, dass eine Gateway-authentifizierte Plugin-Route implizit eine Admin-Oberfläche ist. Wenn Ihre Route rein administratives Verhalten braucht, verlangen Sie einen identitätstragenden Auth-Modus und dokumentieren Sie den expliziten Vertragsumfang des Headers
x-openclaw-scopes.
Importpfade des Plugin SDK
Verwenden Sie SDK-Subpaths statt des monolithischen Importsopenclaw/plugin-sdk,
wenn Sie Plugins erstellen:
openclaw/plugin-sdk/plugin-entryfür Plugin-Registrierungsprimitive.openclaw/plugin-sdk/corefür den generischen gemeinsamen pluginseitigen Vertrag.openclaw/plugin-sdk/config-schemafür den Export des Zod-Schemas der Wurzelopenclaw.json(OpenClawSchema).- Stabile Kanal-Primitive wie
openclaw/plugin-sdk/channel-setup,openclaw/plugin-sdk/setup-runtime,openclaw/plugin-sdk/setup-adapter-runtime,openclaw/plugin-sdk/setup-tools,openclaw/plugin-sdk/channel-pairing,openclaw/plugin-sdk/channel-contract,openclaw/plugin-sdk/channel-feedback,openclaw/plugin-sdk/channel-inbound,openclaw/plugin-sdk/channel-lifecycle,openclaw/plugin-sdk/channel-reply-pipeline,openclaw/plugin-sdk/command-auth,openclaw/plugin-sdk/secret-inputundopenclaw/plugin-sdk/webhook-ingressfür gemeinsame Setup-/Auth-/Antwort-/Webhook- Verdrahtung.channel-inboundist die gemeinsame Heimat für Debounce, Mention-Matching, Helper für Inbound-Mention-Richtlinien, Envelope-Formatierung und Kontext-Helper für Inbound-Envelopes.channel-setupist die schmale optionale Setup-Naht.setup-runtimeist die laufzeitsichere Setup-Oberfläche, die vonsetupEntry/ verzögertem Start verwendet wird, einschließlich der importsicheren Setup-Patch-Adapter.setup-adapter-runtimeist die env-bewusste Naht für Account-Setup-Adapter.setup-toolsist die kleine Naht für CLI-/Archiv-/Dokumentations-Helfer (formatCliCommand,detectBinary,extractArchive,resolveBrewExecutable,formatDocsLink,CONFIG_DIR). - Domänen-Subpaths wie
openclaw/plugin-sdk/channel-config-helpers,openclaw/plugin-sdk/allow-from,openclaw/plugin-sdk/channel-config-schema,openclaw/plugin-sdk/telegram-command-config,openclaw/plugin-sdk/channel-policy,openclaw/plugin-sdk/approval-gateway-runtime,openclaw/plugin-sdk/approval-handler-adapter-runtime,openclaw/plugin-sdk/approval-handler-runtime,openclaw/plugin-sdk/approval-runtime,openclaw/plugin-sdk/config-runtime,openclaw/plugin-sdk/infra-runtime,openclaw/plugin-sdk/agent-runtime,openclaw/plugin-sdk/lazy-runtime,openclaw/plugin-sdk/reply-history,openclaw/plugin-sdk/routing,openclaw/plugin-sdk/status-helpers,openclaw/plugin-sdk/text-runtime,openclaw/plugin-sdk/runtime-storeundopenclaw/plugin-sdk/directory-runtimefür gemeinsame Laufzeit-/Konfigurations-Helfer.telegram-command-configist die schmale öffentliche Naht für Normalisierung/Validierung von benutzerdefinierten Telegram- Befehlen und bleibt verfügbar, selbst wenn die Vertragsoberfläche des gebündelten Telegram vorübergehend nicht verfügbar ist.text-runtimeist die gemeinsame Naht für Text/Markdown/Logging, einschließlich Entfernen von für Assistenten sichtbarem Text, Helpern für Markdown-Rendering/Chunking, Redaktions- Helpern, Helpern für Richtlinien-Tags und Safe-Text-Utilities. - Kanalspezifische Approval-Seams sollten bevorzugt einen einzigen
approvalCapability- Vertrag auf dem Plugin verwenden. Der Kern liest dann Auth, Bereitstellung, Rendering, natives Routing und lazy natives Handler-Verhalten für Approvals über diese eine Fähigkeit, statt Approval-Verhalten in unabhängige Plugin-Felder zu mischen. openclaw/plugin-sdk/channel-runtimeist veraltet und verbleibt nur als Kompatibilitäts-Shim für ältere Plugins. Neuer Code sollte stattdessen die schmaleren generischen Primitive importieren, und Repo-Code sollte keine neuen Importe dieses Shims hinzufügen.- Interne Elemente gebündelter Extensions bleiben privat. Externe Plugins sollten nur
openclaw/plugin-sdk/*-Subpaths verwenden. OpenClaw-Kern-/Test-Code kann die öffentlichen Repo-Einstiegspunkte unter einer Plugin-Paketwurzel wieindex.js,api.js,runtime-api.js,setup-entry.jsund eng begrenzte Dateien wielogin-qr-api.jsverwenden. Importieren Sie niemalssrc/*eines Plugin-Pakets aus dem Kern oder aus einer anderen Extension. - Aufteilung der Repo-Einstiegspunkte:
<plugin-package-root>/api.jsist das Barrel für Helfer/Typen,<plugin-package-root>/runtime-api.jsist das nur-Laufzeit-Barrel,<plugin-package-root>/index.jsist der Einstieg des gebündelten Plugins, und<plugin-package-root>/setup-entry.jsist der Einstieg des Setup-Plugins. - Aktuelle Beispiele für gebündelte Provider:
- Anthropic verwendet
api.js/contract-api.jsfür Claude-Stream-Helper wiewrapAnthropicProviderStream, Helper für Beta-Header und Parsing vonservice_tier. - OpenAI verwendet
api.jsfür Provider-Builder, Helper für Standardmodelle und Builder für Realtime-Provider. - OpenRouter verwendet
api.jsfür seinen Provider-Builder sowie Onboarding-/Konfigurations- Helper, währendregister.runtime.jsweiterhin generischeplugin-sdk/provider-stream-Helper für die repo-lokale Nutzung re-exportieren kann.
- Anthropic verwendet
- Über Fassade geladene öffentliche Einstiegspunkte bevorzugen den aktiven Laufzeit- Konfigurations-Snapshot, wenn einer existiert, und fallen andernfalls auf die auf der Platte aufgelöste Konfigurationsdatei zurück, wenn OpenClaw noch keinen Laufzeit-Snapshot bereitstellt.
- Generische gemeinsame Primitive bleiben der bevorzugte öffentliche SDK-Vertrag. Ein kleiner
reservierter Kompatibilitätssatz gebündelter, kanalmarkierter Helper-Seams existiert weiterhin.
Behandeln Sie diese als Seams für gebündelte Wartung/Kompatibilität, nicht als neue
Importziele für Drittanbieter; neue kanalübergreifende Verträge sollten weiterhin auf
generischen
plugin-sdk/*-Subpaths oder den plugin-lokalen Barrelsapi.js/runtime-api.jslanden.
- Vermeiden Sie für neuen Code das Root-Barrel
openclaw/plugin-sdk. - Bevorzugen Sie zuerst die schmalen stabilen Primitive. Die neueren Subpaths für setup/pairing/reply/
feedback/contract/inbound/threading/command/secret-input/webhook/infra/
allowlist/status/message-tool sind der vorgesehene Vertrag für neue
gebündelte und externe Plugin-Arbeit.
Target-Parsing/-Matching gehört auf
openclaw/plugin-sdk/channel-targets. Gates für Message-Actions und Helper für Reaktions-Message-IDs gehören aufopenclaw/plugin-sdk/channel-actions. - Extensionspezifische Helper-Barrels gebündelter Plugins sind standardmäßig nicht stabil. Wenn ein
Helper nur von einer gebündelten Extension benötigt wird, behalten Sie ihn hinter der
lokalen Naht
api.jsoderruntime-api.jsder Extension, statt ihn nachopenclaw/plugin-sdk/<extension>zu befördern. - Neue gemeinsame Helper-Seams sollten generisch sein, nicht kanalmarkiert. Gemeinsames Target-
Parsing gehört auf
openclaw/plugin-sdk/channel-targets; kanalspezifische Interna bleiben hinter dem lokalenapi.jsoderruntime-api.jsdes besitzenden Plugins. - Fähigkeitsspezifische Subpaths wie
image-generation,media-understandingundspeechexistieren, weil gebündelte/native Plugins sie heute verwenden. Ihre Existenz bedeutet für sich genommen nicht, dass jeder exportierte Helper ein langfristig eingefrorener externer Vertrag ist.
Schemas für das Message-Tool
Plugins sollten kanalspezifische Schema-Beiträge fürdescribeMessageTool(...)
besitzen. Behalten Sie providerspezifische Felder im Plugin, nicht im gemeinsamen Kern.
Für gemeinsame portable Schemafragmente verwenden Sie die generischen Helper, die über
openclaw/plugin-sdk/channel-actions exportiert werden:
createMessageToolButtonsSchema()für Payloads im Stil von SchaltflächengitterncreateMessageToolCardSchema()für strukturierte Karten-Payloads
Auflösung von Kanalzielen
Kanal-Plugins sollten die kanalspezifische Zielsemantik besitzen. Halten Sie den gemeinsamen Outbound-Host generisch und verwenden Sie die Oberfläche des Messaging-Adapters für Provider-Regeln:messaging.inferTargetChatType({ to })entscheidet, ob ein normalisiertes Ziel vor der Verzeichnissuche alsdirect,groupoderchannelbehandelt werden soll.messaging.targetResolver.looksLikeId(raw, normalized)teilt dem Kern mit, ob eine Eingabe direkt in die Auflösung einer ID-ähnlichen Form übergehen soll, statt in die Verzeichnissuche.messaging.targetResolver.resolveTarget(...)ist der Plugin-Fallback, wenn der Kern nach der Normalisierung oder nach einem Verzeichnis-Fehlschlag eine endgültige providereigene Auflösung benötigt.messaging.resolveOutboundSessionRoute(...)besitzt die providerspezifische Konstruktion der Sitzungsroute, sobald ein Ziel aufgelöst ist.
- Verwenden Sie
inferTargetChatTypefür Kategorientscheidungen, die vor der Suche nach Peers/Gruppen stattfinden sollten. - Verwenden Sie
looksLikeIdfür Prüfungen wie „dies als explizite/native Ziel-ID behandeln“. - Verwenden Sie
resolveTargetfür provider-spezifischen Normalisierungs-Fallback, nicht für umfangreiche Verzeichnissuche. - Behalten Sie native Provider-IDs wie Chat-IDs, Thread-IDs, JIDs, Handles und Raum-IDs
innerhalb von
target-Werten oder providerspezifischen Parametern, nicht in generischen SDK-Feldern.
Konfigurationsgestützte Verzeichnisse
Plugins, die Verzeichniseinträge aus der Konfiguration ableiten, sollten diese Logik im Plugin behalten und die gemeinsamen Helper ausopenclaw/plugin-sdk/directory-runtime wiederverwenden.
Verwenden Sie dies, wenn ein Kanal konfigurationsgestützte Peers/Gruppen benötigt, wie etwa:
- Allowlist-gesteuerte DM-Peers
- konfigurierte Kanal-/Gruppenzuordnungen
- kontobezogene statische Verzeichnis-Fallbacks
directory-runtime behandeln nur generische Operationen:
- Query-Filterung
- Anwenden von Limits
- Helfer für Deduplizierung/Normalisierung
- Erstellen von
ChannelDirectoryEntry[]
Provider-Kataloge
Provider-Plugins können Modellkataloge für die Inferenz definieren mitregisterProvider({ catalog: { run(...) { ... } } }).
catalog.run(...) gibt dieselbe Form zurück, die OpenClaw in
models.providers schreibt:
{ provider }für einen Provider-Eintrag{ providers }für mehrere Provider-Einträge
catalog, wenn das Plugin providerspezifische Modell-IDs, Standardwerte für baseUrl
oder auth-gesteuerte Modellmetadaten besitzt.
catalog.order steuert, wann der Katalog eines Plugins relativ zu den
integrierten impliziten Providern von OpenClaw zusammengeführt wird:
simple: einfache API-Key- oder env-gesteuerte Providerprofile: Provider, die erscheinen, wenn Auth-Profile vorhanden sindpaired: Provider, die mehrere zusammengehörige Provider-Einträge synthetisierenlate: letzter Durchlauf, nach anderen impliziten Providern
discoveryfunktioniert weiterhin als Legacy-Alias- wenn sowohl
catalogals auchdiscoveryregistriert sind, verwendet OpenClawcatalog
Schreibgeschützte Kanalinspektion
Wenn Ihr Plugin einen Kanal registriert, bevorzugen Sie die Implementierung vonplugin.config.inspectAccount(cfg, accountId) zusammen mit resolveAccount(...).
Warum:
resolveAccount(...)ist der Laufzeitpfad. Es darf davon ausgehen, dass Credentials vollständig materialisiert sind, und bei fehlenden erforderlichen Secrets schnell fehlschlagen.- Schreibgeschützte Befehlspfade wie
openclaw status,openclaw status --all,openclaw channels status,openclaw channels resolveund Doctor-/Konfigurations- Reparaturabläufe sollten keine Laufzeit-Credentials materialisieren müssen, nur um Konfiguration zu beschreiben.
inspectAccount(...):
- Nur beschreibenden Kontozustand zurückgeben.
enabledundconfiguredbeibehalten.- Felder zu Credential-Quelle/-Status einschließen, wenn relevant, z. B.:
tokenSource,tokenStatusbotTokenSource,botTokenStatusappTokenSource,appTokenStatussigningSecretSource,signingSecretStatus
- Sie müssen keine rohen Tokenwerte zurückgeben, nur um schreibgeschützte
Verfügbarkeit zu melden. Die Rückgabe von
tokenStatus: "available"(und dem zugehörigen Quellenfeld) reicht für statusartige Befehle aus. - Verwenden Sie
configured_unavailable, wenn ein Credential über SecretRef konfiguriert ist, im aktuellen Befehlspfad aber nicht verfügbar ist.
Paket-Packs
Ein Plugin-Verzeichnis kann einpackage.json mit openclaw.extensions enthalten:
name/<fileBase>.
Wenn Ihr Plugin npm-Abhängigkeiten importiert, installieren Sie sie in diesem Verzeichnis, damit
node_modules verfügbar ist (npm install / pnpm install).
Sicherheitsleitplanke: Jeder Eintrag in openclaw.extensions muss nach der Auflösung von Symlinks innerhalb des Plugin-
Verzeichnisses bleiben. Einträge, die das Paketverzeichnis verlassen, werden
abgelehnt.
Sicherheitshinweis: openclaw plugins install installiert Plugin-Abhängigkeiten mit
npm install --omit=dev --ignore-scripts (keine Lifecycle-Skripte, keine Dev-Abhängigkeiten zur Laufzeit). Halten Sie Plugin-Abhängigkeits-
Bäume „reines JS/TS“ und vermeiden Sie Pakete, die postinstall-Builds benötigen.
Optional: openclaw.setupEntry kann auf ein leichtgewichtiges Nur-Setup-Modul verweisen.
Wenn OpenClaw Setup-Oberflächen für ein deaktiviertes Kanal-Plugin benötigt oder
wenn ein Kanal-Plugin aktiviert, aber noch nicht konfiguriert ist, lädt es setupEntry
statt des vollständigen Plugin-Einstiegs. Das hält Start und Einrichtung leichter,
wenn Ihr Haupteinstieg außerdem Tools, Hooks oder anderen rein laufzeitbezogenen
Code verdrahtet.
Optional: openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen
kann ein Kanal-Plugin während der Phase vor listen beim Gateway-Start ebenfalls in denselben setupEntry-
Pfad opt-in versetzen, selbst wenn der Kanal bereits konfiguriert ist.
Verwenden Sie dies nur, wenn setupEntry die Startoberfläche vollständig abdeckt, die
existieren muss, bevor das Gateway zu lauschen beginnt. In der Praxis bedeutet das, dass der
Setup-Einstieg jede kanaleigene Fähigkeit registrieren muss, von der der Start abhängt, wie z. B.:
- die Kanalregistrierung selbst
- beliebige HTTP-Routen, die verfügbar sein müssen, bevor das Gateway zu lauschen beginnt
- beliebige Gateway-Methoden, Tools oder Services, die in diesem Zeitraum vorhanden sein müssen
singleAccountKeysToMovenamedAccountPromotionKeysresolveSingleAccountPromotionTarget(...)
channels.<id>.accounts.* überführen muss, ohne den vollständigen Plugin-Einstieg zu laden.
Matrix ist das aktuelle gebündelte Beispiel: Es verschiebt nur Auth-/Bootstrap-Schlüssel in ein
benanntes hochgestuftes Konto, wenn bereits benannte Konten existieren, und es kann
einen konfigurierten nicht-kanonischen Standard-Kontoschlüssel beibehalten, statt immer
accounts.default zu erstellen.
Diese Setup-Patch-Adapter halten die Discovery gebündelter Vertragsoberflächen lazy. Die Importzeit
bleibt gering; die Promotionsoberfläche wird nur bei der ersten Verwendung geladen, statt beim Modulimport
erneut den Start gebündelter Kanäle zu betreten.
Wenn diese Startoberflächen Gateway-RPC-Methoden enthalten, behalten Sie sie auf einem
plugin-spezifischen Präfix. Kern-Admin-Namespaces (config.*,
exec.approvals.*, wizard.*, update.*) bleiben reserviert und werden immer
nach operator.admin aufgelöst, selbst wenn ein Plugin einen schmaleren Scope anfordert.
Beispiel:
Katalogmetadaten für Kanäle
Kanal-Plugins können Setup-/Discovery-Metadaten überopenclaw.channel und
Installationshinweise über openclaw.install bekanntgeben. Dadurch bleiben die Katalogdaten des Kerns datenfrei.
Beispiel:
openclaw.channel über das Minimalbeispiel hinaus:
detailLabel: sekundäres Label für reichhaltigere Katalog-/StatusoberflächendocsLabel: Linktext für den Dokumentationslink überschreibenpreferOver: Plugin-/Kanal-IDs niedrigerer Priorität, die dieser Katalogeintrag übertreffen sollteselectionDocsPrefix,selectionDocsOmitLabel,selectionExtras: Steuerung von Texten auf AuswahloberflächenmarkdownCapable: markiert den Kanal für Entscheidungen zur Outbound-Formatierung als Markdown-fähigexposure.configured: blendet den Kanal aus Oberflächen mit konfigurierten Kanälen aus, wenn auffalsegesetztexposure.setup: blendet den Kanal aus interaktiven Setup-/Configure-Pickern aus, wenn auffalsegesetztexposure.docs: markiert den Kanal für Dokumentations-Navigationsoberflächen als intern/privatshowConfigured/showInSetup: Legacy-Aliase werden aus Kompatibilitätsgründen weiterhin akzeptiert; bevorzugen SieexposurequickstartAllowFrom: nimmt den Kanal in den Standard-Quickstart-AblaufallowFromaufforceAccountBinding: explizite Kontobindung erzwingen, selbst wenn nur ein Konto existiertpreferSessionLookupForAnnounceTarget: Sitzungs-Lookup bei der Auflösung von Ankündigungszielen bevorzugen
~/.openclaw/mpm/plugins.json~/.openclaw/mpm/catalog.json~/.openclaw/plugins/catalog.json
OPENCLAW_PLUGIN_CATALOG_PATHS (oder OPENCLAW_MPM_CATALOG_PATHS) auf
eine oder mehrere JSON-Dateien (durch Komma/Semikolon/PATH getrennt). Jede Datei sollte
{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] } enthalten. Der Parser akzeptiert auch "packages" oder "plugins" als Legacy-Aliase für den Schlüssel "entries".
Context-Engine-Plugins
Context-Engine-Plugins besitzen die Orchestrierung des Sitzungs-Kontexts für Ingest, Zusammenstellung und Kompaktierung. Registrieren Sie sie aus Ihrem Plugin mitapi.registerContextEngine(id, factory) und wählen Sie dann die aktive Engine mit
plugins.slots.contextEngine.
Verwenden Sie dies, wenn Ihr Plugin die Standard-
Context-Pipeline ersetzen oder erweitern muss, statt nur Memory Search oder Hooks hinzuzufügen.
compact()
trotzdem und delegieren Sie ihn explizit:
Eine neue Fähigkeit hinzufügen
Wenn ein Plugin Verhalten benötigt, das nicht in die aktuelle API passt, umgehen Sie das Plugin-System nicht mit einem privaten Reach-in. Fügen Sie die fehlende Fähigkeit hinzu. Empfohlene Reihenfolge:- den Kernvertrag definieren Entscheiden Sie, welches gemeinsame Verhalten der Kern besitzen soll: Richtlinie, Fallback, Konfigurations-Merge, Lebenszyklus, kanalorientierte Semantik und Form des Laufzeit-Helfers.
- typisierte Oberflächen für Plugin-Registrierung/Laufzeit hinzufügen
Erweitern Sie
OpenClawPluginApiund/oderapi.runtimeum die kleinste nützliche typisierte Fähigkeitsoberfläche. - Kern + Kanal-/Feature-Konsumenten verdrahten Kanäle und Feature-Plugins sollten die neue Fähigkeit über den Kern konsumieren, nicht durch direkten Import einer Anbieterimplementierung.
- Anbieterimplementierungen registrieren Anbieter-Plugins registrieren dann ihre Backends gegen die Fähigkeit.
- Vertragsabdeckung hinzufügen Fügen Sie Tests hinzu, damit Ownership und Registrierungsform im Laufe der Zeit explizit bleiben.
Checkliste für Fähigkeiten
Wenn Sie eine neue Fähigkeit hinzufügen, sollte die Implementierung in der Regel diese Oberflächen gemeinsam berühren:- Kernvertragstypen in
src/<capability>/types.ts - Kern-Runner/Laufzeit-Helper in
src/<capability>/runtime.ts - Plugin-API-Registrierungsoberfläche in
src/plugins/types.ts - Verdrahtung der Plugin-Registry in
src/plugins/registry.ts - Bereitstellung der Plugin-Laufzeit in
src/plugins/runtime/*, wenn Feature-/Kanal- Plugins sie konsumieren müssen - Capture-/Test-Helper in
src/test-utils/plugin-registration.ts - Ownership-/Vertragsprüfungen in
src/plugins/contracts/registry.ts - Operator-/Plugin-Dokumentation in
docs/
Vorlage für Fähigkeiten
Minimales Muster:- der Kern besitzt den Fähigkeitsvertrag + die Orchestrierung
- Anbieter-Plugins besitzen Anbieterimplementierungen
- Feature-/Kanal-Plugins konsumieren Laufzeit-Helfer
- Vertragstests halten Ownership explizit