using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Windows.Threading; using LanguageDetection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Diagnostics; using System.Windows.Interop; namespace GTPCorrgir { public class gtpask { private readonly string openAiApiKey = "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"; private readonly string groqApiKey = "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"; public Logger Log = new Logger(); private Dictionary languageMap = new Dictionary { { "en", "English" }, { "es", "Spanish" }, { "it", "Italian" }, { "pt", "Portuguese" } // Agrega más idiomas según sea necesario }; public string IdiomaDetectado; public string TextoACorregir; public string TextoCorregido; public string TextodeSistema; private const bool Simulacion = false; private string CrearMensajeDeSistema() { switch (Opciones.Instance.modo) { case Opciones.modoDeUso.Corregir: return "You are an engineer working in industrial automation. Your task is to review texts and rewrite them in a simple and concise manner, making sure to preserve important technical terms and markdown language if present. Please rewrite the following text in " + IdiomaDetectado + " and respond in the following JSON format: { \"Rewritten_text\": \"Your text here\" }."; case Opciones.modoDeUso.Ortografia: return "Please check the following text for spelling errors and provide the corrected version. Do not change the meaning or structure of the sentences. Only correct any spelling mistakes you find, making sure to preserve important technical terms and markdown language if present. Please write in " + IdiomaDetectado + " and respond in the following JSON format: { \"Rewritten_text\": \"Your text here\" }."; default: return "You are an engineer working specialiazed industrial automation. Please answer the following question in " + IdiomaDetectado + " and respond in the following JSON format: { \"Reply_text\": \"Your text here\" }."; } } private string CrearMensajeDeUsuario(string texto) { switch (Opciones.Instance.modo) { case Opciones.modoDeUso.Corregir: return "Please rewrite and improve the following text to make it clearer and more concise the words inside brackets are technical words: \"" + texto + "\""; case Opciones.modoDeUso.Ortografia: return "Please check the following text for spelling errors and provide the corrected version. Do not change the meaning or structure of the sentences. Only correct any spelling mistakes you find on: \"" + texto + "\""; default: return texto; } } private string DetectarIdioma(string TextoACorregir) { LanguageDetector detector = new LanguageDetector(); detector.AddLanguages("en", "es", "it"); string detectedLanguageCode = detector.Detect(TextoACorregir); string detectedLanguageName = languageMap.ContainsKey(detectedLanguageCode) ? languageMap[detectedLanguageCode] : "Desconocido"; return detectedLanguageName; } private bool DetectarIdioma() { if (TextoACorregir.Length>0) { IdiomaDetectado = DetectarIdioma(TextoACorregir); Log.Log("Idioma: " + IdiomaDetectado); if(IdiomaDetectado != "Desconocido") return true; else return false; } return false; } public async Task CorregirTexto() { if (Simulacion) TextoACorregir = "\t\t* Sic : Synchronism?\r\n\t\t* Cont ? \r\n\t\t* Sensor for tensioning?\r\n\t\t* Max ? Overspeed?\r\n\t\t* Min : Stop / Start\r\n\t\t* Variable Speed. - = reference by filler\r\n\t\t* Formats: ? 66mm a 93mm => 27mm. How is changed?"; Log.Log(""); Log.Log("Texto a corregir: " + TextoACorregir); if (DetectarIdioma()) { if (IdiomaDetectado == "Desconocido" || this.TextoACorregir.Length == 0) { // Nada que hacer TextoCorregido = TextoACorregir; return; } var md = new Obsidean(); md.LeerPalabrasTecnicas(); TextoACorregir = md.MarkTechnicalTerms_IgnoreCase(TextoACorregir); Log.Log("Texto marcado: " + TextoACorregir); string RespuestaLLM = ""; if (!Simulacion) { if (Opciones.Instance.LLM == Opciones.LLM_a_Usar.OpenAI) RespuestaLLM = await CallOpenAiApi(TextoACorregir); if (Opciones.Instance.LLM == Opciones.LLM_a_Usar.Ollama) RespuestaLLM = await CallOllamaApi(TextoACorregir); if (Opciones.Instance.LLM == Opciones.LLM_a_Usar.Groq) RespuestaLLM = await CallGroqAiApi(TextoACorregir); } else { await Task.Delay(1000); RespuestaLLM = "Here is the rewritten text in a clearer and more concise manner:\r\n\r\n{\r\n'Rewritten_text': '\r\n### FB Tilting System Overview\r\n\r\nThe FB Tilting system consists of two main components:\r\n\r\n* **FB Tilting**: The main machine responsible for tilting and moving bottles.\r\n* **Sic (Synchronism)**: Ensures synchronized movement of the tilting machine with other system components.\r\n\r\n### Key Components and Functions\r\n\r\n* **Cont (Controller)**: The controlling unit that regulates the system's operation.\r\n* **Sensor for Tensioning**: Monitors and adjusts the tension of the moving parts.\r\n* **Max (Maximum Speed) and Overspeed Protection**: Safeguards the system from excessive speeds.\r\n* **Min (Minimum Speed) and Stop/Start Function**: Manages the system's startup and shutdown sequences.\r\n* **Variable Speed**: Allows for adjustable speed control, referenced by the filling machine.\r\n\r\n### Format Adaptation\r\n\r\nThe system accommodates various formats, including:\r\n* 66mm to 93mm, which are adapted to 27mm formats. The format change process is implemented as follows:\r\n\r\n### Startup Sequence\r\n\r\nThe startup procedure involves:\r\n\r\n1. **Fill to Sic with Minimum Accumulation**: Fills the Sic component with a minimum amount of material.\r\n2. **Run Chain at Fixed Speed**: Operates the chain at a constant speed.\r\n3. **Wait for Phase to Start**: Waits for the phase and ramp of the doser to be parameterized.\r\n4. **Ramp to Variable Speed**: Gradually adjusts the speed to the selected variable speed setting after a few bottles have been processed.'\r\n}"; } Log.Log("Respuesta: " + RespuestaLLM); TextoCorregido = ExtraerValorUnicoJSON(RespuestaLLM); if (TextoCorregido is null) TextoCorregido = "Error en la respuesta."; // Elimina comillas al principio y al final si existen TextoCorregido = md.RemoveTechnicalTermMarkers(TextoCorregido).Trim('\"'); Log.Log("Texto corregido: " + TextoCorregido); } } public string ExtraerValorUnicoJSON(string input) { // Encuentra los índices del inicio y del final del JSON int startJson = input.IndexOf('{'); int endJson = input.LastIndexOf('}') + 1; if (startJson == -1 || endJson == -1 || endJson <= startJson) { return "No valid JSON found in the input string."; } // Extrae solo la parte JSON de la entrada string jsonString = input.Substring(startJson, endJson - startJson); try { // Parsea el JSON JObject jsonObject = JObject.Parse(jsonString); // Obtiene el primer campo independientemente del nombre de la clave var firstField = jsonObject.Properties().FirstOrDefault(); if (firstField != null) { return firstField.Value.ToString(); // Devuelve el valor del primer campo } else { return "JSON does not contain any data."; } } catch (JsonException jsonEx) { // Maneja errores de parseo de JSON return "Error parsing JSON: " + jsonEx.Message; } } static string ExtractCorrectedText(string input) { try { // Encuentra el índice del inicio y del final del JSON int startJson = input.IndexOf('{'); int endJson = input.LastIndexOf('}') + 1; if (startJson == -1 || endJson == -1 || endJson <= startJson) { throw new Exception("No valid JSON found in the input string."); } // Extrae solo la parte JSON de la entrada string jsonString = input.Substring(startJson, endJson - startJson); // Busca el inicio del texto después de "Rewritten_text':" int startKey = jsonString.IndexOf("'Rewritten_text':") + 17; // 17 es la longitud de "'Rewritten_text':" if (startKey == -1) { throw new Exception("Key 'Rewritten_text' not found."); } // Ajusta para encontrar el inicio del texto después de las comillas simples adicionales int startText = jsonString.IndexOf('\'', startKey) + 1; int endText = jsonString.LastIndexOf('\''); if (startText == -1 || endText == -1 || endText <= startText) { throw new Exception("No valid text found in the JSON string."); } // Extrae el texto entre las comillas simples string rewrittenText = jsonString.Substring(startText, endText - startText); return rewrittenText; } catch (Exception ex) { Console.WriteLine("An error occurred: " + ex.Message); return null; } } private async Task CallOllamaApi(string input) { var httpClient = new HttpClient(); string Mensaje_Sistema = CrearMensajeDeSistema(); string Mensaje_Usuario = CrearMensajeDeUsuario(input); httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {openAiApiKey}"); var requestData = new { model = "phi3", //"llama3", messages = new[] { new { role = "system", content = Mensaje_Sistema }, new { role = "user", content = Mensaje_Usuario } }, stream = false }; var content = new StringContent(JsonConvert.SerializeObject(requestData), Encoding.UTF8, "application/json"); try { Log.Log("Ask Ollama: " + JsonConvert.SerializeObject(requestData)); var response = await httpClient.PostAsync("http://127.0.0.1:11434/api/chat", content); response.EnsureSuccessStatusCode(); var jsonResponse = await response.Content.ReadAsStringAsync(); dynamic data = JsonConvert.DeserializeObject(jsonResponse); if (data.done == true && data.message != null) { return data.message.content; } return "No hubo respuesta del asistente o la sesión aún no ha concluido."; } catch (HttpRequestException e) { // Captura errores en la solicitud HTTP, como problemas de red o respuestas de error HTTP. Console.WriteLine($"Error making HTTP request: {e.Message}"); return null; } catch (Exception e) { // Captura cualquier otro error Console.WriteLine($"An error occurred: {e.Message}"); return null; } } private async Task CallOpenAiApi(string input) { var httpClient = new HttpClient(); string Mensaje_Sistema = CrearMensajeDeSistema(); string Mensaje_Usuario = CrearMensajeDeUsuario(input); httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {openAiApiKey}"); var requestData = new { model = "gpt-4", messages = new[] { new { role = "system", content = Mensaje_Sistema }, new { role = "user", content = Mensaje_Usuario } } }; var content = new StringContent(JsonConvert.SerializeObject(requestData), Encoding.UTF8, "application/json"); try { Log.Log("Ask OpenAI: " + JsonConvert.SerializeObject(requestData)); var response = await httpClient.PostAsync("https://api.openai.com/v1/chat/completions", content); response.EnsureSuccessStatusCode(); var jsonResponse = await response.Content.ReadAsStringAsync(); dynamic data = JsonConvert.DeserializeObject(jsonResponse); return data.choices[0].message.content; } catch (HttpRequestException e) { // Captura errores en la solicitud HTTP, como problemas de red o respuestas de error HTTP. Console.WriteLine($"Error making HTTP request: {e.Message}"); return null; } catch (Exception e) { // Captura cualquier otro error Console.WriteLine($"An error occurred: {e.Message}"); return null; } } private async Task CallGroqAiApi(string input) { var httpClient = new HttpClient(); string Mensaje_Sistema = CrearMensajeDeSistema(); string Mensaje_Usuario = CrearMensajeDeUsuario(input); httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {groqApiKey}"); var requestData = new { model = "llama3-70b-8192", messages = new[] { new { role = "system", content = Mensaje_Sistema }, new { role = "user", content = Mensaje_Usuario } }, max_tokens = 2048, stream = false }; var content = new StringContent(JsonConvert.SerializeObject(requestData), Encoding.UTF8, "application/json"); try { Log.Log("Ask Groq: " + JsonConvert.SerializeObject(requestData)); var response = await httpClient.PostAsync("https://api.groq.com/openai/v1/chat/completions", content); response.EnsureSuccessStatusCode(); var jsonResponse = await response.Content.ReadAsStringAsync(); dynamic data = JsonConvert.DeserializeObject(jsonResponse); return data.choices[0].message.content; } catch (HttpRequestException e) { // Captura errores en la solicitud HTTP, como problemas de red o respuestas de error HTTP. Console.WriteLine($"Error making HTTP request: {e.Message}"); return null; } catch (Exception e) { // Captura cualquier otro error Console.WriteLine($"An error occurred: {e.Message}"); return null; } } } }