using System.Text.Json; using ToolsServices; namespace Services.Ollama { #region Classes annexes public class ModelConfig { public string Primary { get; set; } = ""; public string Secondary { get; set; } = ""; public string Fallback { get; set; } = ""; } public class ModelsConfiguration { public Dictionary Config { get; set; } = new(); } #endregion #region Classe principale ModelSelector public class ModelSelector { #region Variables private readonly ModelsConfiguration _Models = new(); private string ConfigPath = FichiersInternesService.ParamsModeles; #endregion #region Constructeur public ModelSelector() { if (!File.Exists(ConfigPath)) { CreateConfig(); } var json = File.ReadAllText(ConfigPath); _Models = JsonSerializer.Deserialize( json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true } ) ?? new ModelsConfiguration(); } #endregion #region Méthodes publiques public bool SaveConfig(string useCase, ModelConfig models) { LoggerService.LogInfo($"ModelSelector.SaveConfig pour le cas d'usage '{useCase}'"); try { if (_Models.Config.ContainsKey(useCase)) { _Models.Config[useCase].Primary = models.Primary; _Models.Config[useCase].Secondary = models.Secondary; _Models.Config[useCase].Fallback = models.Fallback; } else { _Models.Config[useCase] = new ModelConfig { Primary = models.Primary, Secondary = models.Secondary, Fallback = models.Fallback }; } ModelsConfiguration config = new ModelsConfiguration { Config = _Models.Config }; var json = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(ConfigPath, json); return true; } catch (Exception ex) { LoggerService.LogError($"Échec de la sauvegarde de la configuration des modèles du cas d'usage {useCase} : {ex.Message}"); return false; } } public IEnumerable GetModelsForUseCase(string useCase) { LoggerService.LogInfo($"ModelSelector.GetModelsForUseCase pour le cas d'usage : '{useCase}'"); try { if (!_Models.Config.TryGetValue(useCase, out var config)) throw new Exception($"Cas d'usage '{useCase}' introuvable dans la config."); var allModels = new List(); if (config.Primary != null && config.Primary != "") allModels.Add(config.Primary); if (config.Secondary != null && config.Secondary != "") allModels.Add(config.Secondary); if (config.Fallback != null && config.Fallback != "") allModels.Add(config.Fallback); return allModels; } catch (Exception ex) { LoggerService.LogError($"GetModelsForUseCase: {ex.Message}"); return new List(); } } #endregion #region Méthodes privées private void CreateConfig() { var txt = """ { "Config": { "LLM": { "Primary": "thewindmom/hermes-3-llama-3.1-8b:latest", "Secondary": "gemma3:12b", "Fallback": "deepseek-coder-v2:16b" }, "RAG": { "Primary": "gemma3:12b-it-qat", "Secondary": "llama3-chatqa:8b", "Fallback": "phi4-mini:latest" }, "Resume_Documents": { "Primary": "gemma3:12b-it-qat", "Secondary": "llama3-chatqa:8b", "Fallback": "phi4:latest" }, "Interpretation_Images": { "Primary": "llava-llama3:latest", "Secondary": "llava:7b", "Fallback": "" }, "Prompt_Generation_Fooocus": { "Primary": "openchat:latest", "Secondary": "gemma3:12b", "Fallback": "phi4-mini:latest" }, "Analyse_Mails": { "Primary": "thewindmom/hermes-3-llama-3.1-8b:latest", "Secondary": "gemma3:12b-it-qat", "Fallback": "phi4:latest" }, "Analyse_CV_Mission": { "Primary": "phi4:latest", "Secondary": "gemma3:27b", "Fallback": "llama3-chatqa:8b" }, "Pdf_To_Xml": { "Primary": "gemma3:12b-it-qat", "Secondary": "phi4-mini:latest", "Fallback": "" } } } """; TxtService.CreateTextFile(ConfigPath, txt); } #endregion } #endregion }