본문으로 건너뛰기

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

주요 파일 색인

FilePathResponsibility
ChannelPluginLoaderdesktop/app/main/services/capabilities/integrations/channel/ChannelPluginLoader.ts플러그인 발견, 검증, 로드(이중 디렉터리)
ChannelPluginRegistrydesktop/app/main/services/capabilities/integrations/channel/ChannelPluginRegistry.ts플러그인 팩토리와 Channel 인스턴스 수명 주기 관리
ChannelMessageRouterdesktop/app/main/services/capabilities/integrations/channel/ChannelMessageRouter.ts보안 파이프라인, 트리거 매칭, 메시지 버퍼링, 응답 분할
ChannelMagiBridgedesktop/app/main/services/agent-core/magi/ChannelMagiBridge.tsChannel 메시지 → MagiIncomingMessage 변환
ChannelMarketplaceServicedesktop/app/main/services/capabilities/integrations/channel/ChannelMarketplaceService.tsCDN 매니페스트 가져오기, 플러그인 다운로드 및 설치
ChannelPluginRouterdesktop/app/main/services/routers/ChannelPluginRouter.tsIPC 라우팅(프런트엔드 ↔ 백엔드)
channel-sdkpackages/channel-sdk/src/플러그인 개발 SDK(타입, 인터페이스)
channel-typesdesktop/app/shared/contracts/channel-types.ts통합 Channel 타입 정의
channel-sdk (re-export)desktop/app/shared/contracts/channel-sdk.tsSDK 타입 재내보내기 + 인라인 유틸리티 함수
security-typesdesktop/app/shared/contracts/security-types.ts사용자 역할 및 권한 타입 정의
RateLimiterdesktop/app/main/services/platform/security/RateLimiter.ts슬라이딩 윈도우 속도 제한
InputSanitizerdesktop/app/main/services/platform/security/InputSanitizer.ts보이지 않는 문자 제거
PromptGuardiandesktop/app/main/services/platform/security/PromptGuardian.tsAI 기반 프롬프트 인젝션 감지
UserPermissionServicedesktop/app/main/services/platform/security/UserPermissionService.ts역할 기반 접근 제어
ChannelPermissionGatedesktop/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 --> [*]

시작 흐름

  1. ChannelPluginLoader가 두 디렉터리(번들 + marketplace)를 스캔하고 모든 elftia-channel.json 매니페스트를 발견합니다
  2. 발견된 각 플러그인에 대해 loader.load()를 호출해 모듈을 로드하고 팩토리 함수를 가져옵니다
  3. registry.registerPlugin(manifest, factory, dir)를 호출해 Registry에 등록합니다
  4. 데이터베이스에서 저장된 Channel 인스턴스 구성을 로드합니다
  5. 각 인스턴스에 대해 registry.createInstance(id, config)를 호출합니다
  6. enabled && autoConnect인 인스턴스에 대해 registry.connectAll()을 호출합니다
  7. ChannelMagiBridge.start()routeToAgent 이벤트 수신을 시작합니다

연결 관리

  • connectInstance(id)plugin.connect(credentials, options)를 호출합니다. 상태 전환: disconnected → connecting → connected | error
  • disconnectInstance(id)plugin.disconnect()를 호출합니다. 상태 전환: connected → disconnected
  • connectAll() — 내결함성을 위해 Promise.allSettled를 사용해 모든 enabled 인스턴스를 동시에 연결합니다
  • disconnectAll() — 연결된 모든 인스턴스를 동시에 연결 해제합니다

IPC Channel

모든 프런트엔드 작업은 ChannelPluginRouter의 IPC Channel을 통해 구현됩니다.

IPC ChannelDirectionDescription
channelPlugin:listInstancesrenderer → main모든 Channel 인스턴스 목록 가져오기
channelPlugin:createInstancerenderer → main새 인스턴스 생성(암호화된 자격 증명 저장 포함)
channelPlugin:updateInstancerenderer → main인스턴스 구성 업데이트
channelPlugin:deleteInstancerenderer → main인스턴스와 관련 저장소 삭제
channelPlugin:connectrenderer → main지정한 인스턴스 연결
channelPlugin:disconnectrenderer → main지정한 인스턴스 연결 해제
channelPlugin:testConnectionrenderer → main자격 증명 유효성 검증
channelPlugin:getMarketplacerenderer → mainMarketplace 플러그인 목록 가져오기
channelPlugin:downloadPluginrenderer → mainCDN에서 플러그인 다운로드 및 설치
channelPlugin:removePluginrenderer → main플러그인 제거
channelPlugin:updateTriggerrenderer → main트리거 규칙 업데이트
channelPlugin:statusChangemain → renderer인스턴스 상태 변경 알림
channelPlugin:downloadProgressmain → renderer플러그인 다운로드 진행률 알림

데이터 영속성

Channel 인스턴스

인스턴스 구성은 magi_channels 테이블에 저장되며, ChannelPluginRouterchannelsUpsert / channelsUpdate / channelsDelete 작업을 통해 관리됩니다.

플러그인 K-V 저장소

각 플러그인 인스턴스는 플랫폼별 상태 데이터를 위한 독립적인 키-값 저장소(ChannelStorageDb 인터페이스)를 소유합니다. 기본 구현은 인메모리 캐싱 레이어가 있는 SQLite 테이블입니다.

메시지 활동 로그

인바운드 및 아웃바운드 메시지는 JSONL 형식으로 파일 시스템에 기록됩니다.

{channelDataDir}/{channelId}/conversations/{chatDir}/{YYYY-MM-DD}.jsonl

디스크 I/O를 줄이기 위해 쓰기는 버퍼링 메커니즘(2초마다 플러시)을 사용합니다.

다음 단계