Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

235 lines
10KB

  1. using Services.Fooocus;
  2. using Services.Models;
  3. using Services.ReActAgent;
  4. using System.Text.Json;
  5. using ToolsServices;
  6. using static Services.ReActAgent.ModelsUseCases;
  7. namespace Services
  8. {
  9. public static class ChatService
  10. {
  11. #region Variables
  12. private static string Folder => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Conversations");
  13. private static Services.ReActAgent.ReActAgent _ReActAagent = new();
  14. #endregion
  15. #region Constructeur
  16. static ChatService()
  17. {
  18. LoggerService.LogInfo($"ChatService");
  19. try
  20. {
  21. if (!Directory.Exists(Folder))
  22. {
  23. LoggerService.LogDebug($"ChatService : tentative de création du dossier de conversations : {Folder}");
  24. Directory.CreateDirectory(Folder);
  25. LoggerService.LogInfo($"ChatService : dossier de conversations créé : {Folder}");
  26. }
  27. }
  28. catch (Exception ex)
  29. {
  30. LoggerService.LogError($"ChatService : Erreur : {ex.Message}");
  31. }
  32. }
  33. #endregion
  34. #region Méthodes publiques
  35. public static string GetModeleIA(ModelsUseCases.TypeUseCase useCase)
  36. {
  37. return ReActAgent.ReActAgent.GetModeleIA(useCase);
  38. }
  39. public static IEnumerable<string> GetModelesIA(ModelsUseCases.TypeUseCase useCase)
  40. {
  41. return ReActAgent.ReActAgent.GetModelesIA(useCase);
  42. }
  43. public static async Task<List<string>> GetFooocusStylesAsync()
  44. {
  45. return await _ReActAagent.GetFooocusStylesAsync();
  46. }
  47. public static (string, string, string) LoadParametresGenerateImg()
  48. {
  49. return _ReActAagent.LoadParametresGenerateImg();
  50. }
  51. public static bool SaveParametresGenerateImg(string url, string endpointV1, string endpointv2)
  52. {
  53. return _ReActAagent.SaveParametresGenerateImg(url, endpointV1, endpointv2);
  54. }
  55. public static FooocusRequest_Text_to_Image LoadParametresFooocus()
  56. {
  57. return _ReActAagent.LoadParametresFooocus();
  58. }
  59. public static bool SaveParametresFooocus(FooocusRequest_Text_to_Image param, List<string> ListeSelectedsStylesFooocus)
  60. {
  61. return _ReActAagent.SaveParametresFooocus(param, ListeSelectedsStylesFooocus);
  62. }
  63. public static void SaveConversation(ChatConversation conv)
  64. {
  65. LoggerService.LogInfo($"ChatService.Save");
  66. Directory.CreateDirectory(Folder);
  67. var path = Path.Combine(Folder, conv.Id + ".json");
  68. File.WriteAllText(path, JsonSerializer.Serialize(conv, new JsonSerializerOptions { WriteIndented = true }));
  69. }
  70. public static void Delete(string conversationId)
  71. {
  72. LoggerService.LogInfo($"ChatService.Delete");
  73. var path = Path.Combine(Folder, conversationId + ".json");
  74. if (File.Exists(path)) File.Delete(path);
  75. }
  76. public static List<ChatConversation> LoadAll(string type)
  77. {
  78. LoggerService.LogInfo($"ChatService.LoadAll");
  79. return Directory.GetFiles(Folder, "*.json")
  80. .Select(file => JsonSerializer.Deserialize<ChatConversation>(File.ReadAllText(file)))
  81. .Where(c => c != null)
  82. .Where(c=>c.Type == type)
  83. .Cast<ChatConversation>()
  84. .ToList();
  85. }
  86. public static async Task<(bool, string, string)> SendMessageAsync(ModelsUseCases.TypeUseCase useCase, List<ChatMessage> messages, string model, bool isApiExterne=false)
  87. {
  88. LoggerService.LogInfo($"ChatService.SendMessageAsync");
  89. var (s,m) = await _ReActAagent.AppelerLLMAsync(useCase, model, messages, isApiExterne);
  90. return (true, s, m);
  91. }
  92. public static async Task<(bool, string, string)> SendMessageAsync(string message, string model, bool isWithAssistant, bool isGenerateParametres)
  93. {
  94. LoggerService.LogInfo($"ChatService.SendMessageAsync");
  95. var (s,m) = await _ReActAagent.GenerateTextToImage(ModelsUseCases.TypeUseCase.PromptGenerationFooocus, message, model, isWithAssistant, isGenerateParametres);
  96. return (true, s, m);
  97. }
  98. public static async Task<(bool, string, string)> SendMessageAsync(string message, string model, bool isWithAssistant, List<string> documentsFullFilename)
  99. {
  100. LoggerService.LogInfo($"ChatService.SendMessageAsync");
  101. var (s,m) = await _ReActAagent.GenerateTextToImageWithIP(ModelsUseCases.TypeUseCase.PromptGenerationFooocus, message, model, isWithAssistant, documentsFullFilename);
  102. return (true, s, m);
  103. }
  104. public static async Task<(bool, string, string)> SendMessageAsync(ModelsUseCases.TypeUseCase useCase, string prompt, string model, List<string> documentsFullFilename, bool isApiExterne = false)
  105. {
  106. if (useCase == TypeUseCase.LLM)
  107. {
  108. var (b1,s11,s12) = await SendMessageLLMAsync(prompt, model, documentsFullFilename, isApiExterne);
  109. List<ChatMessage> messages = new();
  110. prompt = prompt + "\n" + s11;
  111. var userMessage = new ChatMessage { Role = "user", Content = prompt, Model = model };
  112. messages.Add(userMessage);
  113. var (b2, s21, s22) = await SendMessageAsync(ModelsUseCases.TypeUseCase.LLM, messages, model, isApiExterne);
  114. return (b1 && b2, "Résumé\n------: \n" + s11 + "\n------\nFin du résumé\n\n" + s21, "Résumé : " + s12 + "\n" + "Traitement de la demande : " + s22);
  115. }
  116. else if (useCase == TypeUseCase.LLM_Coder)
  117. {
  118. return await SendMessageLLMCoderAsync(prompt, model, documentsFullFilename, isApiExterne);
  119. }
  120. else
  121. {
  122. return (false, "Erreur : Cas d'usage qui n'est ni LLM, ni LLM Coder", model);
  123. }
  124. }
  125. #endregion
  126. #region Méthodes privées
  127. private static async Task<(bool, string, string)> SendMessageLLMAsync(string prompt, string model, List<string> documentsFullFilename, bool isApiExterne = false)
  128. {
  129. (List<string> lstImages, List<string> lstDocuments) = FilesService.GetListesFichiers(documentsFullFilename);
  130. // Images mais pas de documents
  131. if (lstImages.Count > 0 && lstDocuments.Count == 0)
  132. {
  133. LoggerService.LogInfo($"ChatService.SendMessageLLMAsync : {lstImages.Count} image(s) mais pas de documents");
  134. var (s, m) = await _ReActAagent.AppelerLLMAsync(ModelsUseCases.TypeUseCase.InterpretationImages, model, prompt, lstImages, isApiExterne);
  135. return (true, s, m);
  136. }
  137. // Documents mais pas d'image
  138. else if (lstImages.Count == 0 && lstDocuments.Count > 0)
  139. {
  140. LoggerService.LogInfo($"ChatService.SendMessageLLMAsync : {lstDocuments.Count} document(s) mais pas d'image");
  141. var (resume, m) = await GetResume(lstDocuments);
  142. return (true, resume.ToString(), m);
  143. }
  144. // Images + documents
  145. else
  146. {
  147. LoggerService.LogInfo($"ChatService.SendMessageLLMAsync : {lstImages.Count} image(s) + {lstDocuments.Count} document(s)");
  148. var resume = await GetResume(lstDocuments);
  149. var (reponse, m) = await _ReActAagent.AppelerLLMAsync(ModelsUseCases.TypeUseCase.InterpretationImages, model, prompt, lstImages, isApiExterne);
  150. return (true, resume + "\n\n" + reponse, m);
  151. }
  152. }
  153. private static async Task<(bool, string, string)> SendMessageLLMCoderAsync(string prompt, string model, List<string> documentsFullFilename, bool isApiExterne = false)
  154. {
  155. (List<string> lstImages, List<string> lstDocuments) = FilesService.GetListesFichiers(documentsFullFilename);
  156. // Images non prises en compte dans ce contexte
  157. if (lstImages.Count > 0 && lstDocuments.Count == 0)
  158. {
  159. LoggerService.LogDebug($"ChatService.SendMessageLLMCoderAsync : {lstImages.Count} image(s) mais pas de documents : pas pris en compte");
  160. return (false, "Erreur : les images ne sont prises en compte dans ce contexte", model);
  161. }
  162. // Documents pris en compte
  163. else if (lstDocuments.Count > 0)
  164. {
  165. LoggerService.LogInfo($"ChatService.SendMessageLLMCoderAsync : {lstDocuments.Count} document(s)");
  166. var codeDocs = "";
  167. foreach (var doc in lstDocuments)
  168. {
  169. var code = $"{Path.GetFileName(doc)} : \n" + TxtService.ExtractTextFromTxt(doc);
  170. codeDocs += "\n" + code;
  171. }
  172. var (rep, m) = await _ReActAagent.AppelerLLMAsync(ModelsUseCases.TypeUseCase.LLM_Coder, true, prompt + "\n\n" + codeDocs, "Analyse de code", model, isApiExterne);
  173. return (true, rep, m);
  174. }
  175. // cas qui ne devrait pas arriver
  176. else
  177. {
  178. LoggerService.LogInfo($"ChatService.SendMessageLLMCoderAsync : {lstImages.Count} image(s) + {lstDocuments.Count} document(s)");
  179. return (true, "Cas qui ne devrait pas arriver", model);
  180. }
  181. }
  182. private static async Task<(string, string)> GetResume(List<string> lstDocuments)
  183. {
  184. LoggerService.LogInfo($"ChatService.GetResume");
  185. string resumes = "";
  186. string model = "";
  187. foreach (var doc in lstDocuments)
  188. {
  189. var filename = System.IO.Path.GetFileName(doc);
  190. string content = FilesService.ExtractText(doc);
  191. //agent.IngestDocument(content, doc);
  192. var (resume, m) = await _ReActAagent.SummarizeIntegralLongDocAsync("ChatRoom", content);
  193. resumes += "\n\n" + filename + " : \n" + resume;
  194. model = m;
  195. }
  196. return (resumes, model);
  197. }
  198. public static async Task<List<OllamaModel>> GetInstalledModelsAsync()
  199. {
  200. var models = await _ReActAagent.GetInstalledModelsAsync(true);
  201. return models;
  202. }
  203. #endregion
  204. }
  205. }