Plugin SDK と Runtime のリファクタリング計画
開発を進めていると、コア機能と拡張機能の境界線が曖昧になり、コードが複雑に絡み合ってしまうことがあります。内部の変更が予期せぬ場所でエラーを引き起こし、メンテナンスが困難になるのは、多くの開発者が経験する悩みです。
現在のシステムでは、コネクタがコアの内部コードを直接参照していたり、独自のヘルパーが散在していたりするため、アップグレードが壊れやすく、外部プラグインの導入を妨げる要因となっています。これを解決するために、全てのメッセージングコネクタを独立したプラグインとして扱う新しいアーキテクチャへ移行します。
- OpenClaw Core
- TypeScript の基礎知識
- Node.js 環境
クイックスタート
Section titled “クイックスタート”新しい設計では、プラグインは src/** から直接インポートするのではなく、SDK または Runtime を介してのみコア機能にアクセスします。
1. Plugin SDK の導入
Section titled “1. Plugin SDK の導入”コンパイル時に使用する安定した API として openclaw/plugin-sdk を使用します。ここには型定義や設定用のヘルパーが含まれます。
2. Plugin Runtime へのアクセス
Section titled “2. Plugin Runtime へのアクセス”実行時の動作は、注入された OpenClawPluginApi.runtime を通じて操作します。
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; };};トラブルシューティング
Section titled “トラブルシューティング”アップグレード時にコネクタが破損する
Section titled “アップグレード時にコネクタが破損する”現在のコネクタがコアの内部構造に依存していることが原因です。SDK と Runtime の 2 層構造に移行することで、コアの変更からプラグインを保護します。
外部プラグインの開発が困難
Section titled “外部プラグインの開発が困難”コアのソースコードにアクセスせずにプラグインを開発できない現状があります。openclaw/plugin-sdk を公開し、Semver によるバージョン管理を行うことで、外部からの開発を可能にします。
質問がある場合や、セットアップで困ったときは AI Setup Assistant を活用してください。
次のステップ
Section titled “次のステップ”- Plugins: プラグインの基本概念
- Channels: 利用可能なチャンネル一覧
- Configuration: Gateway の設定方法
OpenClaw Expert
まだ解決しませんか?
このページで解決しない場合は、OpenClaw Expertに直接質問してください。