# Channels The Channels module provides a unified abstraction for communication platforms like the CLI and Telegram. It handles message transport, while [[Core]] manages AI context and session state. ## Luna.Channels.Abstractions This project defines the contracts and event models for all channel implementations. ### IChannel The primary interface for any communication transport. There is no abstract base class; `IChannel` is the complete contract. ```csharp public interface IChannel : IDisposable { string ChannelId { get; } string ChannelType { get; } string DisplayName { get; } bool IsConnected { get; } event ChannelMessageReceivedEventHandler? MessageReceived; event EventHandler? ConnectionStateChanged; Task SendMessageAsync(ChannelMessage message, CancellationToken ct = default); Task SendStreamingMessageAsync(IAsyncEnumerable messageStream, CancellationToken ct = default); } ``` ### IChannelManager Coordinates registered channels and handles message routing. ```csharp public interface IChannelManager { void RegisterChannel(IChannel channel); void UnregisterChannel(string channelId); IChannel? GetChannel(string channelId); IReadOnlyList GetAllChannels(); event EventHandler? MessageRouted; } ``` ### Supporting Types - **ChannelType**: A static class providing constants like `cli` and `telegram`. - **ChannelMessageReceivedEventHandler**: Delegate for handling incoming messages. `Task ChannelMessageReceivedEventHandler(object? sender, ChannelMessageReceivedEventArgs e)` - **ChannelMessageReceivedEventArgs**: Contains the `Channel`, `Message`, and an `IsHandled` flag. - **ChannelConnectionEventArgs**: Contains the `Channel` and `IsConnected` status. ## Luna.Channels This project contains the concrete management logic and specific channel implementations. ### ChannelManager The `ChannelManager` implements `IChannelManager` and acts as the central hub for message traffic. It injects `ISessionManager` from [[Core]] and `ILogger`. When a channel is registered via `RegisterChannel`, the manager subscribes to its `MessageReceived` event. The `OnMessageReceivedAsync` handler performs the following: 1. Calls `sessionManager.RouteMessagesAsync(message.Content, message.ConversationId, channel.ChannelId)`. 2. Pipes the resulting `IAsyncEnumerable` back to the channel via `channel.SendStreamingMessageAsync`. ### Channel Implementations - [[CLI Channel]] — SignalR-based adapter for the command-line interface. - [[Telegram Channel]] — Telegram Bot API adapter with message splitting and streaming. - [[Web Interface Channel]] — Browser-based chat UI (not yet implemented). ## Routing Flow 1. `Channel.MessageReceived` event triggers. 2. `ChannelManager` catches the event and identifies the sender. 3. Manager calls `SessionManager.RouteMessagesAsync`. 4. `SessionManager` returns an `IAsyncEnumerable`. 5. `ChannelManager` passes this stream to `Channel.SendStreamingMessageAsync`. 6. The channel implementation handles the physical transport of the stream. ## Architecture Decisions - **Separation of Concerns**: `ChannelManager` handles transport and routing. `SessionManager` handles AI context and conversation logic. - **Conversation Scoping**: Sessions are scoped to conversations, not specific channels. This allows for potential cross-channel persistence. - **Unified DTOs**: All message data uses the `ChannelMessage` DTO from `Luna.Shared`. - **Registration**: Channels are registered via the `AddChannels()` DI extension method, following the [[Configuration]] patterns. - **Options Pattern**: Implementations use `IOptions` (e.g., `TelegramOptions`) for configuration. ## Dependencies ### Project References - `Luna.Channels.Abstractions` - `Luna.Configuration` - `Luna.Core.Abstractions` - `Luna.Shared` ### NuGet Packages - `Telegram.Bot` - `Microsoft.Extensions.Hosting.Abstractions` - `Microsoft.Extensions.Logging.Abstractions` ## Adding a New Channel To implement a new channel: 1. Create a class implementing `IChannel`. 2. Ensure it handles both `SendMessageAsync` and `SendStreamingMessageAsync`. 3. Raise `MessageReceived` when the external platform sends a message. 4. Register the channel with `IChannelManager` during startup or via a background adapter (like `TelegramAdapter`).