2024-04-24 03:33:57 -03:00
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 ;
2024-04-25 12:51:43 -03:00
using Newtonsoft.Json.Linq ;
2024-04-25 13:11:48 -03:00
using System.Diagnostics ;
2024-04-29 05:56:48 -03:00
using System.Windows.Interop ;
2024-04-24 03:33:57 -03:00
namespace GTPCorrgir
{
2024-04-28 03:42:04 -03:00
2024-04-29 05:56:48 -03:00
public class gtpask
2024-04-24 03:33:57 -03:00
{
private readonly string openAiApiKey = "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" ;
2024-04-26 13:44:52 -03:00
private readonly string groqApiKey = "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" ;
2024-04-25 13:11:48 -03:00
public Logger Log = new Logger ( ) ;
2024-04-24 03:33:57 -03:00
private Dictionary < string , string > languageMap = new Dictionary < string , string >
{
2024-04-25 12:51:43 -03:00
{ "en" , "English" } ,
{ "es" , "Spanish" } ,
{ "it" , "Italian" } ,
{ "pt" , "Portuguese" }
2024-04-24 03:33:57 -03:00
// Agrega más idiomas según sea necesario
} ;
2024-04-25 12:51:43 -03:00
2024-04-24 03:33:57 -03:00
public string IdiomaDetectado ;
public string TextoACorregir ;
public string TextoCorregido ;
2024-04-25 12:51:43 -03:00
public string TextodeSistema ;
2024-04-28 03:42:04 -03:00
private const bool Simulacion = false ;
2024-04-25 12:51:43 -03:00
private string CrearMensajeDeSistema ( )
{
2024-04-29 05:56:48 -03:00
if ( Opciones . Instance . modo = = 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\" }." ;
else
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\" }." ;
2024-04-25 12:51:43 -03:00
}
private string CrearMensajeDeUsuario ( string texto )
{
2024-04-29 05:56:48 -03:00
if ( Opciones . Instance . modo = = 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 + "\"" ;
else
return texto ;
2024-04-25 12:51:43 -03:00
}
2024-04-24 03:33:57 -03:00
private string DetectarIdioma ( string TextoACorregir )
{
LanguageDetector detector = new LanguageDetector ( ) ;
2024-04-25 12:51:43 -03:00
detector . AddLanguages ( "en" , "es" , "it" ) ;
2024-04-24 03:33:57 -03:00
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 ) ;
2024-04-25 13:11:48 -03:00
Log . Log ( "Idioma: " + IdiomaDetectado ) ;
2024-04-24 03:33:57 -03:00
if ( IdiomaDetectado ! = "Desconocido" )
return true ;
else return false ;
}
return false ;
}
public async Task CorregirTexto ( )
2024-04-25 13:11:48 -03:00
{
2024-04-26 12:57:18 -03:00
if ( Simulacion )
2024-04-26 13:44:52 -03:00
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?" ;
2024-04-26 12:57:18 -03:00
2024-04-25 13:45:14 -03:00
Log . Log ( "" ) ;
2024-04-25 13:11:48 -03:00
Log . Log ( "Texto a corregir: " + TextoACorregir ) ;
2024-04-24 03:33:57 -03:00
if ( DetectarIdioma ( ) ) {
if ( IdiomaDetectado = = "Desconocido" | | this . TextoACorregir . Length = = 0 )
{
// Nada que hacer
TextoCorregido = TextoACorregir ;
return ;
}
2024-04-25 12:51:43 -03:00
var md = new Obsidean ( ) ;
md . LeerPalabrasTecnicas ( ) ;
2024-04-28 03:42:04 -03:00
TextoACorregir = md . MarkTechnicalTerms_IgnoreCase ( TextoACorregir ) ;
2024-04-25 12:51:43 -03:00
2024-04-25 13:45:14 -03:00
Log . Log ( "Texto marcado: " + TextoACorregir ) ;
2024-04-25 13:11:48 -03:00
2024-04-28 03:42:04 -03:00
string RespuestaLLM = "" ;
2024-04-26 12:57:18 -03:00
if ( ! Simulacion )
{
2024-04-28 03:42:04 -03:00
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 ) ;
2024-04-26 12:57:18 -03:00
} else
{
await Task . Delay ( 1000 ) ;
2024-04-26 13:44:52 -03:00
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}" ;
2024-04-26 12:57:18 -03:00
}
2024-04-25 13:11:48 -03:00
Log . Log ( "Respuesta: " + RespuestaLLM ) ;
2024-04-24 03:33:57 -03:00
2024-04-29 05:56:48 -03:00
TextoCorregido = ExtraerValorUnicoJSON ( RespuestaLLM ) ;
if ( TextoCorregido is null )
TextoCorregido = "Error en la respuesta." ;
2024-04-24 03:33:57 -03:00
// Elimina comillas al principio y al final si existen
TextoCorregido = TextoCorregido . Trim ( '\"' ) ;
2024-04-25 13:11:48 -03:00
2024-04-25 13:45:14 -03:00
Log . Log ( "Texto corregido: " + TextoCorregido ) ;
2024-04-24 03:33:57 -03:00
}
}
2024-04-25 12:51:43 -03:00
2024-04-29 05:56:48 -03:00
public string ExtraerValorUnicoJSON ( string input )
2024-04-25 12:51:43 -03:00
{
2024-04-29 05:56:48 -03:00
// 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 ) ;
2024-04-25 12:51:43 -03:00
try
{
2024-04-29 05:56:48 -03:00
// Parsea el JSON
JObject jsonObject = JObject . Parse ( jsonString ) ;
2024-04-25 12:51:43 -03:00
2024-04-29 05:56:48 -03:00
// Obtiene el primer campo independientemente del nombre de la clave
var firstField = jsonObject . Properties ( ) . FirstOrDefault ( ) ;
if ( firstField ! = null )
2024-04-25 12:51:43 -03:00
{
2024-04-29 05:56:48 -03:00
return firstField . Value . ToString ( ) ; // Devuelve el valor del primer campo
}
else
{
return "JSON does not contain any data." ;
2024-04-25 12:51:43 -03:00
}
}
2024-04-29 05:56:48 -03:00
catch ( JsonException jsonEx )
2024-04-25 12:51:43 -03:00
{
2024-04-29 05:56:48 -03:00
// Maneja errores de parseo de JSON
return "Error parsing JSON: " + jsonEx . Message ;
2024-04-25 12:51:43 -03:00
}
}
2024-04-29 05:56:48 -03:00
2024-04-26 13:44:52 -03:00
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 ) ;
2024-04-28 03:42:04 -03:00
// 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 ;
2024-04-26 13:44:52 -03:00
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 ;
}
}
2024-04-24 03:33:57 -03:00
private async Task < string > CallOllamaApi ( string input )
{
var httpClient = new HttpClient ( ) ;
2024-04-25 12:51:43 -03:00
string Mensaje_Sistema = CrearMensajeDeSistema ( ) ;
string Mensaje_Usuario = CrearMensajeDeUsuario ( input ) ;
2024-04-24 03:33:57 -03:00
httpClient . DefaultRequestHeaders . Add ( "Authorization" , $"Bearer {openAiApiKey}" ) ;
var requestData = new
{
2024-04-28 03:42:04 -03:00
model = "phi3" , //"llama3",
2024-04-24 03:33:57 -03:00
messages = new [ ]
{
2024-04-25 12:51:43 -03:00
new { role = "system" , content = Mensaje_Sistema } ,
new { role = "user" , content = Mensaje_Usuario }
2024-04-24 03:33:57 -03:00
} ,
stream = false
} ;
var content = new StringContent ( JsonConvert . SerializeObject ( requestData ) , Encoding . UTF8 , "application/json" ) ;
try
{
2024-04-25 13:45:14 -03:00
Log . Log ( "Ask Ollama: " + JsonConvert . SerializeObject ( requestData ) ) ;
2024-04-24 03:33:57 -03:00
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 ;
}
}
2024-04-25 12:51:43 -03:00
2024-04-24 03:33:57 -03:00
private async Task < string > CallOpenAiApi ( string input )
{
var httpClient = new HttpClient ( ) ;
2024-04-25 12:51:43 -03:00
string Mensaje_Sistema = CrearMensajeDeSistema ( ) ;
string Mensaje_Usuario = CrearMensajeDeUsuario ( input ) ;
2024-04-24 03:33:57 -03:00
httpClient . DefaultRequestHeaders . Add ( "Authorization" , $"Bearer {openAiApiKey}" ) ;
var requestData = new
{
model = "gpt-4" ,
messages = new [ ]
{
2024-04-25 12:51:43 -03:00
new { role = "system" , content = Mensaje_Sistema } ,
new { role = "user" , content = Mensaje_Usuario }
2024-04-24 03:33:57 -03:00
}
} ;
var content = new StringContent ( JsonConvert . SerializeObject ( requestData ) , Encoding . UTF8 , "application/json" ) ;
try
{
2024-04-25 13:45:14 -03:00
Log . Log ( "Ask OpenAI: " + JsonConvert . SerializeObject ( requestData ) ) ;
2024-04-24 03:33:57 -03:00
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 ;
}
}
2024-04-26 13:44:52 -03:00
private async Task < string > 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 }
2024-04-28 03:42:04 -03:00
} ,
max_tokens = 2048 ,
stream = false
2024-04-26 13:44:52 -03:00
} ;
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 ;
}
}
2024-04-24 03:33:57 -03:00
}
}