add comment

This commit is contained in:
Leonid Pershin
2025-10-15 20:32:27 +03:00
parent 51a8157803
commit ecc518701c
5 changed files with 203 additions and 23 deletions

View File

@@ -1,9 +1,23 @@
namespace ChatBot.Models.Configuration namespace ChatBot.Models.Configuration
{ {
/// <summary>
/// Основные настройки приложения
/// </summary>
public class AppSettings public class AppSettings
{ {
/// <summary>
/// Настройки Telegram бота
/// </summary>
public TelegramBotSettings TelegramBot { get; set; } = new(); public TelegramBotSettings TelegramBot { get; set; } = new();
/// <summary>
/// Настройки OpenRouter API
/// </summary>
public OpenRouterSettings OpenRouter { get; set; } = new(); public OpenRouterSettings OpenRouter { get; set; } = new();
/// <summary>
/// Настройки логирования Serilog
/// </summary>
public SerilogSettings Serilog { get; set; } = new(); public SerilogSettings Serilog { get; set; } = new();
} }
} }

View File

@@ -1,13 +1,43 @@
namespace ChatBot.Models.Configuration namespace ChatBot.Models.Configuration
{ {
/// <summary>
/// Настройки OpenRouter API
/// </summary>
public class OpenRouterSettings public class OpenRouterSettings
{ {
/// <summary>
/// API токен для аутентификации в OpenRouter
/// </summary>
public string Token { get; set; } = string.Empty; public string Token { get; set; } = string.Empty;
/// <summary>
/// URL эндпоинта OpenRouter API
/// </summary>
public string Url { get; set; } = string.Empty; public string Url { get; set; } = string.Empty;
/// <summary>
/// Список доступных моделей ИИ
/// </summary>
public List<string> AvailableModels { get; set; } = new(); public List<string> AvailableModels { get; set; } = new();
/// <summary>
/// Модель по умолчанию для генерации ответов
/// </summary>
public string DefaultModel { get; set; } = string.Empty; public string DefaultModel { get; set; } = string.Empty;
/// <summary>
/// Максимальное количество повторных попыток при ошибках
/// </summary>
public int MaxRetries { get; set; } = 3; public int MaxRetries { get; set; } = 3;
/// <summary>
/// Максимальное количество токенов в ответе
/// </summary>
public int MaxTokens { get; set; } = 1000; public int MaxTokens { get; set; } = 1000;
/// <summary>
/// Температура генерации (креативность ответов от 0.0 до 2.0)
/// </summary>
public double Temperature { get; set; } = 0.7; public double Temperature { get; set; } = 0.7;
} }
} }

View File

@@ -1,22 +1,60 @@
namespace ChatBot.Models.Configuration namespace ChatBot.Models.Configuration
{ {
/// <summary>
/// Настройки логирования Serilog
/// </summary>
public class SerilogSettings public class SerilogSettings
{ {
/// <summary>
/// Список используемых sink'ов для логирования
/// </summary>
public List<string> Using { get; set; } = new(); public List<string> Using { get; set; } = new();
/// <summary>
/// Настройки минимального уровня логирования
/// </summary>
public MinimumLevelSettings MinimumLevel { get; set; } = new(); public MinimumLevelSettings MinimumLevel { get; set; } = new();
/// <summary>
/// Настройки получателей логов (куда писать логи)
/// </summary>
public List<WriteToSettings> WriteTo { get; set; } = new(); public List<WriteToSettings> WriteTo { get; set; } = new();
/// <summary>
/// Список обогатителей логов (дополнительная информация)
/// </summary>
public List<string> Enrich { get; set; } = new(); public List<string> Enrich { get; set; } = new();
} }
/// <summary>
/// Настройки минимального уровня логирования
/// </summary>
public class MinimumLevelSettings public class MinimumLevelSettings
{ {
/// <summary>
/// Уровень логирования по умолчанию
/// </summary>
public string Default { get; set; } = "Information"; public string Default { get; set; } = "Information";
/// <summary>
/// Переопределения уровня логирования для конкретных пространств имен
/// </summary>
public Dictionary<string, string> Override { get; set; } = new(); public Dictionary<string, string> Override { get; set; } = new();
} }
/// <summary>
/// Настройки получателя логов
/// </summary>
public class WriteToSettings public class WriteToSettings
{ {
/// <summary>
/// Название sink'а для записи логов
/// </summary>
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
/// <summary>
/// Аргументы для настройки sink'а
/// </summary>
public Dictionary<string, object> Args { get; set; } = new(); public Dictionary<string, object> Args { get; set; } = new();
} }
} }

View File

@@ -1,7 +1,13 @@
namespace ChatBot.Models.Configuration namespace ChatBot.Models.Configuration
{ {
/// <summary>
/// Настройки Telegram бота
/// </summary>
public class TelegramBotSettings public class TelegramBotSettings
{ {
/// <summary>
/// Токен бота для работы с Telegram API
/// </summary>
public string BotToken { get; set; } = string.Empty; public string BotToken { get; set; } = string.Empty;
} }
} }

View File

@@ -2,31 +2,46 @@ using ChatBot.Models.Configuration;
namespace ChatBot.Models.Configuration.Validators namespace ChatBot.Models.Configuration.Validators
{ {
/// <summary>
/// Валидатор конфигурации приложения
/// </summary>
public static class ConfigurationValidator public static class ConfigurationValidator
{ {
/// <summary>
/// Валидирует все настройки приложения
/// </summary>
/// <param name="settings">Настройки приложения</param>
/// <returns>Результат валидации</returns>
public static ValidationResult ValidateAppSettings(AppSettings settings) public static ValidationResult ValidateAppSettings(AppSettings settings)
{ {
var errors = new List<string>(); var errors = new List<string>();
// Валидация TelegramBot // Валидация настроек Telegram бота
var telegramResult = ValidateTelegramBotSettings(settings.TelegramBot); var telegramResult = ValidateTelegramBotSettings(settings.TelegramBot);
errors.AddRange(telegramResult.Errors); errors.AddRange(telegramResult.Errors);
// Валидация OpenRouter // Валидация настроек OpenRouter
var openRouterResult = ValidateOpenRouterSettings(settings.OpenRouter); var openRouterResult = ValidateOpenRouterSettings(settings.OpenRouter);
errors.AddRange(openRouterResult.Errors); errors.AddRange(openRouterResult.Errors);
return new ValidationResult { IsValid = !errors.Any(), Errors = errors }; return new ValidationResult { IsValid = !errors.Any(), Errors = errors };
} }
/// <summary>
/// Валидирует настройки Telegram бота
/// </summary>
/// <param name="settings">Настройки Telegram бота</param>
/// <returns>Результат валидации</returns>
public static ValidationResult ValidateTelegramBotSettings(TelegramBotSettings settings) public static ValidationResult ValidateTelegramBotSettings(TelegramBotSettings settings)
{ {
var errors = new List<string>(); var errors = new List<string>();
// Проверка наличия токена бота
if (string.IsNullOrWhiteSpace(settings.BotToken)) if (string.IsNullOrWhiteSpace(settings.BotToken))
{ {
errors.Add("TelegramBot:BotToken is required"); errors.Add("TelegramBot:BotToken is required");
} }
// Проверка формата токена (должен содержать ':' или начинаться с 'bot')
else if ( else if (
!settings.BotToken.StartsWith("bot", StringComparison.OrdinalIgnoreCase) !settings.BotToken.StartsWith("bot", StringComparison.OrdinalIgnoreCase)
&& !settings.BotToken.Contains(":") && !settings.BotToken.Contains(":")
@@ -40,79 +55,156 @@ namespace ChatBot.Models.Configuration.Validators
return new ValidationResult { IsValid = !errors.Any(), Errors = errors }; return new ValidationResult { IsValid = !errors.Any(), Errors = errors };
} }
/// <summary>
/// Валидирует настройки OpenRouter
/// </summary>
/// <param name="settings">Настройки OpenRouter</param>
/// <returns>Результат валидации</returns>
public static ValidationResult ValidateOpenRouterSettings(OpenRouterSettings settings) public static ValidationResult ValidateOpenRouterSettings(OpenRouterSettings settings)
{ {
var errors = new List<string>(); var errors = new List<string>();
if (string.IsNullOrWhiteSpace(settings.Token)) // Валидация всех компонентов настроек OpenRouter
ValidateToken(settings.Token, errors);
ValidateUrl(settings.Url, errors);
ValidateAvailableModels(settings.AvailableModels, errors);
ValidateDefaultModel(settings.DefaultModel, settings.AvailableModels, errors);
ValidateNumericSettings(settings, errors);
return new ValidationResult { IsValid = !errors.Any(), Errors = errors };
}
/// <summary>
/// Валидирует токен OpenRouter
/// </summary>
/// <param name="token">Токен для проверки</param>
/// <param name="errors">Список ошибок валидации</param>
private static void ValidateToken(string token, List<string> errors)
{
// Проверка наличия токена
if (string.IsNullOrWhiteSpace(token))
{ {
errors.Add("OpenRouter:Token is required"); errors.Add("OpenRouter:Token is required");
} }
else if (!settings.Token.StartsWith("sk-", StringComparison.OrdinalIgnoreCase)) // Проверка формата токена (должен начинаться с 'sk-')
else if (!token.StartsWith("sk-", StringComparison.OrdinalIgnoreCase))
{ {
errors.Add("OpenRouter:Token appears to be invalid (should start with 'sk-')"); errors.Add("OpenRouter:Token appears to be invalid (should start with 'sk-')");
} }
}
if (string.IsNullOrWhiteSpace(settings.Url)) /// <summary>
/// Валидирует URL OpenRouter
/// </summary>
/// <param name="url">URL для проверки</param>
/// <param name="errors">Список ошибок валидации</param>
private static void ValidateUrl(string url, List<string> errors)
{
// Проверка наличия URL
if (string.IsNullOrWhiteSpace(url))
{ {
errors.Add("OpenRouter:Url is required"); errors.Add("OpenRouter:Url is required");
} }
// Проверка корректности URL (должен быть валидным HTTP/HTTPS URL)
else if ( else if (
!Uri.TryCreate(settings.Url, UriKind.Absolute, out var uri) !Uri.TryCreate(url, UriKind.Absolute, out var uri)
|| (uri.Scheme != "http" && uri.Scheme != "https") || (uri.Scheme != "http" && uri.Scheme != "https")
) )
{ {
errors.Add("OpenRouter:Url must be a valid HTTP/HTTPS URL"); errors.Add("OpenRouter:Url must be a valid HTTP/HTTPS URL");
} }
}
if (settings.AvailableModels == null || !settings.AvailableModels.Any()) /// <summary>
/// Валидирует список доступных моделей
/// </summary>
/// <param name="models">Список моделей для проверки</param>
/// <param name="errors">Список ошибок валидации</param>
private static void ValidateAvailableModels(IEnumerable<string> models, List<string> errors)
{
// Проверка наличия хотя бы одной модели
if (models == null || !models.Any())
{ {
errors.Add("OpenRouter:AvailableModels must contain at least one model"); errors.Add("OpenRouter:AvailableModels must contain at least one model");
} return;
else
{
foreach (var model in settings.AvailableModels)
{
if (string.IsNullOrWhiteSpace(model))
{
errors.Add("OpenRouter:AvailableModels contains empty model name");
}
}
} }
// Проверка на пустые названия моделей
var emptyModels = models.Where(string.IsNullOrWhiteSpace).ToList();
if (emptyModels.Any())
{
errors.Add("OpenRouter:AvailableModels contains empty model name");
}
}
/// <summary>
/// Валидирует модель по умолчанию
/// </summary>
/// <param name="defaultModel">Модель по умолчанию</param>
/// <param name="availableModels">Список доступных моделей</param>
/// <param name="errors">Список ошибок валидации</param>
private static void ValidateDefaultModel(
string defaultModel,
IEnumerable<string> availableModels,
List<string> errors
)
{
// Проверка, что модель по умолчанию присутствует в списке доступных
if ( if (
!string.IsNullOrWhiteSpace(settings.DefaultModel) !string.IsNullOrWhiteSpace(defaultModel)
&& settings.AvailableModels != null && availableModels != null
&& !settings.AvailableModels.Contains(settings.DefaultModel) && !availableModels.Contains(defaultModel)
) )
{ {
errors.Add( errors.Add(
$"OpenRouter:DefaultModel '{settings.DefaultModel}' is not in AvailableModels list" $"OpenRouter:DefaultModel '{defaultModel}' is not in AvailableModels list"
); );
} }
}
/// <summary>
/// Валидирует числовые параметры настроек OpenRouter
/// </summary>
/// <param name="settings">Настройки OpenRouter</param>
/// <param name="errors">Список ошибок валидации</param>
private static void ValidateNumericSettings(
OpenRouterSettings settings,
List<string> errors
)
{
// Проверка количества повторных попыток (1-10)
if (settings.MaxRetries < 1 || settings.MaxRetries > 10) if (settings.MaxRetries < 1 || settings.MaxRetries > 10)
{ {
errors.Add("OpenRouter:MaxRetries must be between 1 and 10"); errors.Add("OpenRouter:MaxRetries must be between 1 and 10");
} }
// Проверка максимального количества токенов (1-100000)
if (settings.MaxTokens < 1 || settings.MaxTokens > 100000) if (settings.MaxTokens < 1 || settings.MaxTokens > 100000)
{ {
errors.Add("OpenRouter:MaxTokens must be between 1 and 100000"); errors.Add("OpenRouter:MaxTokens must be between 1 and 100000");
} }
// Проверка температуры (0.0-2.0)
if (settings.Temperature < 0.0 || settings.Temperature > 2.0) if (settings.Temperature < 0.0 || settings.Temperature > 2.0)
{ {
errors.Add("OpenRouter:Temperature must be between 0.0 and 2.0"); errors.Add("OpenRouter:Temperature must be between 0.0 and 2.0");
} }
return new ValidationResult { IsValid = !errors.Any(), Errors = errors };
} }
} }
/// <summary>
/// Результат валидации конфигурации
/// </summary>
public class ValidationResult public class ValidationResult
{ {
/// <summary>
/// Указывает, прошла ли валидация успешно
/// </summary>
public bool IsValid { get; set; } public bool IsValid { get; set; }
/// <summary>
/// Список ошибок валидации
/// </summary>
public List<string> Errors { get; set; } = new(); public List<string> Errors { get; set; } = new();
} }
} }