Skip to main content
Für das öffentliche Funktionsmodell, die Plugin-Strukturen und die Verträge zu Zuständigkeit und Ausführung siehe Plugin-Architektur. Diese Seite behandelt die internen Mechanismen: Lade-Pipeline, Registry, Runtime-Hooks, Gateway-HTTP- Routen, Importpfade und Schematabellen.

Lade-Pipeline

Beim Start führt OpenClaw ungefähr Folgendes aus:
  1. potenzielle Plugin-Wurzelverzeichnisse ermitteln
  2. native oder kompatible Bundle-Manifeste und Paketmetadaten lesen
  3. unsichere Kandidaten ablehnen
  4. Plugin-Konfiguration normalisieren (plugins.enabled, allow, deny, entries, slots, load.paths)
  5. Aktivierung für jeden Kandidaten festlegen
  6. aktivierte native Module laden: Erstellte gebündelte Module verwenden einen nativen Loader; lokale TypeScript-Quellen von Drittanbietern verwenden als Notlösung den Jiti-Fallback
  7. native register(api)-Hooks aufrufen und Registrierungen in der Plugin-Registry erfassen
  8. die Registry für Befehle und Runtime-Oberflächen bereitstellen
Sicherheitsprüfungen werden vor der Runtime-Ausführung durchgeführt. Die Ermittlung blockiert einen Kandidaten, wenn:
  • sein aufgelöster Einstiegspunkt außerhalb des Plugin-Wurzelverzeichnisses liegt
  • sein Pfad (oder sein Wurzelverzeichnis) für alle Benutzer beschreibbar ist
  • bei nicht gebündelten Plugins der Pfadeigentümer nicht mit der aktuellen uid (oder root) übereinstimmt
Bei für alle Benutzer beschreibbaren gebündelten Verzeichnissen wird zunächst direkt vor Ort eine chmod-Reparatur versucht (npm-/globale Installationen können Paketverzeichnisse mit 0777 ausliefern), bevor die Prüfung erneut erfolgt; bei gebündeltem Ursprung werden Eigentümerprüfungen vollständig übersprungen. Blockierte Kandidaten enthalten in der ausgegebenen Diagnose weiterhin ihre Plugin-ID, sofern diese bekannt ist (einschließlich IDs, die aus einem Manifest innerhalb eines ansonsten abgelehnten Verzeichnisses aufgelöst wurden). Dadurch wird eine Konfiguration, die auf diese ID verweist, einem blockierten Plugin mit einer Warnung zur Pfadsicherheit zugeordnet, statt einen nicht damit zusammenhängenden Fehler „Unbekanntes Plugin“ zu erhalten.

Manifest-zuerst-Verhalten

Das Manifest ist die maßgebliche Quelle der Steuerungsebene. OpenClaw verwendet es, um:
  • das Plugin zu identifizieren
  • deklarierte Kanäle/Skills/Konfigurationsschemata oder Bundle-Funktionen zu ermitteln
  • plugins.entries.<id>.config zu validieren
  • Beschriftungen/Platzhalter der Control UI zu ergänzen
  • Installations-/Katalogmetadaten anzuzeigen
  • leichtgewichtige Aktivierungs- und Einrichtungsdeskriptoren zu erhalten, ohne die Plugin-Runtime zu laden
Bei nativen Plugins bildet das Runtime-Modul den Teil der Datenebene. Es registriert das tatsächliche Verhalten, beispielsweise Hooks, Werkzeuge, Befehle oder Provider-Abläufe. Optionale Manifestblöcke activation und setup verbleiben auf der Steuerungsebene. Sie sind reine Metadatendeskriptoren für die Aktivierungsplanung und Einrichtungsermittlung; sie ersetzen weder die Runtime-Registrierung noch register(...) oder setupEntry. Aktive Aktivierungs-Consumer verwenden Hinweise zu Befehlen, Kanälen und Providern aus dem Manifest, um das Laden von Plugins vor einer umfassenderen Materialisierung der Registry einzugrenzen:
  • Beim Laden der CLI wird auf Plugins eingegrenzt, denen der angeforderte primäre Befehl gehört
  • Bei der Kanaleinrichtung/Plugin-Auflösung wird auf Plugins eingegrenzt, denen die angeforderte Kanal-ID gehört
  • Bei der expliziten Provider-Einrichtung/Runtime-Auflösung wird auf Plugins eingegrenzt, denen die angeforderte Provider-ID gehört
  • Die Startplanung des Gateways verwendet activation.onStartup für explizite Start- Importe; Plugins ohne Startmetadaten werden nur durch engere Aktivierungsauslöser geladen
Der Aktivierungsplaner stellt sowohl eine reine ID-API für bestehende Aufrufer als auch eine Plan-API für Diagnosen bereit. Planeinträge geben an, warum ein Plugin ausgewählt wurde, und unterscheiden dabei explizite activation.*-Hinweise vom Fallback über die Manifest-Zuständigkeit: Diese Trennung der Gründe bildet die Kompatibilitätsgrenze: Bestehende Plugin-Metadaten funktionieren weiterhin, während neuer Code umfassende Hinweise oder Fallback-Verhalten erkennen kann, ohne die Semantik des Runtime-Ladens zu ändern. Runtime-Vorabladevorgänge zur Anfragezeit, die den umfassenden Geltungsbereich all anfordern, leiten weiterhin eine explizite effektive Menge von Plugin-IDs aus der Konfiguration, der Startplanung, den konfigurierten Kanälen, Slots und Regeln zur automatischen Aktivierung ab (resolveEffectivePluginIds in src/plugins/effective-plugin-ids.ts). Wenn diese abgeleitete Menge leer ist, lässt OpenClaw den Geltungsbereich leer, statt ihn auf jedes ermittelbare Plugin auszuweiten. Die Einrichtungsermittlung bevorzugt Deskriptor-eigene IDs wie setup.providers und setup.cliBackends, um potenzielle Plugins einzugrenzen, bevor auf setup-api für Plugins zurückgegriffen wird, die weiterhin Runtime-Hooks zur Einrichtungszeit benötigen. Listen zur Provider-Einrichtung verwenden Manifest-providerAuthChoices, aus Deskriptoren abgeleitete Einrichtungs- optionen und Installationskatalog-Metadaten, ohne die Provider-Runtime zu laden. Ein explizites setup.requiresRuntime: false stellt eine reine Deskriptor-Abschaltung dar; ein ausgelassenes requiresRuntime behält aus Kompatibilitätsgründen den Legacy-Fallback über die Einrichtungs-API bei. Wenn mehr als ein ermitteltes Plugin denselben normalisierten Einrichtungs-Provider oder dieselbe CLI-Backend-ID beansprucht, lehnt die Einrichtungssuche den mehrdeutigen Zuständigen ab, statt sich auf die Ermittlungsreihenfolge zu verlassen. Wenn die Einrichtungs-Runtime ausgeführt wird, melden Registry-Diagnosen Abweichungen zwischen setup.providers / setup.cliBackends und den Providern oder CLI- Backends, die tatsächlich durch die Einrichtungs-API registriert wurden, ohne Legacy-Plugins zu blockieren.

Plugin-Cache-Grenze

OpenClaw speichert weder Ergebnisse der Plugin-Ermittlung noch direkte Daten der Manifest-Registry hinter zeitbasierten Gültigkeitsfenstern zwischen. Installationen, Manifeständerungen und Änderungen an Ladepfaden müssen beim nächsten expliziten Lesen der Metadaten oder beim nächsten Neuaufbau des Snapshots sichtbar werden. Der Manifestdatei-Parser verwendet einen begrenzten Dateisignatur-Cache, dessen Schlüssel aus dem Pfad des geöffneten Manifests sowie Gerät/Inode, Größe und mtime/ctime besteht; dieser Cache verhindert lediglich das erneute Parsen unveränderter Bytes und darf keine Antworten zu Ermittlung, Registry, Zuständigkeit oder Richtlinien zwischenspeichern. Der sichere schnelle Metadatenpfad basiert auf explizitem Objektbesitz und nicht auf einem verborgenen Cache. Leistungskritische Pfade beim Gateway-Start sollten den aktuellen PluginMetadataSnapshot, den abgeleiteten PluginLookUpTable oder eine explizite Manifest-Registry durch die Aufrufkette reichen. Konfigurationsvalidierung, automatische Aktivierung beim Start, Plugin-Bootstrap und Provider- Auswahl können diese Objekte wiederverwenden, solange sie die aktuelle Konfiguration und den aktuellen Plugin-Bestand darstellen. Die Einrichtungssuche rekonstruiert Manifest-Metadaten weiterhin bei Bedarf, sofern der jeweilige Einrichtungspfad keine explizite Manifest-Registry erhält; dies sollte ein Fallback für selten ausgeführte Pfade bleiben, statt verborgene Such-Caches hinzuzufügen. Wenn sich die Eingabe ändert, erstellen und ersetzen Sie den Snapshot neu, statt ihn zu verändern oder historische Kopien aufzubewahren. Ansichten der aktiven Plugin-Registry und Bootstrap- Hilfsfunktionen für gebündelte Kanäle sollten aus der aktuellen Registry/dem aktuellen Wurzelverzeichnis neu berechnet werden. Kurzlebige Maps innerhalb eines einzelnen Aufrufs sind zulässig, um Arbeit zu deduplizieren oder Wiedereintritte zu verhindern; sie dürfen nicht zu Prozessmetadaten-Caches werden. Beim Laden von Plugins ist das Runtime-Laden die persistente Cache-Schicht. Sie kann Loader-Zustände wiederverwenden, wenn Code oder installierte Artefakte tatsächlich geladen werden, beispielsweise:
  • PluginLoaderCacheState und kompatible aktive Runtime-Registries
  • Jiti-/Modul-Caches und Loader-Caches für öffentliche Oberflächen, die verhindern, dass dieselbe Runtime-Oberfläche wiederholt importiert wird
  • Dateisystem-Caches für installierte Plugin-Artefakte
  • kurzlebige Maps pro Aufruf für die Pfadnormalisierung oder Auflösung von Duplikaten
Diese Caches sind Implementierungsdetails der Datenebene. Sie dürfen keine Fragen der Steuerungsebene beantworten, etwa „Welchem Plugin gehört dieser Provider?“, sofern der Aufrufer nicht ausdrücklich das Laden der Runtime angefordert hat. Fügen Sie keine persistenten oder zeitbasierten Caches hinzu für:
  • Ermittlungsergebnisse
  • direkte Manifest-Registries
  • aus dem Index installierter Plugins rekonstruierte Manifest-Registries
  • Suche nach Provider-Zuständigen, Modellunterdrückung, Provider-Richtlinien oder Metadaten öffentlicher Artefakte
  • andere aus Manifesten abgeleitete Antworten, bei denen ein geändertes Manifest, ein geänderter installierter Index oder ein geänderter Ladepfad beim nächsten Lesen der Metadaten sichtbar sein sollte
Aufrufer, die Manifest-Metadaten aus dem persistenten Index installierter Plugins neu aufbauen, rekonstruieren diese Registry bei Bedarf. Der installierte Index ist ein dauerhafter Zustand der Quellebene; er ist kein verborgener prozessinterner Metadaten-Cache.

Registry-Modell

Geladene Plugins verändern nicht direkt beliebige globale Variablen des Kerns. Sie registrieren sich in einer zentralen Plugin-Registry (PluginRegistry in src/plugins/registry-types.ts), die Plugin-Datensätze (Identität, Quelle, Ursprung, Status, Diagnosen) sowie Arrays für jede Funktion verwaltet: Werkzeuge, Legacy-Hooks und typisierte Hooks, Kanäle, Provider, Gateway-RPC-Handler, HTTP-Routen, CLI-Registrierungsfunktionen, Hintergrunddienste, Plugin-eigene Befehle und Dutzende weitere typisierte Provider- Familien (Sprachausgabe, Einbettungen, Bild-/Video-/Musikgenerierung, Web- Abruf/-Suche, Agent-Harnesses, Sitzungsaktionen und so weiter). Kernfunktionen lesen anschließend aus dieser Registry, statt direkt mit Plugin- Modulen zu kommunizieren. Dadurch bleibt der Ladevorgang unidirektional:
  • Plugin-Modul -> Registry-Registrierung
  • Kern-Runtime -> Registry-Nutzung
Diese Trennung ist für die Wartbarkeit wichtig. Dadurch benötigen die meisten Kernoberflächen nur einen Integrationspunkt: „Registry lesen“, nicht „jedes Plugin-Modul als Sonderfall behandeln“.

Callbacks für Konversationsbindungen

Plugins, die eine Konversation binden, können reagieren, wenn eine Genehmigung abgeschlossen wurde. Verwenden Sie api.onConversationBindingResolved(...), um einen Callback zu erhalten, nachdem eine Bindungs- anfrage genehmigt oder abgelehnt wurde:
Felder der Callback-Nutzlast:
  • status: "approved" oder "denied"
  • decision: "allow-once", "allow-always" oder "deny"
  • binding: die aufgelöste Bindung für genehmigte Anfragen
  • request: die Zusammenfassung der ursprünglichen Anfrage, der Hinweis zum Trennen, die Absender-ID und die Konversationsmetadaten
Dieser Callback dient ausschließlich zur Benachrichtigung. Er ändert nicht, wer eine Konversation binden darf, und wird ausgeführt, nachdem die Verarbeitung der Genehmigung im Kern abgeschlossen ist.

Provider-Runtime-Hooks

Provider-Plugins verfügen über drei Ebenen:
  • Manifest-Metadaten für eine leichtgewichtige Suche vor der Runtime: setup.providers[].envVars, providerAuthAliases, providerAuthChoices und channelConfigs.
  • Hooks zur Konfigurationszeit: catalog plus applyConfigDefaults.
  • Runtime-Hooks: mehr als 40 optionale Hooks für Authentifizierung, Modellauflösung, Stream-Wrapper, Denkstufen, Wiederholungsrichtlinien und Nutzungsendpunkte. Siehe Hook-Reihenfolge und Nutzung.
OpenClaw ist weiterhin für die generische Agentenschleife, das Failover, die Transkriptverarbeitung und die Tool-Richtlinie zuständig. Diese Hooks bilden die Erweiterungsschnittstelle für providerspezifisches Verhalten, ohne dass ein vollständig benutzerdefinierter Inferenztransport erforderlich ist. Verwenden Sie Manifest setup.providers[].envVars, wenn der Provider umgebungsvariablenbasierte Anmeldedaten besitzt, die generische Authentifizierungs-, Status- und Modellauswahlpfade erkennen sollen, ohne die Plugin-Laufzeit zu laden. Verwenden Sie Manifest providerAuthAliases, wenn eine Provider-ID die Umgebungsvariablen, Authentifizierungsprofile, konfigurationsgestützte Authentifizierung und Auswahl für das API-Schlüssel-Onboarding einer anderen Provider-ID wiederverwenden soll. Verwenden Sie Manifest providerAuthChoices, wenn CLI-Oberflächen für Onboarding und Authentifizierungsauswahl die Auswahl-ID des Providers, Gruppenbeschriftungen und eine einfache Authentifizierungsanbindung über ein einzelnes Flag kennen sollen, ohne die Provider-Laufzeit zu laden. Behalten Sie Provider-Laufzeit- envVars für Hinweise für Betreiber bei, etwa Onboarding-Beschriftungen oder Variablen zur Einrichtung von OAuth-Client-ID und -Client-Secret. Beschreiben Sie die umgebungsvariablengesteuerte Kanaleinrichtung und Authentifizierung über die zugehörigen channelConfigs.<id>.schema- und Einrichtungsdeskriptoren.

Reihenfolge und Verwendung der Hooks

Bei Modell-/Provider-Plugins ruft OpenClaw die Hooks ungefähr in dieser Reihenfolge auf. Die Spalte „Wann verwenden“ dient als schnelle Entscheidungshilfe. Ausschließlich der Kompatibilität dienende Provider-Felder, die OpenClaw nicht mehr aufruft, wie ProviderPlugin.capabilities und suppressBuiltInModel, sind hier bewusst nicht aufgeführt. normalizeModelId, normalizeTransport und normalizeConfig prüfen zuerst das übereinstimmende Provider-Plugin und durchlaufen dann weitere Hook-fähige Provider-Plugins, bis eines tatsächlich die Modell-ID oder den Transport/die Konfiguration ändert. Dadurch funktionieren Alias-/Kompatibilitäts-Provider-Shims weiterhin, ohne dass der Aufrufer wissen muss, welches gebündelte Plugin für die Umschreibung zuständig ist. Wenn kein Provider-Hook einen unterstützten Konfigurationseintrag der Google-Familie umschreibt, führt der gebündelte Google-Konfigurationsnormalisierer weiterhin diese Kompatibilitätsbereinigung durch. Wenn der Provider ein vollständig benutzerdefiniertes Wire-Protokoll oder einen benutzerdefinierten Request-Executor benötigt, handelt es sich um eine andere Erweiterungsklasse. Diese Hooks sind für Provider-Verhalten vorgesehen, das weiterhin in der normalen Inferenzschleife von OpenClaw ausgeführt wird. resolveUsageAuth entscheidet, ob OpenClaw fetchUsageSnapshot aufrufen oder für Nutzungs-/Statusoberflächen auf die generische Auflösung von Zugangsdaten zurückgreifen soll. Geben Sie { token, accountId?, subscriptionType?, rateLimitTier? } zurück, wenn der Provider über Nutzungszugangsdaten verfügt (die optionalen Tarifmetadaten fließen in fetchUsageSnapshot ein), geben Sie { handled: true } zurück, wenn die Provider-eigene Nutzungsauthentifizierung die Anfrage verarbeitet hat und den generischen API-Schlüssel-/OAuth-Fallback unterdrücken muss, und geben Sie null oder undefined zurück, wenn der Provider die Nutzungsauthentifizierung nicht verarbeitet hat. Deklarieren Sie Organisations- oder Abrechnungszugangsdaten im Manifest providerUsageAuthEnvVars. Dadurch können generische Erkennungs- und Secret-Bereinigungsoberflächen sie erkennen, ohne sie zu Kandidaten für die Inferenzauthentifizierung zu machen.

Provider-Beispiel

Integrierte Beispiele

Gebündelte Provider-Plugins kombinieren die oben genannten Hooks entsprechend den Katalog-, Authentifizierungs-, Denk-, Wiederholungs- und Nutzungsanforderungen der jeweiligen Anbieter. Der maßgebliche Hook-Satz befindet sich bei jedem Plugin unter extensions/; diese Seite veranschaulicht die Strukturen, statt die Liste zu spiegeln.
OpenRouter, Kilocode, Z.AI und xAI registrieren catalog sowie resolveDynamicModel / prepareDynamicModel, damit sie vorgelagerte Modell-IDs vor dem statischen Katalog von OpenClaw bereitstellen können.
GitHub Copilot, Gemini CLI, ChatGPT Codex, MiniMax, Xiaomi und z.ai kombinieren prepareRuntimeAuth oder formatApiKey mit resolveUsageAuth + fetchUsageSnapshot, um Token-Austausch und die Integration von /usage zu übernehmen.
Gemeinsame benannte Familien (google-gemini, passthrough-gemini, anthropic-by-model, hybrid-anthropic-openai) ermöglichen Providern, sich über buildReplayPolicy für Transkriptrichtlinien zu entscheiden, statt die Bereinigung in jedem Plugin erneut zu implementieren.
byteplus, cloudflare-ai-gateway, huggingface, kimi-coding, nvidia, qianfan, synthetic, together, venice, vercel-ai-gateway und volcengine registrieren nur catalog und verwenden die gemeinsame Inferenzschleife.
Beta-Header, /fast / serviceTier und context1m befinden sich innerhalb der öffentlichen api.ts- / contract-api.ts-Schnittstelle des Anthropic-Plugins (wrapAnthropicProviderStream, resolveAnthropicBetas, resolveAnthropicFastMode, resolveAnthropicServiceTier) und nicht im generischen SDK.

Runtime-Hilfsfunktionen

Plugins können über api.runtime auf ausgewählte Kern-Hilfsfunktionen zugreifen. Für TTS:
Hinweise:
  • textToSpeech gibt die normale TTS-Ausgabe-Payload des Kerns für Datei-/Sprachnachrichtenoberflächen zurück.
  • Verwendet die Kernkonfiguration tts und die Provider-Auswahl.
  • Gibt einen PCM-Audiopuffer und die Abtastrate zurück. Plugins müssen für Provider neu abtasten/kodieren.
  • listVoices ist pro Provider optional. Verwenden Sie es für anbietereigene Sprachauswahl- oder Einrichtungsabläufe.
  • Der Kern übergibt eine aufgelöste Anfragefrist an Provider-Hooks vom Typ listVoices; Provider-spezifische Zeitüberschreitungseinstellungen können sie überschreiben.
  • Sprachlisten können umfangreichere Metadaten wie Gebietsschema, Geschlecht und Persönlichkeits-Tags für Provider-bewusste Auswahlfelder enthalten.
  • OpenAI und ElevenLabs unterstützen derzeit Telefonie. Microsoft nicht.
Plugins können über api.registerSpeechProvider(...) auch Sprachanbieter registrieren.
Hinweise:
  • Belassen Sie TTS-Richtlinien, Fallback und Antwortzustellung im Kern.
  • Verwenden Sie Sprachanbieter für anbietereigenes Syntheseverhalten.
  • Die ältere Microsoft-Eingabe edge wird auf die Provider-ID microsoft normalisiert.
  • Das bevorzugte Zuständigkeitsmodell ist unternehmensorientiert: Ein Anbieter-Plugin kann Text-, Sprach-, Bild- und zukünftige Medien-Provider verwalten, wenn OpenClaw diese Fähigkeitsverträge hinzufügt.
Für das Verstehen von Bildern, Audio und Videos registrieren Plugins einen typisierten Provider für Medienverständnis statt einer generischen Schlüssel/Wert-Sammlung:
Hinweise:
  • Belassen Sie Orchestrierung, Fallback, Konfiguration und Kanalverdrahtung im Kern.
  • Belassen Sie anbieterspezifisches Verhalten im Provider-Plugin.
  • Additive Erweiterungen sollten typisiert bleiben: neue optionale Methoden, neue optionale Ergebnisfelder, neue optionale Fähigkeiten.
  • Die Videoerzeugung folgt bereits demselben Muster:
    • Der Kern verwaltet den Fähigkeitsvertrag und die Runtime-Hilfsfunktion.
    • Anbieter-Plugins registrieren api.registerVideoGenerationProvider(...).
    • Funktions-/Kanal-Plugins verwenden api.runtime.videoGeneration.*.
Für Runtime-Hilfsfunktionen zum Medienverständnis können Plugins Folgendes aufrufen:
Für die Audiotranskription können Plugins entweder die Runtime für Medienverständnis oder den älteren STT-Alias verwenden:
Hinweise:
  • api.runtime.mediaUnderstanding.* ist die bevorzugte gemeinsame Oberfläche für das Verstehen von Bildern, Audio und Videos.
  • extractStructuredWithModel(...) ist die Plugin-seitige Schnittstelle für begrenzte, Provider-eigene, bildorientierte Extraktion. Fügen Sie mindestens eine Bildeingabe ein; Texteingaben sind ergänzender Kontext. Produkt-Plugins verwalten ihre Routen und Schemas, während OpenClaw die Provider-/Runtime-Grenze verwaltet.
  • Verwendet die Audio-Kernkonfiguration für Medienverständnis (tools.media.audio) und die Provider-Fallback-Reihenfolge.
  • Gibt { text: undefined } zurück, wenn keine Transkriptionsausgabe erzeugt wird (beispielsweise bei übersprungener/nicht unterstützter Eingabe).
Plugins können über api.runtime.subagent auch Subagent-Hintergrundläufe starten:
Hinweise:
  • provider und model sind optionale Überschreibungen pro Lauf und keine dauerhaften Sitzungsänderungen.
  • toolsAlsoAllow akzeptiert exakte, eindeutig zugeordnete Werkzeugnamen, die vom aufrufenden Plugin registriert wurden. Kernnamen und mehrdeutige Namen werden abgelehnt. Es ergänzt das normale Profil, doch Betreiber-Zulassungs- und Sperrlisten bleiben maßgeblich.
  • OpenClaw berücksichtigt diese Überschreibungsfelder nur für vertrauenswürdige Aufrufer.
  • Für Plugin-eigene Fallback-Läufe müssen Betreiber sich mit plugins.entries.<id>.subagent.allowModelOverride: true ausdrücklich dafür entscheiden.
  • Verwenden Sie plugins.entries.<id>.subagent.allowedModels, um vertrauenswürdige Plugins auf bestimmte kanonische provider/model-Ziele zu beschränken, oder "*", um ausdrücklich jedes Ziel zuzulassen.
  • Subagent-Läufe nicht vertrauenswürdiger Plugins funktionieren weiterhin, Überschreibungsanforderungen werden jedoch abgelehnt, statt stillschweigend auf einen Fallback zurückzugreifen.
  • Von Plugins erstellte Subagent-Sitzungen werden mit der ID des erstellenden Plugins gekennzeichnet. Fallback api.runtime.subagent.deleteSession(...) darf nur diese zugehörigen Sitzungen löschen; das Löschen beliebiger Sitzungen erfordert weiterhin eine Gateway-Anfrage mit Administratorbereich.
Für die Websuche können Plugins die gemeinsame Runtime-Hilfsfunktion verwenden, statt auf die Verdrahtung der Agentenwerkzeuge zuzugreifen:
Plugins können über api.registerWebSearchProvider(...) auch Websuch-Provider registrieren. Hinweise:
  • Belassen Sie Provider-Auswahl, Auflösung von Zugangsdaten und gemeinsame Anfragesemantik im Kern.
  • Verwenden Sie Websuch-Provider für anbieterspezifische Suchtransporte.
  • api.runtime.webSearch.* ist die bevorzugte gemeinsame Oberfläche für Funktions-/Kanal-Plugins, die Suchverhalten benötigen, ohne vom Wrapper des Agentenwerkzeugs abhängig zu sein.

api.runtime.imageGeneration

  • generate(...): Generiert ein Bild mithilfe der konfigurierten Provider-Kette für die Bilderzeugung.
  • listProviders(...): Listet verfügbare Provider für die Bilderzeugung und deren Fähigkeiten auf.

Gateway-HTTP-Routen

Plugins können mit api.registerHttpRoute(...) HTTP-Endpunkte bereitstellen.
Routenfelder:
  • path: Routenpfad unter dem Gateway-HTTP-Server.
  • auth: Erforderlich, "gateway" oder "plugin". Verwenden Sie "gateway", um die normale Gateway-Authentifizierung zu verlangen, oder "plugin" für eine vom Plugin verwaltete Authentifizierung/Webhook-Verifizierung.
  • match: Optional. "exact" (Standard) oder "prefix".
  • handleUpgrade: Optionaler Handler für WebSocket-Upgrade-Anfragen auf derselben Route.
  • replaceExisting: Optional. Ermöglicht demselben Plugin, seine eigene vorhandene Routenregistrierung zu ersetzen.
  • handler: Gibt true zurück, wenn die Route die Anfrage verarbeitet hat.
Hinweise:
  • api.registerHttpHandler(...) wurde entfernt und verursacht einen Fehler beim Laden des Plugins. Verwenden Sie stattdessen api.registerHttpRoute(...).
  • Plugin-Routen müssen auth ausdrücklich deklarieren.
  • Exakte Konflikte bei path + match werden abgelehnt, außer bei replaceExisting: true; außerdem kann ein Plugin die Route eines anderen Plugins nicht ersetzen.
  • Überlappende Routen mit unterschiedlichen auth-Stufen werden abgelehnt. Behalten Sie exact-/prefix-Durchreichungsketten ausschließlich auf derselben Authentifizierungsstufe.
  • auth: "plugin"-Routen erhalten nicht automatisch Laufzeitbereiche für Operatoren. Sie sind für vom Plugin verwaltete Webhooks bzw. Signaturverifizierung vorgesehen, nicht für privilegierte Aufrufe von Gateway-Hilfsfunktionen.
  • auth: "gateway"-Routen werden innerhalb eines Gateway-Anfragelaufzeitbereichs ausgeführt. Die Standardoberfläche (gatewayRuntimeScopeSurface: "write-default") ist absichtlich restriktiv:
    • Die Bearer-Authentifizierung mit gemeinsamem Geheimnis (gateway.auth.mode = "token" / "password") sowie jede Authentifizierungsmethode ohne vertrauenswürdigen Proxy erhalten einen einzelnen operator.write-Bereich, selbst wenn der Aufrufer x-openclaw-scopes sendet.
    • trusted-proxy-Aufrufer ohne expliziten x-openclaw-scopes-Header behalten ebenfalls die bisherige, ausschließlich auf operator.write beschränkte Oberfläche.
    • trusted-proxy-Aufrufer, die x-openclaw-scopes senden, erhalten stattdessen die deklarierten Bereiche.
    • Eine Route kann gatewayRuntimeScopeSurface: "trusted-operator" aktivieren, um x-openclaw-scopes bei identitätstragenden Authentifizierungsmodi stets zu berücksichtigen (fehlt der Header, wird auf den vollständigen Standardsatz der CLI-Bereiche zurückgegriffen).
  • Sandbox-isolierte externe Control-UI-Registerkarten, die auf auth: "gateway"-Routen basieren, verwenden eine kurzlebige, signierte Cookie-Berechtigung, die ausschließlich durch einen authentifizierten Bootstrap ausgestellt wird; Registerkarten mit Plugin-Authentifizierung behalten ihren direkten iframe-Pfad. Vor dem Einbinden führt das übergeordnete Element innerhalb derselben opaken Sandbox eine routeneigene Prüfung aus und verweigert den Zugriff, wenn die Datenschutzrichtlinie des Browsers das Cookie blockiert. Die Berechtigung ist an das zuständige Plugin, den Stamm der übereinstimmenden Route und die aktuelle Authentifizierungsgeneration gebunden. Ihr prozesszufälliger Cookie-Name verhindert, dass vertrauenswürdige Gateways auf demselben Host einander überschreiben; Cookies isolieren jedoch niemals TCP-Ports. Der Gateway-Hostname bildet daher eine einzelne Grenze für Anmeldedaten: Stellen Sie auf diesem Hostnamen keine gegenseitig nicht vertrauenswürdigen Dienste bereit, auch nicht auf anderen Ports. Die Routenzustellung lehnt eine Wiederverwendung für eine verschachtelte Route ab, die einem anderen Plugin gehört. Da Sandbox-Nachfahren für Cookie-Zwecke websiteübergreifend sind, akzeptiert die Berechtigung ausschließlich GET und HEAD mit operator.read; Änderungen und WebSocket-Upgrades verbleiben auf explizit Gateway-authentifizierten Oberflächen. Das Cookie kann absichtlich kein CHIPS verwenden: Aktuelle Browser beziehen ein Bit für websiteübergreifende Vorfahren in den Partitionierungsschlüssel ein, sodass verschachtelte opake Sandbox-Frames den Zugriff auf Ressourcen derselben Route verlieren würden. Das Cookie erfordert einen sicheren Kontext und die Browserberechtigung für websiteübergreifende Cookies. Daher sind Gateway-authentifizierte externe Registerkarten auf reinen HTTP-LAN-Ursprüngen oder bei vollständiger Blockierung von Drittanbieter-Cookies nicht verfügbar; verwenden Sie HTTPS/Tailscale Serve oder einen vom Browser als vertrauenswürdig eingestuften Loopback mit einer kompatiblen Cookie-Richtlinie.
  • Die Berechtigung verhindert die Offenlegung des Gateway-Bearer-Tokens und eine versehentliche Wiederverwendung von Routen oder Bereichen; sie schafft keine Sicherheitsgrenze zwischen nativen Plugins. Nativer Plugin-Code und die von ihm bereitgestellten UI-Inhalte bleiben Teil derselben vertrauenswürdigen, prozessinternen Plugin-Grenze.
  • Praktische Regel: Gehen Sie nicht davon aus, dass eine Gateway-authentifizierte Plugin-Route implizit eine Administratoroberfläche ist. Wenn Ihre Route ausschließlich Administratoren vorbehaltenes Verhalten benötigt, aktivieren Sie die trusted-operator-Bereichsoberfläche, verlangen Sie einen identitätstragenden Authentifizierungsmodus und dokumentieren Sie den expliziten Vertrag für den x-openclaw-scopes-Header.
  • Nach Routenabgleich und Authentifizierung nehmen gewöhnliche Handler an der Zulassung von Gateway-Stammaufgaben teil. Ein vorbereitetes oder neu startendes Gateway gibt 503 zurück, bevor es den Handler aufruft. Die enge Ausnahme bildet eine durch das Manifest berechtigte auth: "gateway"-Route, die zusätzlich die routenspezifische trusted-operator-Oberfläche aktiviert. Sie bleibt erreichbar, damit die Zustellung der Aussetzungssteuerung nicht blockiert wird, während gewöhnliche gleichgeordnete Routen desselben Plugins hinter der Zulassungsgrenze verbleiben. Der Besitz eines WebSocket-handleUpgrade verwendet dieselbe atomare Zulassungsgrenze. Sobald der Handler einen Socket akzeptiert, liegt dessen weitere Lebensdauer in der Verantwortung des Plugins und wird von dieser Grenze nicht nachverfolgt.

Importpfade des Plugin-SDK

Verwenden Sie beim Erstellen neuer Plugins schmale SDK-Unterpfade statt des monolithischen openclaw/plugin-sdk-Stamm-Barrels. Kernunterpfade: Kanal-Plugins wählen aus einer Familie schmaler Schnittstellen — channel-setup, setup-runtime, setup-tools, channel-pairing, channel-contract, channel-feedback, channel-inbound, channel-outbound, command-auth, secret-input, webhook-ingress, channel-targets und channel-actions. Das Genehmigungsverhalten sollte in einem einzigen approvalCapability-Vertrag zusammengeführt werden, statt es über nicht zusammenhängende Plugin-Felder zu verteilen. Siehe Kanal-Plugins. Laufzeit- und Konfigurationshilfen befinden sich unter entsprechenden fokussierten *-runtime-Unterpfaden (approval-runtime, agent-runtime, lazy-runtime, directory-runtime, text-runtime, runtime-store, system-event-runtime, heartbeat-runtime, channel-activity-runtime usw.). Bevorzugen Sie config-contracts, plugin-config-runtime, runtime-config-snapshot und config-mutation gegenüber dem breiten Kompatibilitäts-Barrel config-runtime.
openclaw/plugin-sdk/channel-lifecycle, kleine Fassaden für Kanalhilfen, openclaw/plugin-sdk/config-runtime und openclaw/plugin-sdk/infra-runtime sind veraltete Kompatibilitäts-Shims für ältere Plugins. Neuer Code sollte stattdessen schmalere generische Grundelemente importieren.
Repo-interne Einstiegspunkte (je Stamm des gebündelten Plugin-Pakets):
  • index.js — Einstiegspunkt des gebündelten Plugins
  • api.js — Barrel für Hilfsfunktionen und Typen
  • runtime-api.js — ausschließlich für die Laufzeit vorgesehenes Barrel
  • setup-entry.js — Einstiegspunkt des Einrichtungs-Plugins
Externe Plugins sollten ausschließlich openclaw/plugin-sdk/*-Unterpfade importieren. Importieren Sie niemals src/* eines anderen Plugin-Pakets aus dem Kern oder einem anderen Plugin. Über Fassaden geladene Einstiegspunkte bevorzugen den aktiven Schnappschuss der Laufzeitkonfiguration, sofern vorhanden, und greifen andernfalls auf die aufgelöste Konfigurationsdatei auf dem Datenträger zurück. Fähigkeitsspezifische Unterpfade wie image-generation, media-understanding und speech existieren, weil gebündelte Plugins sie derzeit verwenden. Sie sind nicht automatisch langfristig unveränderliche externe Verträge — prüfen Sie die entsprechende SDK-Referenzseite, wenn Sie sich auf sie verlassen.

Schemas für Nachrichtenwerkzeuge

Plugins sollten kanalspezifische Beiträge zum describeMessageTool(...)-Schema für Grundelemente außerhalb von Nachrichten wie Reaktionen, Lesebestätigungen und Umfragen besitzen. Die gemeinsame Sendedarstellung sollte den generischen MessagePresentation-Vertrag anstelle Provider-nativer Felder für Schaltflächen, Komponenten, Blöcke oder Karten verwenden. Informationen zum Vertrag, zu Rückfallregeln, zur Provider-Zuordnung und zur Checkliste für Plugin-Autoren finden Sie unter Nachrichtendarstellung. Sendefähige Plugins deklarieren über Nachrichtenfähigkeiten, was sie darstellen können:
  • presentation für semantische Darstellungsblöcke (text, context, divider, chart, table, buttons, select)
  • delivery-pin für angeheftete Zustellungsanfragen
Der Kern entscheidet, ob die Darstellung nativ gerendert oder auf Text reduziert wird. Stellen Sie über das generische Nachrichtenwerkzeug keine Provider-nativen UI-Ausweichmöglichkeiten bereit. Veraltete SDK-Hilfsfunktionen für ältere native Schemas bleiben für bestehende Drittanbieter-Plugins exportiert, neue Plugins sollten sie jedoch nicht verwenden.

Auflösung von Kanalzielen

Kanal-Plugins sollten die kanalspezifische Zielsemantik besitzen. Halten Sie den gemeinsamen ausgehenden Host generisch und verwenden Sie die Messaging-Adapter-Oberfläche für Provider-Regeln:
  • messaging.inferTargetChatType({ to }) entscheidet vor der Verzeichnissuche, ob ein normalisiertes Ziel als direct, group oder channel behandelt werden soll.
  • messaging.targetResolver.looksLikeId(raw, normalized) teilt dem Kern mit, ob eine Eingabe direkt zur ID-ähnlichen Auflösung wechseln und die Verzeichnissuche überspringen soll.
  • messaging.targetResolver.reservedLiterals listet einzelne Wörter auf, die Kanal-/Sitzungsreferenzen für diesen Provider sind. Bei der Auflösung bleiben konfigurierte Verzeichniseinträge erhalten, bevor reservierte Literale abgelehnt werden; anschließend wird bei einem Fehlschlag im Verzeichnis der Zugriff verweigert.
  • messaging.targetResolver.resolveTarget(...) ist der Plugin-Rückfall, wenn der Kern nach der Normalisierung oder einem Fehlschlag im Verzeichnis eine abschließende, dem Provider zugeordnete Auflösung benötigt.
  • messaging.resolveOutboundSessionRoute(...) besitzt die Provider-spezifische Konstruktion der Sitzungsroute, sobald ein Ziel aufgelöst wurde.
Empfohlene Aufteilung:
  • Verwenden Sie inferTargetChatType für Kategorieentscheidungen, die vor der Suche nach Peers/Gruppen erfolgen sollen.
  • Verwenden Sie looksLikeId für Prüfungen nach dem Muster „Dies als explizite/native Ziel-ID behandeln“.
  • Verwenden Sie resolveTarget als Provider-spezifischen Rückfall für die Normalisierung, nicht für eine umfassende Verzeichnissuche.
  • Bewahren Sie Provider-native IDs wie Chat-IDs, Thread-IDs, JIDs, Handles und Raum-IDs in target-Werten oder Provider-spezifischen Parametern auf, nicht in generischen SDK-Feldern.

Konfigurationsgestützte Verzeichnisse

Plugins, die Verzeichniseinträge aus der Konfiguration ableiten, sollten diese Logik im Plugin belassen und die gemeinsamen Hilfsfunktionen aus openclaw/plugin-sdk/directory-runtime wiederverwenden. Verwenden Sie dies, wenn ein Kanal konfigurationsgestützte Peers/Gruppen benötigt, beispielsweise:
  • durch eine Positivliste gesteuerte DM-Peers
  • konfigurierte Kanal-/Gruppenzuordnungen
  • kontobezogene statische Verzeichnisrückfälle
Die gemeinsamen Hilfsfunktionen in directory-runtime verarbeiten ausschließlich generische Operationen:
  • Abfragefilterung
  • Anwendung von Begrenzungen
  • Hilfsfunktionen für Deduplizierung/Normalisierung
  • Erstellung von ChannelDirectoryEntry[]
Kanalspezifische Kontoprüfung und ID-Normalisierung sollten in der Plugin-Implementierung verbleiben.

Provider-Kataloge

Provider-Plugins können mit registerProvider({ catalog: { run(...) { ... } } }) Modellkataloge für Inferenz definieren. catalog.run(...) gibt dieselbe Struktur zurück, die OpenClaw in models.providers schreibt:
  • { provider } für einen Provider-Eintrag
  • { providers } für mehrere Provider-Einträge
Verwenden Sie catalog, wenn das Plugin Provider-spezifische Modell-IDs, Standardwerte für die Basis-URL oder authentifizierungsabhängige Modellmetadaten verwaltet. catalog.order steuert, wann der Katalog eines Plugins relativ zu den integrierten impliziten Providern von OpenClaw zusammengeführt wird:
  • simple: einfache API-Schlüssel- oder umgebungsgesteuerte Provider
  • profile: Provider, die angezeigt werden, wenn Authentifizierungsprofile vorhanden sind
  • paired: Provider, die mehrere zusammengehörige Provider-Einträge erzeugen
  • late: letzter Durchlauf nach anderen impliziten Providern
Bei Schlüsselkollisionen haben später geladene Provider Vorrang, sodass Plugins einen integrierten Provider-Eintrag mit derselben Provider-ID absichtlich überschreiben können. Plugins können außerdem schreibgeschützte Modellzeilen über api.registerModelCatalogProvider({ provider, kinds, staticCatalog, liveCatalog }) veröffentlichen. Dies ist der vorgesehene Pfad für Listen-, Hilfe- und Auswahloberflächen und unterstützt Zeilen vom Typ text, voice, image_generation, video_generation und music_generation. Provider-Plugins bleiben für Live-Endpunktaufrufe, den Token-Austausch und die Zuordnung von Anbieterantworten zuständig; der Core verwaltet die gemeinsame Zeilenstruktur, Quellenbezeichnungen und die Formatierung der Hilfe für Medienwerkzeuge. Registrierungen von Providern zur Mediengenerierung erzeugen automatisch statische Katalogzeilen aus defaultModel, models und capabilities. Kompatibilität:
  • discovery funktioniert weiterhin als Legacy-Alias, gibt jedoch eine Veraltungswarnung aus
  • wenn sowohl catalog als auch discovery registriert sind, verwendet OpenClaw catalog und gibt eine Warnung aus
  • augmentModelCatalog ist veraltet; gebündelte Provider sollten ergänzende Zeilen über registerModelCatalogProvider veröffentlichen

Schreibgeschützte Kanalprüfung

Wenn Ihr Plugin einen Kanal registriert, sollten Sie plugin.config.inspectAccount(cfg, accountId) zusammen mit resolveAccount(...) implementieren. Gründe:
  • resolveAccount(...) ist der Laufzeitpfad. Er darf davon ausgehen, dass Anmeldedaten vollständig materialisiert sind, und kann schnell fehlschlagen, wenn erforderliche Geheimnisse fehlen.
  • Schreibgeschützte Befehlspfade wie openclaw status, openclaw status --all, openclaw channels status, openclaw channels resolve sowie Reparaturabläufe für Doctor und Konfiguration sollten Laufzeitanmeldedaten nicht materialisieren müssen, nur um die Konfiguration zu beschreiben.
Empfohlenes Verhalten für inspectAccount(...):
  • Geben Sie nur einen beschreibenden Kontostatus zurück.
  • Behalten Sie enabled und configured bei.
  • Fügen Sie gegebenenfalls Felder für Quelle und Status der Anmeldedaten hinzu, beispielsweise:
    • tokenSource, tokenStatus
    • botTokenSource, botTokenStatus
    • appTokenSource, appTokenStatus
    • signingSecretSource, signingSecretStatus
  • Sie müssen keine Rohwerte von Tokens zurückgeben, nur um die schreibgeschützte Verfügbarkeit zu melden. Die Rückgabe von tokenStatus: "available" (und des zugehörigen Quellenfelds) reicht für statusorientierte Befehle aus.
  • Verwenden Sie configured_unavailable, wenn Anmeldedaten über SecretRef konfiguriert, im aktuellen Befehlspfad jedoch nicht verfügbar sind.
Dadurch können schreibgeschützte Befehle „konfiguriert, aber in diesem Befehlspfad nicht verfügbar“ melden, anstatt abzustürzen oder das Konto fälschlicherweise als nicht konfiguriert zu melden.

Paket-Packs

Ein Plugin-Verzeichnis kann eine package.json mit openclaw.extensions enthalten:
Jeder Eintrag wird zu einem Plugin. Wenn das Pack mehrere Erweiterungen aufführt, wird die Plugin-ID zu <manifestOrPackageName>/<fileBase> (die Manifest-ID hat Vorrang, wenn sie vorhanden ist; andernfalls wird der nicht bereichsgebundene Name package.json verwendet). Wenn Ihr Plugin npm-Abhängigkeiten importiert, installieren Sie diese in diesem Verzeichnis, damit node_modules verfügbar ist (npm install / pnpm install). Sicherheitsvorgabe: Jeder openclaw.extensions-Eintrag muss nach der Auflösung symbolischer Links innerhalb des Plugin- Verzeichnisses bleiben. Einträge, die das Paketverzeichnis verlassen, werden abgelehnt. Sicherheitshinweis: openclaw plugins install installiert Plugin-Abhängigkeiten mit einer projektlokalen npm install --omit=dev --ignore-scripts (keine Lebenszyklusskripte, keine Entwicklungsabhängigkeiten zur Laufzeit) und ignoriert dabei geerbte globale npm-Installationseinstellungen. Halten Sie die Abhängigkeitsbäume von Plugins „reines JS/TS“ und vermeiden Sie Pakete, die postinstall-Builds erfordern. Optional: openclaw.setupEntry kann auf ein schlankes, ausschließlich für die Einrichtung vorgesehenes Modul verweisen. Wenn OpenClaw Einrichtungsoberflächen für ein deaktiviertes Kanal-Plugin benötigt oder wenn ein Kanal-Plugin aktiviert, aber noch nicht konfiguriert ist, lädt es setupEntry anstelle des vollständigen Plugin-Eintrags. Dadurch bleiben Start und Einrichtung schlanker, wenn Ihr Haupt-Plugin-Eintrag außerdem Werkzeuge, Hooks oder anderen ausschließlich zur Laufzeit benötigten Code einbindet. Optional: openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen kann ein Kanal-Plugin während der Startphase vor dem Lauschen des Gateways für denselben setupEntry-Pfad aktivieren, selbst wenn der Kanal bereits konfiguriert ist. Verwenden Sie dies nur, wenn setupEntry die Startoberfläche vollständig abdeckt, die vorhanden sein muss, bevor das Gateway zu lauschen beginnt. In der Praxis bedeutet dies, dass der Einrichtungseintrag jede kanaleigene Fähigkeit registrieren muss, von der der Start abhängt, beispielsweise:
  • die Kanalregistrierung selbst
  • alle HTTP-Routen, die verfügbar sein müssen, bevor das Gateway zu lauschen beginnt
  • alle Gateway-Methoden, Werkzeuge oder Dienste, die während desselben Zeitfensters vorhanden sein müssen
Wenn Ihr vollständiger Eintrag weiterhin eine erforderliche Startfähigkeit verwaltet, aktivieren Sie dieses Flag nicht. Behalten Sie das Standardverhalten des Plugins bei und lassen Sie OpenClaw während des Starts den vollständigen Eintrag laden. Gebündelte Kanäle können außerdem ausschließlich für die Einrichtung vorgesehene Hilfsfunktionen für Vertragsoberflächen veröffentlichen, die der Core abfragen kann, bevor die vollständige Kanallaufzeit geladen wird. Die aktuelle Einrichtungsoberfläche für die Heraufstufung ist:
  • singleAccountKeysToMove
  • namedAccountPromotionKeys
  • resolveSingleAccountPromotionTarget(...)
Der Core verwendet diese Oberfläche, wenn er eine Legacy-Kanalkonfiguration für ein einzelnes Konto in channels.<id>.accounts.* überführen muss, ohne den vollständigen Plugin-Eintrag zu laden. Matrix ist das aktuelle gebündelte Beispiel: Wenn benannte Konten bereits vorhanden sind, verschiebt es nur Authentifizierungs-/Bootstrap-Schlüssel in ein benanntes heraufgestuftes Konto und kann einen konfigurierten, nicht kanonischen Schlüssel für das Standardkonto beibehalten, statt immer accounts.default zu erstellen. Diese Einrichtungs-Patch-Adapter sorgen dafür, dass die Erkennung gebündelter Vertragsoberflächen verzögert erfolgt. Die Importzeit bleibt kurz; die Heraufstufungsoberfläche wird erst bei der ersten Verwendung geladen, statt beim Modulimport den Start gebündelter Kanäle erneut auszuführen. Wenn diese Startoberflächen Gateway-RPC-Methoden enthalten, verwenden Sie dafür ein Plugin-spezifisches Präfix. Die Core-Administrationsnamensräume (config.*, exec.approvals.*, wizard.*, update.*) bleiben reserviert und werden immer zu operator.admin aufgelöst, selbst wenn ein Plugin einen engeren Geltungsbereich anfordert. Beispiel:

Metadaten des Kanalkatalogs

Kanal-Plugins können Einrichtungs-/Erkennungsmetadaten über openclaw.channel und Installationshinweise über openclaw.install bereitstellen. Dadurch enthält der Core-Katalog keine Daten. Beispiel:
Nützliche openclaw.channel-Felder über das Minimalbeispiel hinaus:
  • detailLabel: sekundäre Bezeichnung für umfangreichere Katalog-/Statusoberflächen
  • docsLabel: Linktext für den Dokumentationslink überschreiben
  • preferOver: Plugin-/Kanal-IDs mit niedrigerer Priorität, die dieser Katalogeintrag übertreffen soll
  • selectionDocsPrefix, selectionDocsOmitLabel, selectionExtras: Steuerung der Texte auf Auswahloberflächen
  • markdownCapable: kennzeichnet den Kanal für Entscheidungen zur ausgehenden Formatierung als Markdown-fähig
  • exposure.configured: blendet den Kanal auf Listenoberflächen für konfigurierte Kanäle aus, wenn auf false gesetzt
  • exposure.setup: blendet den Kanal in interaktiven Auswahlfeldern für Einrichtung/Konfiguration aus, wenn auf false gesetzt
  • exposure.docs: kennzeichnet den Kanal für Dokumentationsnavigationsoberflächen als intern/privat
  • quickstartAllowFrom: nimmt den Kanal in den standardmäßigen Schnellstartablauf allowFrom auf
  • forceAccountBinding: erfordert eine explizite Kontobindung, selbst wenn nur ein Konto vorhanden ist
  • preferSessionLookupForAnnounceTarget: bevorzugt bei der Auflösung von Ankündigungszielen die Sitzungssuche
OpenClaw kann außerdem externe Kanalkataloge zusammenführen (beispielsweise einen Export aus einer MPM- Registry). Legen Sie eine JSON-Datei an einem der folgenden Orte ab:
  • ~/.openclaw/mpm/plugins.json
  • ~/.openclaw/mpm/catalog.json
  • ~/.openclaw/plugins/catalog.json
Alternativ können Sie OPENCLAW_PLUGIN_CATALOG_PATHS (oder OPENCLAW_MPM_CATALOG_PATHS) auf eine oder mehrere JSON-Dateien verweisen lassen (durch Kommas, Semikolons oder PATH getrennt). Jede Datei sollte { "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] } enthalten. Der Parser akzeptiert außerdem "packages" oder "plugins" als Legacy-Aliasse für den Schlüssel "entries". Generierte Kanalkatalogeinträge und Katalogeinträge für Provider-Installationen stellen normalisierte Fakten zur Installationsquelle neben dem unverarbeiteten openclaw.install-Block bereit. Die normalisierten Fakten geben an, ob die npm-Spezifikation eine exakte Version oder ein variabler Selektor ist, ob die erwarteten Integritätsmetadaten vorhanden sind und ob außerdem ein lokaler Quellpfad verfügbar ist. Wenn die Katalog-/Paketidentität bekannt ist, warnen die normalisierten Fakten, falls der geparste npm-Paketname von dieser Identität abweicht. Sie warnen außerdem, wenn defaultChoice ungültig ist oder auf eine nicht verfügbare Quelle verweist sowie wenn npm-Integritätsmetadaten ohne eine gültige npm- Quelle vorhanden sind. Verbraucher sollten installSource als additives optionales Feld behandeln, damit manuell erstellte Einträge und Katalog-Shims es nicht erzeugen müssen. Dadurch können Onboarding und Diagnosen den Zustand der Quellenebene erläutern, ohne die Plugin-Laufzeit zu importieren. Offizielle externe npm-Einträge sollten eine exakte npmSpec zusammen mit expectedIntegrity bevorzugen. Reine Paketnamen und Dist-Tags funktionieren aus Kompatibilitätsgründen weiterhin, zeigen jedoch Warnungen auf Quellenebene an, sodass sich der Katalog zu fixierten, integritätsgeprüften Installationen weiterentwickeln kann, ohne vorhandene Plugins zu beeinträchtigen. Wenn das Onboarding aus einem lokalen Katalogpfad installiert, zeichnet es einen verwalteten Eintrag im Plugin- Index mit source: "path" und nach Möglichkeit einem arbeitsbereichsrelativen sourcePath auf. Der absolute operative Ladepfad verbleibt in plugins.load.paths; der Installationseintrag vermeidet es, lokale Pfade der Arbeitsstation in die langfristige Konfiguration zu duplizieren. Dadurch bleiben lokale Entwicklungsinstallationen für Diagnosen auf Quellenebene sichtbar, ohne eine zweite Oberfläche zur Offenlegung unverarbeiteter Dateisystempfade hinzuzufügen. Die persistierte SQLite-Tabelle installed_plugin_index ist die maßgebliche Quelle für Installationen und kann aktualisiert werden, ohne Plugin-Laufzeitmodule zu laden. Ihre installRecords-Zuordnung bleibt auch dann dauerhaft erhalten, wenn ein Plugin-Manifest fehlt oder ungültig ist; ihre plugins-Nutzlast ist eine wiederherstellbare Manifestansicht.

Plugins für die Kontext-Engine

Plugins für die Kontext-Engine verwalten die Orchestrierung des Sitzungskontexts für Aufnahme, Zusammenstellung und Compaction. Registrieren Sie sie aus Ihrem Plugin mit api.registerContextEngine(id, factory) und wählen Sie anschließend die aktive Engine mit plugins.slots.contextEngine aus. Verwenden Sie dies, wenn Ihr Plugin die standardmäßige Kontext- Pipeline ersetzen oder erweitern muss, statt lediglich eine Speichersuche oder Hooks hinzuzufügen.
Die Factory ctx stellt optionale Werte für config, agentDir und workspaceDir zur Initialisierung bei der Konstruktion bereit. Der Host schließt die registrierte asynchrone Vorbereitung des Memory-Prompts ab, bevor er assemble() einer nicht veralteten Engine aufruft. buildMemorySystemPromptAddition(...) bleibt synchron und liest diesen unveränderlichen Lauf-Snapshot, während assemble() aktiv ist. Reichen Sie den bereitgestellten Werkzeug- und Zitationskontext unverändert weiter, damit der Snapshot keine Laufgrenzen überschreiten kann. assemble() kann contextProjection zurückgeben, wenn das aktive Harness über einen persistenten Backend-Thread verfügt. Lassen Sie es bei der veralteten Projektion pro Durchlauf weg. Geben Sie { mode: "thread_bootstrap", epoch } zurück, wenn der zusammengesetzte Kontext einmalig in einen Backend-Thread eingefügt und wiederverwendet werden soll, bis sich die Epoche ändert. Ändern Sie die Epoche, nachdem sich der semantische Kontext der Engine geändert hat, beispielsweise nach einem von der Engine verwalteten Compaction-Durchlauf. Hosts können Metadaten von Werkzeugaufrufen, die Eingabeform und redigierte Werkzeugergebnisse in einer Thread-Bootstrap-Projektion beibehalten, damit neue Backend-Threads die Werkzeugkontinuität bewahren, ohne unverarbeitete, geheimnistragende Payloads zu kopieren. Wenn Ihre Engine den Compaction-Algorithmus nicht verwaltet, behalten Sie die Implementierung von compact() bei und delegieren Sie ihn ausdrücklich:

Neue Capability hinzufügen

Wenn ein Plugin ein Verhalten benötigt, das nicht zur aktuellen API passt, umgehen Sie das Plugin-System nicht durch einen privaten Direktzugriff. Fügen Sie die fehlende Capability hinzu. Empfohlene Reihenfolge:
  1. Definieren Sie den Core-Vertrag. Legen Sie fest, welches gemeinsame Verhalten der Core verwalten soll: Richtlinie, Fallback, Konfigurationszusammenführung, Lebenszyklus, kanalbezogene Semantik und Form der Runtime-Hilfsfunktion.
  2. Fügen Sie typisierte Oberflächen für Plugin-Registrierung und Runtime hinzu. Erweitern Sie OpenClawPluginApi und/oder api.runtime um die kleinste zweckmäßige typisierte Capability-Oberfläche.
  3. Binden Sie Core- sowie Kanal-/Feature-Consumer an. Kanäle und Feature-Plugins sollten die neue Capability über den Core nutzen, statt die Implementierung eines Providers direkt zu importieren.
  4. Registrieren Sie Provider-Implementierungen. Provider-Plugins registrieren anschließend ihre Backends für die Capability.
  5. Fügen Sie Vertragsabdeckung hinzu. Fügen Sie Tests hinzu, damit Eigentümerschaft und Registrierungsform dauerhaft explizit bleiben.
So bleibt OpenClaw meinungsstark, ohne fest auf die Sichtweise eines einzelnen Providers zugeschnitten zu werden. Eine konkrete Datei-Checkliste und ein ausgearbeitetes Beispiel finden Sie im Capability-Kochbuch.

Capability-Checkliste

Wenn Sie eine neue Capability hinzufügen, sollte die Implementierung üblicherweise diese Oberflächen gemeinsam berühren:
  • Core-Vertragstypen in src/<capability>/types.ts
  • Core-Runner/-Runtime-Hilfsfunktion in src/<capability>/runtime.ts
  • Registrierungsoberfläche der Plugin-API in src/plugins/types.ts
  • Verdrahtung der Plugin-Registry in src/plugins/registry.ts
  • Runtime-Bereitstellung des Plugins in src/plugins/runtime/*, wenn Feature-/Kanal- Plugins sie nutzen müssen
  • Erfassungs-/Testhilfen in src/test-utils/plugin-registration.ts
  • Eigentümerschafts-/Vertragszusicherungen in src/plugins/contracts/registry.ts
  • Dokumentation für Betreiber/Plugins in docs/
Wenn eine dieser Oberflächen fehlt, ist dies üblicherweise ein Zeichen dafür, dass die Capability noch nicht vollständig integriert ist.

Capability-Vorlage

Minimales Muster:
Vertragstestmuster (src/plugins/contracts/registry.ts stellt Eigentümerschaftsabfragen wie providerContractPluginIds bereit; Tests bestätigen, dass die contracts.videoGenerationProviders-Liste eines Plugins mit seinen tatsächlichen Registrierungen übereinstimmt):
Dadurch bleibt die Regel einfach:
  • Der Core verwaltet den Capability-Vertrag und die Orchestrierung
  • Provider-Plugins verwalten die Provider-Implementierungen
  • Feature-/Kanal-Plugins nutzen Runtime-Hilfsfunktionen
  • Vertragstests halten die Eigentümerschaft explizit fest

Verwandte Themen