Plugin SDK + Runtime: Die neue Architektur für Messaging Connector
Kennst du das? Du willst eine kleine Änderung am Core vornehmen, aber plötzlich funktionieren mehrere Integrationen nicht mehr. Direkte Imports aus internen Verzeichnissen machen Updates riskant und verhindern, dass externe Entwickler saubere Plugins bauen können. Dieser Wildwuchs an Patterns führt dazu, dass jede Erweiterung anders funktioniert und Upgrades zur Qual werden.
Wir lösen dieses Problem, indem wir Messaging Connector strikt vom Core entkoppeln. Jeder Connector wird zu einem Plugin, das ausschließlich über eine stabile API kommuniziert.
Voraussetzungen
Abschnitt betitelt „Voraussetzungen“- OpenClaw Core
- TypeScript (für Typisierung)
openclaw/plugin-sdkOpenClawConfig
Schnellstart
Abschnitt betitelt „Schnellstart“In der neuen Architektur nutzt du zwei Layer, um Plugins zu bauen oder zu migrieren. Der wichtigste Punkt: Importiere niemals direkt aus src/**.
- Plugin SDK nutzen: Verwende
openclaw/plugin-sdkfür Typen wieChannelPluginoder Hilfsfunktionen für die Konfiguration. - Runtime API verwenden: Greife auf Core-Funktionen nur über
OpenClawPluginApi.runtimezu. - Konfiguration validieren: Nutze
buildChannelConfigSchemafür deine Plugin-Einstellungen. - Version festlegen: Deklariere eine benötigte Runtime-Version (z. B.
openclawRuntime: ">=2026.2.0").
Hier ist die Definition der neuen Plugin-Runtime, die du für alle Interaktionen nutzt:
export type PluginRuntime = { channel: { text: { chunkMarkdownText(text: string, limit: number): string[]; resolveTextChunkLimit(cfg: OpenClawConfig, channel: string, accountId?: string): number; hasControlCommand(text: string, cfg: OpenClawConfig): boolean; }; reply: { dispatchReplyWithBufferedBlockDispatcher(params: { ctx: unknown; cfg: unknown; dispatcherOptions: { deliver: (payload: { text?: string; mediaUrls?: string[]; mediaUrl?: string; }) => void | Promise<void>; onError?: (err: unknown, info: { kind: string }) => void; }; }): Promise<void>; createReplyDispatcherWithTyping?: unknown; // adapter for Teams-style flows }; routing: { resolveAgentRoute(params: { cfg: unknown; channel: string; accountId: string; peer: { kind: RoutePeerKind; id: string }; }): { sessionKey: string; accountId: string }; }; pairing: { buildPairingReply(params: { channel: string; idLine: string; code: string }): string; readAllowFromStore(channel: string): Promise<string[]>; upsertPairingRequest(params: { channel: string; id: string; meta?: { name?: string }; }): Promise<{ code: string; created: boolean }>; }; media: { fetchRemoteMedia(params: { url: string }): Promise<{ buffer: Buffer; contentType?: string }>; saveMediaBuffer( buffer: Uint8Array, contentType: string | undefined, direction: "inbound" | "outbound", maxBytes: number, ): Promise<{ path: string; contentType?: string }>; }; mentions: { buildMentionRegexes(cfg: OpenClawConfig, agentId?: string): RegExp[]; matchesMentionPatterns(text: string, regexes: RegExp[]): boolean; }; groups: { resolveGroupPolicy( cfg: OpenClawConfig, channel: string, accountId: string, groupId: string, ): { allowlistEnabled: boolean; allowed: boolean; groupConfig?: unknown; defaultConfig?: unknown; }; resolveRequireMention( cfg: OpenClawConfig, channel: string, accountId: string, groupId: string, override?: boolean, ): boolean; }; debounce: { createInboundDebouncer<T>(opts: { debounceMs: number; buildKey: (v: T) => string | null; shouldDebounce: (v: T) => boolean; onFlush: (entries: T[]) => Promise<void>; onError?: (err: unknown) => void; }): { push: (v: T) => void; flush: () => Promise<void> }; resolveInboundDebounceMs(cfg: OpenClawConfig, channel: string): number; }; commands: { resolveCommandAuthorizedFromAuthorizers(params: { useAccessGroups: boolean; authorizers: Array<{ configured: boolean; allowed: boolean }>; }): boolean; }; }; logging: { shouldLogVerbose(): boolean; getChildLogger(name: string): PluginLogger; }; state: { resolveStateDir(cfg: OpenClawConfig): string; };};Fehlerbehebung
Abschnitt betitelt „Fehlerbehebung“- Instabile Upgrades: Wenn dein Plugin bei Core-Updates bricht, liegt das oft an direkten Imports aus
src/**. Migriere auf das SDK und die Runtime API, um Stabilität zu garantieren. - Veraltete Bridges: Falls du noch
core-bridge.tsin deinen Extensions nutzt, ersetze diese Logik durchapi.runtimeAufrufe.
Hast du Fragen zur Implementierung? Nutze unseren AI Setup Assistant.
Nächste Schritte
Abschnitt betitelt „Nächste Schritte“OpenClaw Expert
Noch festgefahren?
Wenn diese Seite nicht hilft, frage OpenClaw Expert nach Schritt-fuer-Schritt-Loesungen.