From 7c049fc435962172643e76302978b44a791bb2f0 Mon Sep 17 00:00:00 2001 From: Andrey Kondratov <22258361+andrey-kondratov@users.noreply.github.com> Date: Tue, 20 Aug 2024 13:51:53 +0300 Subject: [PATCH] Minor refactoring here and there. --- src/PillsBot/PillsBot.Server/BotService.cs | 102 +++++------ .../PillsBot.Server/Chat/IChatClient.cs | 11 -- .../Chat/Interfaces/IChatClient.cs | 10 ++ .../Chat/TelegramChatClient.cs | 170 +++++++++--------- .../Configuration/AIOptions.cs | 33 ++-- .../Configuration/PillsBotOptions.cs | 13 +- .../Configuration/ReminderOptions.cs | 13 +- .../ServiceCollectionExtensions.cs | 76 ++++---- .../Configuration/TelegramOptions.cs | 7 +- .../Extensions/TypeExtensions.cs | 8 + .../{ => Interfaces}/IMessagesRepository.cs | 0 src/PillsBot/PillsBot.Server/Program.cs | 69 ++++--- .../AzureOpenAIMessageProvider.cs | 1 - .../ConfigurationMessageProvider.cs | 1 - .../{ => Interfaces}/IMessageProvider.cs | 0 15 files changed, 252 insertions(+), 262 deletions(-) delete mode 100644 src/PillsBot/PillsBot.Server/Chat/IChatClient.cs create mode 100644 src/PillsBot/PillsBot.Server/Chat/Interfaces/IChatClient.cs create mode 100644 src/PillsBot/PillsBot.Server/Extensions/TypeExtensions.cs rename src/PillsBot/PillsBot.Server/Persistence/{ => Interfaces}/IMessagesRepository.cs (100%) rename src/PillsBot/PillsBot.Server/TextGeneration/{ => Interfaces}/IMessageProvider.cs (100%) diff --git a/src/PillsBot/PillsBot.Server/BotService.cs b/src/PillsBot/PillsBot.Server/BotService.cs index 7f93364..b49c9c5 100644 --- a/src/PillsBot/PillsBot.Server/BotService.cs +++ b/src/PillsBot/PillsBot.Server/BotService.cs @@ -5,78 +5,74 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using PillsBot.Server.Chat; -using PillsBot.Server.Configuration; using PillsBot.Server.TextGeneration; -namespace PillsBot.Server +namespace PillsBot.Server; + +internal class BotService(ILogger logger, IChatClient chatClient, + IOptions options, IServiceProvider serviceProvider) : BackgroundService { - internal class BotService(ILogger logger, IChatClient chatClient, - IOptions options, IServiceProvider serviceProvider) - : BackgroundService + private readonly ILogger _logger = logger; + private readonly IChatClient _chatClient = chatClient; + private readonly PillsBotOptions _options = options.Value; + private readonly IServiceProvider _serviceProvider = serviceProvider; + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - private readonly ILogger _logger = logger; - private readonly IChatClient _chatClient = chatClient; - private readonly PillsBotOptions _options = options.Value; - private readonly IServiceProvider _serviceProvider = serviceProvider; + _logger.LogInformation("Starting bot version {Version}.", typeof(BotService).GetAssemblyVersionString()); - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + try { - _logger.LogInformation("Starting bot..."); - - try - { - await _chatClient.Start(stoppingToken); - } - catch (Exception exception) - { - _logger.LogError(exception, "Failed to start the chat client."); - return; - } + await _chatClient.Start(stoppingToken); + } + catch (Exception exception) + { + _logger.LogError(exception, "Failed to start the chat client."); + return; + } - _logger.LogInformation("Bot started."); + _logger.LogInformation("Bot started."); - DateTime begins = _options.Reminder.Begins; - TimeSpan interval = _options.Reminder.Interval; + DateTime begins = _options.Reminder.Begins; + TimeSpan interval = _options.Reminder.Interval; - DateTime next = GetNext(begins, interval); - _logger.LogInformation("Next reminder comes off at {Next}", next); + DateTime next = GetNext(begins, interval); + _logger.LogInformation("Next reminder comes off at {Next}", next); - while (!stoppingToken.IsCancellationRequested) + while (!stoppingToken.IsCancellationRequested) + { + if (next <= DateTime.Now) { - if (next <= DateTime.Now) - { - await using AsyncServiceScope scope = _serviceProvider.CreateAsyncScope(); - - IMessageProvider messageProvider = scope.ServiceProvider.GetRequiredService(); - (string reminder, string button, string appreciation) = await messageProvider.GetMessage(stoppingToken); - await _chatClient.Notify(reminder, button, appreciation, stoppingToken); + await using AsyncServiceScope scope = _serviceProvider.CreateAsyncScope(); - next = GetNext(begins, interval); - _logger.LogInformation("Next reminder comes off at {Next}", next); - } + IMessageProvider messageProvider = scope.ServiceProvider.GetRequiredService(); + (string reminder, string button, string appreciation) = await messageProvider.GetMessage(stoppingToken); + await _chatClient.Notify(reminder, button, appreciation, stoppingToken); - await Task.Delay(1000, stoppingToken); + next = GetNext(begins, interval); + _logger.LogInformation("Next reminder comes off at {Next}", next); } - _logger.LogInformation("Bot stopped."); + await Task.Delay(1000, stoppingToken); } - private static DateTime GetNext(DateTime begins, TimeSpan interval) - { - DateTime now = DateTime.Now; - if (now < begins) - { - return begins; - } + _logger.LogInformation("Bot stopped."); + } - DateTime current = begins; - while (current < now) - { - current = current.Add(interval); - } + private static DateTime GetNext(DateTime begins, TimeSpan interval) + { + DateTime now = DateTime.Now; + if (now < begins) + { + return begins; + } - return current; + DateTime current = begins; + while (current < now) + { + current = current.Add(interval); } + + return current; } } diff --git a/src/PillsBot/PillsBot.Server/Chat/IChatClient.cs b/src/PillsBot/PillsBot.Server/Chat/IChatClient.cs deleted file mode 100644 index 11d4ee2..0000000 --- a/src/PillsBot/PillsBot.Server/Chat/IChatClient.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; - -namespace PillsBot.Server.Chat -{ - internal interface IChatClient - { - Task Start(CancellationToken cancellationToken = default); - Task Notify(string reminder, string button, string appreciation, CancellationToken cancellationToken = default); - } -} diff --git a/src/PillsBot/PillsBot.Server/Chat/Interfaces/IChatClient.cs b/src/PillsBot/PillsBot.Server/Chat/Interfaces/IChatClient.cs new file mode 100644 index 0000000..c26ae9e --- /dev/null +++ b/src/PillsBot/PillsBot.Server/Chat/Interfaces/IChatClient.cs @@ -0,0 +1,10 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace PillsBot.Server; + +internal interface IChatClient +{ + Task Start(CancellationToken cancellationToken = default); + Task Notify(string reminder, string button, string appreciation, CancellationToken cancellationToken = default); +} diff --git a/src/PillsBot/PillsBot.Server/Chat/TelegramChatClient.cs b/src/PillsBot/PillsBot.Server/Chat/TelegramChatClient.cs index 880c0b0..aa9a5f8 100644 --- a/src/PillsBot/PillsBot.Server/Chat/TelegramChatClient.cs +++ b/src/PillsBot/PillsBot.Server/Chat/TelegramChatClient.cs @@ -4,120 +4,118 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using PillsBot.Server.Configuration; using Telegram.Bot; using Telegram.Bot.Polling; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; -namespace PillsBot.Server.Chat +namespace PillsBot.Server; + +internal class TelegramChatClient(ILogger logger, IOptions options) + : IChatClient, IUpdateHandler { - internal class TelegramChatClient(ILogger logger, IOptions options) - : IChatClient, IUpdateHandler + private static readonly ReceiverOptions ReceiverOptions = new() { - private static readonly ReceiverOptions ReceiverOptions = new() - { - AllowedUpdates = [UpdateType.Message, UpdateType.CallbackQuery] - }; + AllowedUpdates = [UpdateType.Message, UpdateType.CallbackQuery] + }; - private readonly ILogger _logger = logger; - private readonly PillsBotOptions _options = options.Value; - private readonly TelegramBotClient _client = new(options.Value.Telegram?.ApiToken ?? throw new InvalidOperationException("Missing Telegram API token.")); + private readonly ILogger _logger = logger; + private readonly PillsBotOptions _options = options.Value; + private readonly TelegramBotClient _client = new(options.Value.Telegram?.ApiToken ?? throw new InvalidOperationException("Missing Telegram API token.")); - public async Task Start(CancellationToken cancellationToken = default) + public async Task Start(CancellationToken cancellationToken = default) + { + bool valid = await _client.TestApiAsync(cancellationToken); + if (!valid) { - bool valid = await _client.TestApiAsync(cancellationToken); - if (!valid) - { - throw new InvalidOperationException("Telegram token validation failed."); - } - - // webhooks not supported - WebhookInfo webhookInfo = await _client.GetWebhookInfoAsync(cancellationToken); - if (!string.IsNullOrEmpty(webhookInfo.Url)) - { - _logger.LogWarning("A webhook is set up on the server. Deleting..."); - await _client.DeleteWebhookAsync(true, cancellationToken); - } - - _client.StartReceiving(this, ReceiverOptions, cancellationToken); - _logger.LogInformation("Started receiving updates."); + throw new InvalidOperationException("Telegram token validation failed."); } - public async Task Notify(string reminder, string button, string appreciation, CancellationToken cancellationToken = default) + // webhooks not supported + WebhookInfo webhookInfo = await _client.GetWebhookInfoAsync(cancellationToken); + if (!string.IsNullOrEmpty(webhookInfo.Url)) { - ChatId chatId = _options.Telegram?.ChatId ?? - throw new InvalidOperationException("Chat id not configured"); + _logger.LogWarning("A webhook is set up on the server. Deleting..."); + await _client.DeleteWebhookAsync(true, cancellationToken); + } - IReplyMarkup replyMarkup = GetReplyMarkup(button, appreciation); + _client.StartReceiving(this, ReceiverOptions, cancellationToken); + _logger.LogInformation("Started receiving updates."); + } - _logger.LogInformation("Sending message: {Message} to chat {ChatId}", reminder, chatId); - await _client.SendTextMessageAsync(chatId, reminder, replyMarkup: replyMarkup, - cancellationToken: cancellationToken); + public async Task Notify(string reminder, string button, string appreciation, CancellationToken cancellationToken = default) + { + ChatId chatId = _options.Telegram?.ChatId ?? + throw new InvalidOperationException("Chat id not configured"); - _logger.LogInformation("Message sent."); - } + IReplyMarkup replyMarkup = GetReplyMarkup(button, appreciation); - public Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, - CancellationToken cancellationToken) - { - return update.Type switch - { - UpdateType.CallbackQuery => OnCallbackQuery(update.CallbackQuery, cancellationToken), - UpdateType.Message => OnClientMessage(update.Message), - _ => throw new InvalidEnumArgumentException("UpdateType", (int)update.Type, typeof(UpdateType)) - }; - } + _logger.LogInformation("Sending message: {Message} to chat {ChatId}", reminder, chatId); + await _client.SendTextMessageAsync(chatId, reminder, replyMarkup: replyMarkup, + cancellationToken: cancellationToken); + + _logger.LogInformation("Message sent."); + } - public Task HandlePollingErrorAsync(ITelegramBotClient botClient, Exception exception, - CancellationToken cancellationToken) + public Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, + CancellationToken cancellationToken) + { + return update.Type switch { - _logger.LogError(exception, "Polling error."); - return Task.CompletedTask; - } + UpdateType.CallbackQuery => OnCallbackQuery(update.CallbackQuery, cancellationToken), + UpdateType.Message => OnClientMessage(update.Message), + _ => throw new InvalidEnumArgumentException("UpdateType", (int)update.Type, typeof(UpdateType)) + }; + } + + public Task HandlePollingErrorAsync(ITelegramBotClient botClient, Exception exception, + CancellationToken cancellationToken) + { + _logger.LogError(exception, "Polling error."); + return Task.CompletedTask; + } - private async Task OnCallbackQuery(CallbackQuery? query, CancellationToken cancellationToken) + private async Task OnCallbackQuery(CallbackQuery? query, CancellationToken cancellationToken) + { + _logger.LogTrace("A callback query received: {@CallbackQuery}", query); + + if (query?.Message is null) { - _logger.LogTrace("A callback query received: {@CallbackQuery}", query); - - if (query?.Message is null) - { - _logger.LogWarning("Callback query message was empty. Enable trace log level to see the details."); - return; - } - - long chatId = query.Message.Chat.Id; - if (chatId != _options.Telegram!.ChatId) - { - _logger.LogWarning("Unexpected chat id in callback query: {@CallbackQuery}", query); - return; - } - - // fire message removal - await _client.DeleteMessageAsync(chatId, query.Message.MessageId, cancellationToken); - - // fire callback - await _client.AnswerCallbackQueryAsync(query.Id, query.Data, cancellationToken: cancellationToken); + _logger.LogWarning("Callback query message was empty. Enable trace log level to see the details."); + return; } - private Task OnClientMessage(Message? message) + long chatId = query.Message.Chat.Id; + if (chatId != _options.Telegram!.ChatId) { - _logger.LogInformation("A message received: {@Message}", message); - return Task.CompletedTask; + _logger.LogWarning("Unexpected chat id in callback query: {@CallbackQuery}", query); + return; } - private InlineKeyboardMarkup GetReplyMarkup(string button, string appreciation) + // fire message removal + await _client.DeleteMessageAsync(chatId, query.Message.MessageId, cancellationToken); + + // fire callback + await _client.AnswerCallbackQueryAsync(query.Id, query.Data, cancellationToken: cancellationToken); + } + + private Task OnClientMessage(Message? message) + { + _logger.LogInformation("A message received: {@Message}", message); + return Task.CompletedTask; + } + + private InlineKeyboardMarkup GetReplyMarkup(string button, string appreciation) + { + if (appreciation.Length > 64) { - if (appreciation.Length > 64) - { - _logger.LogWarning("Appreciation message \"{Appreciation}\" length is greater than 64. Will truncate.", appreciation); - appreciation = appreciation[..64]; - } - - var inlineKeyboardButton = InlineKeyboardButton.WithCallbackData(button, appreciation); - var result = new InlineKeyboardMarkup(inlineKeyboardButton); - return result; + _logger.LogWarning("Appreciation message \"{Appreciation}\" length is greater than 64. Will truncate.", appreciation); + appreciation = appreciation[..64]; } + + var inlineKeyboardButton = InlineKeyboardButton.WithCallbackData(button, appreciation); + var result = new InlineKeyboardMarkup(inlineKeyboardButton); + return result; } } diff --git a/src/PillsBot/PillsBot.Server/Configuration/AIOptions.cs b/src/PillsBot/PillsBot.Server/Configuration/AIOptions.cs index e43a4ae..2e1d076 100644 --- a/src/PillsBot/PillsBot.Server/Configuration/AIOptions.cs +++ b/src/PillsBot/PillsBot.Server/Configuration/AIOptions.cs @@ -1,23 +1,22 @@ using Microsoft.Extensions.Logging; -namespace PillsBot.Server.Configuration +namespace PillsBot.Server; + +public class AIOptions { - public class AIOptions - { - public bool Enabled { get; set; } = false; - public string Languages { get; set; } = "en-US"; - public string PetNames { get; set; } = "unknown"; - public string PetGender { get; set; } = "unknown"; - public LogLevel LogLevel { get; set; } = LogLevel.Warning; - public AzureOpenAIOptions? Azure { get; set; } = null; - public int ChoicesCount { get; set; } = 20; - public int MaxTokens { get; set; } = 1000; + public bool Enabled { get; set; } = false; + public string Languages { get; set; } = "en-US"; + public string PetNames { get; set; } = "unknown"; + public string PetGender { get; set; } = "unknown"; + public LogLevel LogLevel { get; set; } = LogLevel.Warning; + public AzureOpenAIOptions? Azure { get; set; } = null; + public int ChoicesCount { get; set; } = 20; + public int MaxTokens { get; set; } = 1000; - public class AzureOpenAIOptions - { - public required string Endpoint { get; set; } - public required string Key { get; set; } - public required string DeploymentName { get; set; } - } + public class AzureOpenAIOptions + { + public required string Endpoint { get; set; } + public required string Key { get; set; } + public required string DeploymentName { get; set; } } } diff --git a/src/PillsBot/PillsBot.Server/Configuration/PillsBotOptions.cs b/src/PillsBot/PillsBot.Server/Configuration/PillsBotOptions.cs index fdbd7d8..0e0aad4 100644 --- a/src/PillsBot/PillsBot.Server/Configuration/PillsBotOptions.cs +++ b/src/PillsBot/PillsBot.Server/Configuration/PillsBotOptions.cs @@ -1,9 +1,8 @@ -namespace PillsBot.Server.Configuration +namespace PillsBot.Server; + +public class PillsBotOptions { - public class PillsBotOptions - { - public TelegramOptions? Telegram { get; set; } - public ReminderOptions Reminder { get; set; } = new(); - public AIOptions AI { get; set; } = new(); - } + public TelegramOptions? Telegram { get; set; } + public ReminderOptions Reminder { get; set; } = new(); + public AIOptions AI { get; set; } = new(); } diff --git a/src/PillsBot/PillsBot.Server/Configuration/ReminderOptions.cs b/src/PillsBot/PillsBot.Server/Configuration/ReminderOptions.cs index e9b9f49..11eecee 100644 --- a/src/PillsBot/PillsBot.Server/Configuration/ReminderOptions.cs +++ b/src/PillsBot/PillsBot.Server/Configuration/ReminderOptions.cs @@ -1,11 +1,10 @@ using System; -namespace PillsBot.Server.Configuration +namespace PillsBot.Server; + +public class ReminderOptions { - public class ReminderOptions - { - public DateTime Begins { get; set; } = DateTime.Now.AddSeconds(5); - public TimeSpan Interval { get; set; } = TimeSpan.FromDays(.5); - public string Message { get; set; } = "Pills time!"; - } + public DateTime Begins { get; set; } = DateTime.Now.AddSeconds(5); + public TimeSpan Interval { get; set; } = TimeSpan.FromDays(.5); + public string Message { get; set; } = "Pills time!"; } diff --git a/src/PillsBot/PillsBot.Server/Configuration/ServiceCollectionExtensions.cs b/src/PillsBot/PillsBot.Server/Configuration/ServiceCollectionExtensions.cs index cda8494..1e6583d 100644 --- a/src/PillsBot/PillsBot.Server/Configuration/ServiceCollectionExtensions.cs +++ b/src/PillsBot/PillsBot.Server/Configuration/ServiceCollectionExtensions.cs @@ -3,53 +3,51 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; -using PillsBot.Server.Chat; using PillsBot.Server.Persistence; using PillsBot.Server.TextGeneration; -namespace PillsBot.Server.Configuration +namespace PillsBot.Server; + +public static class ServiceCollectionExtensions { - public static class ServiceCollectionExtensions + public static IServiceCollection AddPillsBot(this IServiceCollection services, IConfiguration configuration) { - public static IServiceCollection AddPillsBot(this IServiceCollection services, IConfiguration configuration) + IConfigurationSection configurationSection = configuration.GetSection("PillsBot"); + PillsBotOptions options = new(); + configurationSection.Bind(options); + + services + .AddOptions() + .Configure(configurationSection); + + services + .AddTransient() + .AddHostedService(); + + if (!options.AI.Enabled) { - IConfigurationSection configurationSection = configuration.GetSection("PillsBot"); - PillsBotOptions options = new(); - configurationSection.Bind(options); - - services - .AddOptions() - .Configure(configurationSection); - - services - .AddTransient() - .AddHostedService(); - - if (!options.AI.Enabled) - { - services.AddTransient(); - - return services; - } - - if (options.AI.Azure is null) - { - throw new InvalidOperationException("Missing Azure AI configuration."); - } - - services - .AddTransient() - .AddScoped() - .AddKernel() - .AddAzureOpenAIChatCompletion(options.AI.Azure.DeploymentName, options.AI.Azure.Endpoint, options.AI.Azure.Key); - - services - .AddDbContext(options => options - .UseNpgsql(configuration.GetConnectionString("PillsBotDbContext")) - .UseSnakeCaseNamingConvention()) - .AddScoped(); + services.AddTransient(); return services; } + + if (options.AI.Azure is null) + { + throw new InvalidOperationException("Missing Azure AI configuration."); + } + + services + .AddTransient() + .AddScoped() + .AddKernel() + .AddAzureOpenAIChatCompletion(options.AI.Azure.DeploymentName, options.AI.Azure.Endpoint, options.AI.Azure.Key); + + services + .AddDbContext(options => options + .UseNpgsql(configuration.GetConnectionString("PillsBotDbContext")) + .UseSnakeCaseNamingConvention()) + .AddScoped(); + + return services; } } diff --git a/src/PillsBot/PillsBot.Server/Configuration/TelegramOptions.cs b/src/PillsBot/PillsBot.Server/Configuration/TelegramOptions.cs index 5274c9c..28810d5 100644 --- a/src/PillsBot/PillsBot.Server/Configuration/TelegramOptions.cs +++ b/src/PillsBot/PillsBot.Server/Configuration/TelegramOptions.cs @@ -1,4 +1,3 @@ -namespace PillsBot.Server.Configuration -{ - public record TelegramOptions(string? ApiToken, long? ChatId); -} +namespace PillsBot.Server; + +public record TelegramOptions(string? ApiToken, long? ChatId); diff --git a/src/PillsBot/PillsBot.Server/Extensions/TypeExtensions.cs b/src/PillsBot/PillsBot.Server/Extensions/TypeExtensions.cs new file mode 100644 index 0000000..c0a05fe --- /dev/null +++ b/src/PillsBot/PillsBot.Server/Extensions/TypeExtensions.cs @@ -0,0 +1,8 @@ +using System; + +namespace PillsBot.Server; + +internal static class TypeExtensions +{ + public static string GetAssemblyVersionString(this Type type) => type.Assembly.GetName()?.Version?.ToString(3) ?? string.Empty; +} diff --git a/src/PillsBot/PillsBot.Server/Persistence/IMessagesRepository.cs b/src/PillsBot/PillsBot.Server/Persistence/Interfaces/IMessagesRepository.cs similarity index 100% rename from src/PillsBot/PillsBot.Server/Persistence/IMessagesRepository.cs rename to src/PillsBot/PillsBot.Server/Persistence/Interfaces/IMessagesRepository.cs diff --git a/src/PillsBot/PillsBot.Server/Program.cs b/src/PillsBot/PillsBot.Server/Program.cs index cde6f05..6040492 100644 --- a/src/PillsBot/PillsBot.Server/Program.cs +++ b/src/PillsBot/PillsBot.Server/Program.cs @@ -3,48 +3,45 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; -using PillsBot.Server.Configuration; using Serilog; using Serilog.Events; -namespace PillsBot.Server +namespace PillsBot.Server; + +public static class Program { - public static class Program + public static void Main(string[] args) { - public static void Main(string[] args) - { - Log.Logger = new LoggerConfiguration() - .WriteTo.Console() - .CreateBootstrapLogger(); + Log.Logger = new LoggerConfiguration() + .WriteTo.Console() + .CreateBootstrapLogger(); - try - { - Log.Information("Version: {Version}", typeof(Program).Assembly.GetName().Version?.ToString(3)); - CreateHostBuilder(args).Build().Run(); - } - catch (Exception ex) - { - Log.Fatal(ex, "An unhandled exception occurred during bootstrapping"); - } - finally - { - Log.CloseAndFlush(); - } + try + { + CreateHostBuilder(args).Build().Run(); + } + catch (Exception exception) + { + Log.Fatal(exception, "Unhandled error, exiting."); + } + finally + { + Log.CloseAndFlush(); } - - public static IHostBuilder CreateHostBuilder(string[] args) => Host - .CreateDefaultBuilder(args) - .ConfigureServices((context, services) => services - .AddApplicationInsightsTelemetryWorkerService(context.Configuration) - .AddPillsBot(context.Configuration)) - .UseSerilog((context, services, configuration) => configuration - .MinimumLevel.Is(context.HostingEnvironment.IsDevelopment() ? LogEventLevel.Debug : LogEventLevel.Information) - .MinimumLevel.Override("Microsoft.SemanticKernel", (LogEventLevel)services.GetRequiredService>().Value.AI.LogLevel) - .Enrich.FromLogContext() - .Enrich.WithProperty("Environment", context.HostingEnvironment.EnvironmentName) - .Enrich.WithProperty("Version", typeof(Program).Assembly.GetName().Version?.ToString(3), true) - .WriteTo.Console() - .WriteTo.ApplicationInsights(services.GetRequiredService(), - TelemetryConverter.Traces)); } + + public static IHostBuilder CreateHostBuilder(string[] args) => Host + .CreateDefaultBuilder(args) + .ConfigureServices((context, services) => services + .AddApplicationInsightsTelemetryWorkerService(context.Configuration) + .AddPillsBot(context.Configuration)) + .UseSerilog((context, services, configuration) => configuration + .MinimumLevel.Is(context.HostingEnvironment.IsDevelopment() ? LogEventLevel.Debug : LogEventLevel.Information) + .MinimumLevel.Override("Microsoft.SemanticKernel", (LogEventLevel)services.GetRequiredService>().Value.AI.LogLevel) + .Enrich.FromLogContext() + .Enrich.WithProperty("Environment", context.HostingEnvironment.EnvironmentName) + .Enrich.WithProperty("Version", typeof(Program).GetAssemblyVersionString(), true) + .WriteTo.Console() + .WriteTo.ApplicationInsights(services.GetRequiredService(), + TelemetryConverter.Traces)); } diff --git a/src/PillsBot/PillsBot.Server/TextGeneration/AzureOpenAIMessageProvider.cs b/src/PillsBot/PillsBot.Server/TextGeneration/AzureOpenAIMessageProvider.cs index 1ab6618..097f529 100644 --- a/src/PillsBot/PillsBot.Server/TextGeneration/AzureOpenAIMessageProvider.cs +++ b/src/PillsBot/PillsBot.Server/TextGeneration/AzureOpenAIMessageProvider.cs @@ -11,7 +11,6 @@ using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.SemanticKernel.Connectors.OpenAI; -using PillsBot.Server.Configuration; using PillsBot.Server.Persistence; using Polly; using Polly.Retry; diff --git a/src/PillsBot/PillsBot.Server/TextGeneration/ConfigurationMessageProvider.cs b/src/PillsBot/PillsBot.Server/TextGeneration/ConfigurationMessageProvider.cs index 39d8fb6..2e160d5 100644 --- a/src/PillsBot/PillsBot.Server/TextGeneration/ConfigurationMessageProvider.cs +++ b/src/PillsBot/PillsBot.Server/TextGeneration/ConfigurationMessageProvider.cs @@ -1,7 +1,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Options; -using PillsBot.Server.Configuration; namespace PillsBot.Server.TextGeneration; diff --git a/src/PillsBot/PillsBot.Server/TextGeneration/IMessageProvider.cs b/src/PillsBot/PillsBot.Server/TextGeneration/Interfaces/IMessageProvider.cs similarity index 100% rename from src/PillsBot/PillsBot.Server/TextGeneration/IMessageProvider.cs rename to src/PillsBot/PillsBot.Server/TextGeneration/Interfaces/IMessageProvider.cs