Channelシステム概要
ChannelシステムはElftiaのマルチプラットフォーム向けメッセージ受信レイヤーです。Discord、Telegram、Slackなど外部プラットフォームからのメッセージをAgentの処理パイプラインへルーティングし、返信を元のプラットフォームへ送り返す役割を担います。
アーキテクチャ概要
graph TB
subgraph External Platforms
D[Discord]
T[Telegram]
S[Slack]
O[Other Platforms...]
end
subgraph Channel Plugin Layer
PL[ChannelPluginLoader<br/>Plugin Discovery & Loading]
PR[ChannelPluginRegistry<br/>Instance Management & Event Dispatch]
end
subgraph Message Pipeline
MR[ChannelMessageRouter<br/>Security Pipeline + Trigger Matching]
end
subgraph Security Pipeline
RL[RateLimiter]
IS[InputSanitizer]
PG[PromptGuardian]
UP[UserPermissionService]
CG[ChannelPermissionGate]
end
subgraph Agent Layer
MB[ChannelMagiBridge<br/>Message Format Conversion]
MS[MagiService<br/>Agent Processing]
end
D & T & S & O --> PR
PL --> PR
PR -->|message event| MR
MR --> RL --> IS --> PG --> UP --> CG
MR -->|routeToAgent event| MB
MB --> MS
MS -->|response| MB
MB -->|sendResponse| MR
MR -->|sendMessage| PR
PR --> D & T & S & O
主要ファイル一覧
| ファイル | パス | 責務 |
|---|---|---|
| ChannelPluginLoader | desktop/app/main/services/capabilities/integrations/channel/ChannelPluginLoader.ts | プラグインの探索・検証・ロード(2ディレクトリ対応) |
| ChannelPluginRegistry | desktop/app/main/services/capabilities/integrations/channel/ChannelPluginRegistry.ts | プラグインファクトリとChannelインスタンスのライフサイクル管理 |
| ChannelMessageRouter | desktop/app/main/services/capabilities/integrations/channel/ChannelMessageRouter.ts | セキュリティパイプライン、トリガーマッチング、メッセージバッファリング、レスポンス分割 |
| ChannelMagiBridge | desktop/app/main/services/agent-core/magi/ChannelMagiBridge.ts | Channelメッセージ → MagiIncomingMessage への変換 |
| ChannelMarketplaceService | desktop/app/main/services/capabilities/integrations/channel/ChannelMarketplaceService.ts | CDNマニフェスト取得、プラグインのダウンロードとインストール |
| ChannelPluginRouter | desktop/app/main/services/routers/ChannelPluginRouter.ts | IPCルーティング(フロントエンド ↔ バックエンド) |
| channel-sdk | packages/channel-sdk/src/ | プラグイン開発SDK(型定義・インターフェース) |
| channel-types | desktop/app/shared/contracts/channel-types.ts | Channel統一型定義 |
| channel-sdk (re-export) | desktop/app/shared/contracts/channel-sdk.ts | SDK型の再エクスポート + ユーティリティ関数のインライン定義 |
| security-types | desktop/app/shared/contracts/security-types.ts | ユーザーロールと権限の型定義 |
| RateLimiter | desktop/app/main/services/platform/security/RateLimiter.ts | スライディングウィンドウ方式のレート制限 |
| InputSanitizer | desktop/app/main/services/platform/security/InputSanitizer.ts | 不可視文字の除去 |
| PromptGuardian | desktop/app/main/services/platform/security/PromptGuardian.ts | AIによるプロンプトインジェクション検出 |
| UserPermissionService | desktop/app/main/services/platform/security/UserPermissionService.ts | ロールベースのアクセス制御 |
| ChannelPermissionGate | desktop/app/main/services/platform/security/ChannelPermissionGate.ts | 機密操作の確認メカニズム |
プラグインライフサイクル
stateDiagram-v2
[*] --> Discovered: ChannelPluginLoader.discover()
Discovered --> Registered: ChannelPluginRegistry.registerPlugin()
Registered --> InstanceCreated: createInstance(id, config)
InstanceCreated --> Connecting: connectInstance(id)
Connecting --> Connected: plugin.connect() success
Connecting --> Error: plugin.connect() failure
Connected --> Disconnected: disconnectInstance(id)
Error --> Connecting: Retry connection
Disconnected --> Connecting: Reconnect
InstanceCreated --> Removed: removeInstance(id)
Disconnected --> Removed: removeInstance(id)
Connected --> Removed: removeInstance(id)
Removed --> [*]
起動フロー
ChannelPluginLoaderが2つのディレクトリ(バンドル済み + Marketplace)をスキャンし、すべてのelftia-channel.jsonマニフェストを探索する- 検出された各プラグインに対して
loader.load()を呼び出し、モジュールをロードしてファクトリ関数を取得する registry.registerPlugin(manifest, factory, dir)を呼び出してRegistryに登録する- データベースから保存済みのChannelインスタンス設定を読み込む
- 各インスタンスに対して
registry.createInstance(id, config)を呼び出す enabled && autoConnectのインスタンスに対してregistry.connectAll()を呼び出すChannelMagiBridge.start()がrouteToAgentイベントのリッスンを開始する
接続管理
connectInstance(id)—plugin.connect(credentials, options)を呼び出す。状態遷移:disconnected → connecting → connected | errordisconnectInstance(id)—plugin.disconnect()を呼び出す。状態遷移:connected → disconnectedconnectAll()— フォールトトレランスのためPromise.allSettledを使用し、すべてのenabledインスタンスを並行接続するdisconnectAll()— 接続中のすべてのインスタンスを並行切断する
IPCチャンネル
フロントエンドの操作はすべて ChannelPluginRouter のIPCチャンネルを通じて実装されています。
| IPCチャンネル | 方向 | 説明 |
|---|---|---|
channelPlugin:listInstances | renderer → main | すべてのChannelインスタンスの一覧を取得する |
channelPlugin:createInstance | renderer → main | 新しいインスタンスを作成する(認証情報は暗号化して保存) |
channelPlugin:updateInstance | renderer → main | インスタンス設定を更新する |
channelPlugin:deleteInstance | renderer → main | インスタンスと関連ストレージを削除する |
channelPlugin:connect | renderer → main | 指定したインスタンスに接続する |
channelPlugin:disconnect | renderer → main | 指定したインスタンスを切断する |
channelPlugin:testConnection | renderer → main | 認証情報の有効性を確認する |
channelPlugin:getMarketplace | renderer → main | Marketplaceのプラグインリストを取得する |
channelPlugin:downloadPlugin | renderer → main | CDNからプラグインをダウンロード・インストールする |
channelPlugin:removePlugin | renderer → main | プラグインをアンインストールする |
channelPlugin:updateTrigger | renderer → main | トリガールールを更新する |
channelPlugin:statusChange | main → renderer | インスタンスのステータス変更通知 |
channelPlugin:downloadProgress | main → renderer | プラグインダウンロードの進捗通知 |
データ永続化
Channelインスタンス
インスタンスの設定は magi_channels テーブルに保存され、ChannelPluginRouter の channelsUpsert / channelsUpdate / channelsDelete 操作で管理されます。
プラグインのK-Vストレージ
各プラグインインスタンスは、プラットフォーム固有の状態データのために独立したキーバリューストレージ(ChannelStorageDb インターフェース)を持ちます。内部実装はSQLiteテーブルにインメモリキャッシュレイヤーを組み合わせたものです。
メッセージアクティビティログ
送受信メッセージはJSONL形式でファイルシステムに記録されます。
{channelDataDir}/{channelId}/conversations/{chatDir}/{YYYY-MM-DD}.jsonl
書き込みにはバッファリングメカニズム(2秒ごとにフラッシュ)を使用し、ディスクI/Oを抑えています。
次のステップ
- Channel Plugin SDK — プラグインインターフェースの定義とマニフェスト形式
- メッセージルーティングとセキュリティパイプライン — メッセージ処理パイプラインの詳細
- ChannelMagiBridge — ChannelからAgentへのメッセージブリッジ
- Channelプラグインの作成 — カスタムプラグインをゼロから作成する