Add channel system with CLI, Telegram, and Web channel implementations
Define channel abstractions (IChannel, IChannelManager) with event-driven message and connection handling. Implement ChannelManager for multi-channel orchestration, CliChannel for terminal I/O, TelegramChannel with adapter pattern for bot API integration, and WebChannel stub. Includes DI registration and channel type enumeration.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
using System.Collections.Immutable;
|
||||
using Luna.Channels.Abstractions;
|
||||
using Luna.Core.Abstractions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Luna.Channels;
|
||||
|
||||
public class ChannelManager(ISessionManager sessionManager, ILogger<ChannelManager> logger) : IChannelManager
|
||||
{
|
||||
private readonly Dictionary<string, IChannel> channels = new();
|
||||
private readonly Dictionary<string, string> sessionMap = new();
|
||||
|
||||
public event EventHandler<ChannelMessageReceivedEventArgs>? MessageRouted;
|
||||
|
||||
public void RegisterChannel(IChannel channel)
|
||||
{
|
||||
if (!channels.TryAdd(channel.ChannelId, channel))
|
||||
throw new InvalidOperationException($"Channel with id {channel.ChannelId} is already registered.");
|
||||
|
||||
channel.MessageReceived += OnMessageReceivedAsync;
|
||||
}
|
||||
|
||||
public void UnregisterChannel(string channelId)
|
||||
{
|
||||
if (!channels.TryGetValue(channelId, out var channel))
|
||||
return;
|
||||
|
||||
channel.MessageReceived -= OnMessageReceivedAsync;
|
||||
channels.Remove(channelId);
|
||||
}
|
||||
|
||||
public IChannel? GetChannel(string channelId)
|
||||
{
|
||||
channels.TryGetValue(channelId, out var channel);
|
||||
return channel;
|
||||
}
|
||||
|
||||
public IReadOnlyList<IChannel> GetAllChannels()
|
||||
=> channels.Values.ToImmutableList();
|
||||
|
||||
private async Task OnMessageReceivedAsync(object? sender, ChannelMessageReceivedEventArgs args)
|
||||
{
|
||||
if (args.IsHandled)
|
||||
return;
|
||||
|
||||
var channel = args.Channel;
|
||||
var message = args.Message;
|
||||
|
||||
try
|
||||
{
|
||||
var response = sessionManager
|
||||
.RouteMessagesAsync(message.Content, message.ConversationId, channel.ChannelId);
|
||||
|
||||
await channel.SendStreamingMessageAsync(response);
|
||||
MessageRouted?.Invoke(this, args);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
logger.LogError(exception, "Message routing for channel of type {Type} with id {Id} failed", channel.ChannelType, channel.ChannelId);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user