Include Luna AI Assistant design docs covering channels, configuration, core architecture, memory, scheduler, and skills. Add reference docs from OpenClaw and ZeroClaw projects, plus Mistral and OpenAI API specs.
4.5 KiB
Channel System
The Channel System in OpenClaw is a highly decoupled messaging platform integration layer. It allows OpenClaw to interface with diverse services like WhatsApp, Telegram, Slack, and Discord through a unified set of interfaces while preserving platform-specific capabilities.
Plugin-Per-Platform Pattern
OpenClaw employs a strict plugin architecture where every supported messaging platform is a self-contained module located under src/channels/plugins/. This directory contains over 100 files, with each platform adapter implementing a standard set of interfaces defined in types.plugin.ts and types.adapters.ts.
Key aspects of this pattern include:
- Isolation: Each plugin maintains its own dependencies and platform-specific logic (e.g., the Telegram plugin handles its own bot API calls).
- Standardized Lifecycle: Plugins implement
ChannelLifecycleAdapterto manage startup, shutdown, and health checks. - Feature-Based Opt-in: Plugins advertise their capabilities (e.g.,
threads,reactions,media) via aChannelCapabilitiesobject, allowing the core to gracefully degrade or enhance features per-channel.
Shared Registry & Helpers
A centralized registry.ts manages all active channel plugins. Instead of hardcoding platform logic into the core, the registry provides a discovery mechanism for the system to interact with whatever plugins are currently loaded.
Message Normalization
Incoming raw messages from various platforms are normalized into a standard MsgContext before reaching the agent or session logic. This normalization ensures consistent handling of:
- Sender Identification: Mapping platform-specific IDs to a common structure containing
SenderId,SenderName, andSenderUsername. - Thread Tracking: Normalizing
ThreadIdandReplyToIdso the core can track conversations across platforms that represent threads differently (e.g., Slack's thread timestamps vs. Telegram's reply-to message IDs). - Channel Metadata: Attaching
Channel(platform name) andChatType(direct, group, or channel) to every inbound payload.
Shared Utilities
OpenClaw provides several helper modules that plugins use to reduce boilerplate:
sender-identity.ts: Validates and sanitizes sender metadata.chat-meta.ts: Manages channel-level metadata like labels, blurbs, and documentation links.session-envelope.ts: Handles the wrapping of messages for persistent storage.
Access Control & Routing
OpenClaw enforces security and session boundaries at the channel level.
Allowlist-based Access
The system uses an allowlist-based policy for each channel. The allowlist-match.ts and allow-from.ts utilities provide logic to verify if a specific sender or group is permitted to interact with the agent. This ties directly into Security policies, preventing unauthorized access before a session is even initialized.
Session Routing
Incoming messages are routed to specific sessions based on their origin:
- Direct Messages (DMs): Usually routed to a per-sender session.
- Group Chats: Messages are routed to a session keyed by the group ID.
- Thread Binding:
thread-bindings-policy.tsdetermines if a message should stay within an existing session or trigger the creation of a child session.
Channel-Specific Auth
Authentication is delegated to the individual plugins through the ChannelAuthAdapter. Each platform handles its own credential requirements:
- Bot Tokens: Simple token-based auth (Telegram, Discord).
- OAuth: Flow-based authentication for user-level access (Slack, Matrix).
- QR Code Pairing: Used by platforms like WhatsApp or Signal to link an existing account.
The ChannelSetupAdapter provides a standardized ChannelSetupInput bag containing fields for botToken, appToken, privateKey, and more, which are then stored in the system's secure configuration.
Relevance to Luna
The OpenClaw channel system provides a blueprint for expanding Luna beyond its current CLI-only interface.
Key lessons for Channels:
- Establish a Rich Normalized Type: Before adding a second channel, Luna should define a robust internal message format. This prevents the core logic from becoming littered with "if platform is Discord" checks.
- Abstract Outbound Routing: By defining a common
ChannelOutboundAdapter, Luna can send messages to any platform using a unified API, even if the underlying delivery mechanism (WebSocket, HTTP POST, CLI print) varies wildly.