20ba8f99b1
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.
62 lines
2.0 KiB
C#
62 lines
2.0 KiB
C#
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);
|
|
}
|
|
}
|
|
} |