using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.MLTasks.Settings; using BotSharp.Abstraction.Settings; namespace BotSharp.Core.Infrastructures; public class LlmProviderService : ILlmProviderService { private readonly IServiceProvider _services; private readonly ILogger _logger; public LlmProviderService(IServiceProvider services, ILogger logger) { _services = services; _logger = logger; } public List GetProviders() { var providers = new List(); var services1 = _services.GetServices(); providers.AddRange(services1 .Where(x => GetProviderModels(x.Provider).Any()) .Select(x => x.Provider)); var services2 = _services.GetServices(); providers.AddRange(services2 .Where(x => GetProviderModels(x.Provider).Any()) .Select(x => x.Provider)); var services3 = _services.GetServices(); providers.AddRange(services3 .Where(x => GetProviderModels(x.Provider).Any()) .Select(x => x.Provider)); return providers.Distinct().ToList(); } public List GetProviderModels(string provider) { var settingService = _services.GetRequiredService(); return settingService.Bind>($"LlmProviders") .FirstOrDefault(x => x.Provider.Equals(provider)) ?.Models ?? new List(); } public LlmModelSetting GetProviderModel(string provider, string id, bool? multiModal = null, bool realTime = false, bool imageGenerate = false) { var models = GetProviderModels(provider) .Where(x => x.Id == id); if (multiModal.HasValue) { models = models.Where(x => x.MultiModal == multiModal); } models = models.Where(x => x.RealTime == realTime); models = models.Where(x => x.ImageGeneration == imageGenerate); var random = new Random(); var index = random.Next(0, models.Count()); var modelSetting = models.ElementAt(index); return modelSetting; } public LlmModelSetting? GetSetting(string provider, string model) { var settings = _services.GetRequiredService>(); var providerSetting = settings.FirstOrDefault(p => p.Provider.Equals(provider, StringComparison.CurrentCultureIgnoreCase)); if (providerSetting == null) { _logger.LogError($"Can't find provider settings for {provider}"); return null; } var modelSetting = providerSetting.Models.FirstOrDefault(m => m.Name.Equals(model, StringComparison.CurrentCultureIgnoreCase)); if (modelSetting == null) { _logger.LogError($"Can't find model settings for {provider}.{model}"); return null; } // load balancing if (!string.IsNullOrEmpty(modelSetting.Group)) { // find the models in the same group var models = providerSetting.Models .Where(m => !string.IsNullOrEmpty(m.Group) && m.Group.Equals(modelSetting.Group, StringComparison.CurrentCultureIgnoreCase)) .ToList(); // pick one model randomly var random = new Random(); var index = random.Next(0, models.Count()); modelSetting = models.ElementAt(index); } return modelSetting; } public List GetLlmConfigs(LlmConfigOptions? options = null) { var settingService = _services.GetRequiredService(); var providers = settingService.Bind>($"LlmProviders"); var configs = new List(); if (providers.IsNullOrEmpty()) return configs; if (options == null) return providers ?? []; foreach (var provider in providers) { var models = provider.Models ?? []; if (options.Type.HasValue) { models = models.Where(x => x.Type == options.Type.Value).ToList(); } if (options.MultiModal.HasValue) { models = models.Where(x => x.MultiModal == options.MultiModal.Value).ToList(); } if (options.ImageGeneration.HasValue) { models = models.Where(x => x.ImageGeneration == options.ImageGeneration.Value).ToList(); } if (options.RealTime.HasValue) { models = models.Where(x => x.RealTime == options.RealTime.Value).ToList(); } if (models.IsNullOrEmpty()) { continue; } provider.Models = models; configs.Add(provider); } return configs; } }