Mejorado con el uso de mensajes de sistema. Respuestas usando json. Tambien se llen las palabras de uso tecnico para intentar que no sean traducidas. Agregado ventana de notificaciones fija para mostrar el tiempo.

This commit is contained in:
Miguel 2024-04-25 17:51:43 +02:00
parent b3c2fb82c0
commit 575f8c7a61
7 changed files with 256 additions and 23 deletions

View File

@ -3,6 +3,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GTPCorrgir">
<Application.Resources>
</Application.Resources>
</Application.Resources>
</Application>

View File

@ -18,14 +18,16 @@ namespace GTPCorrgir
gtpask GTP = new gtpask();
NotifyIcon notificacion;
System.Windows.Forms.Timer timer;
int segundos = 0;
bool CorreccionFinalizada = false;
Stopwatch stopwatch = new Stopwatch();
private notificacion notificationWindow;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
stopwatch.Start();
if (System.Windows.Clipboard.ContainsText())
@ -34,7 +36,7 @@ namespace GTPCorrgir
}
// Muestra notificación inicial y comienza el cronómetro en el hilo de la UI
MostrarNotificacion("Espera", "Corrigiendo texto...");
ShowCustomNotification("Espera", "Corrigiendo texto...");
IniciarCronometro();
// Ejecuta la tarea de corrección en un hilo secundario
@ -59,7 +61,8 @@ namespace GTPCorrgir
if (GTP.TextoCorregido != null)
{
System.Windows.Clipboard.SetText(GTP.TextoCorregido);
MostrarNotificacion("Corrección Lista", GTP.TextoCorregido);
ShowCustomNotification("Se puede pegar", $" Correccion en : {Math.Round(stopwatch.ElapsedMilliseconds / 1000.0, 1)} s" );
Thread.Sleep(5000); // Espera 5 segundos
}
else
{
@ -71,6 +74,17 @@ namespace GTPCorrgir
});
}
private void ShowCustomNotification(string title, string message)
{
if (notificationWindow == null)
{
notificationWindow = new notificacion();
notificationWindow.Show();
}
notificationWindow.UpdateNotification(title, message);
}
private void MostrarNotificacion(string titulo, string mensaje)
{
notificacion = new NotifyIcon
@ -83,10 +97,11 @@ namespace GTPCorrgir
notificacion.ShowBalloonTip(1000);
}
private void IniciarCronometro()
{
timer = new System.Windows.Forms.Timer();
timer.Interval = 1000; // 1000 milisegundos (1 segundo)
timer.Interval = 100; // 1000 milisegundos (1 segundo)
timer.Tick += ActualizarCronometro;
timer.Start();
}
@ -94,9 +109,9 @@ namespace GTPCorrgir
private void ActualizarCronometro(object sender, EventArgs e)
{
if (!CorreccionFinalizada) {
segundos++;
notificacion.BalloonTipText = $"Texto en {GTP.IdiomaDetectado} pasados: {Math.Round(stopwatch.ElapsedMilliseconds/1000.0,1)} s";
notificacion.ShowBalloonTip(1000);
//notificacion.BalloonTipText = $"Texto en {GTP.IdiomaDetectado} pasados: {Math.Round(stopwatch.ElapsedMilliseconds/1000.0,1)} s";
//notificacion.ShowBalloonTip(1000);
ShowCustomNotification("Trabajando..", $"Texto en {GTP.IdiomaDetectado} pasados: {Math.Round(stopwatch.ElapsedMilliseconds / 1000.0, 1)} s");
}
}

97
Obsidean.cs Normal file
View File

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
namespace GTPCorrgir
{
internal class Obsidean
{
static HashSet<string> technicalTerms;
static string GetObsidianConfigPath()
{
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
return Path.Combine(appDataPath, "obsidian", "obsidian.json");
}
static string GetVaultPath(string vaultName)
{
try
{
string pathToJsonFile = GetObsidianConfigPath();
string jsonContent = File.ReadAllText(pathToJsonFile);
JObject jsonObject = JObject.Parse(jsonContent);
JObject vaults = (JObject)jsonObject["vaults"];
foreach (var vault in vaults)
{
// 'vault' es un KeyValuePair<string, JToken>
// 'vault.Key' es la clave (ID del vault), 'vault.Value' es el valor (detalles del vault como JToken)
string path = (string)vault.Value["path"];
if (!string.IsNullOrEmpty(path))
{
// Añadir una barra al final asegura que Path.GetDirectoryName funcione correctamente
string lastDirectoryName = Path.GetFileName(Path.GetDirectoryName(path.TrimEnd('\\') + "\\"));
if (lastDirectoryName.Equals(vaultName, StringComparison.OrdinalIgnoreCase))
{
return path;
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error al leer o parsear el archivo JSON: " + ex.Message);
}
return null;
}
public void LeerPalabrasTecnicas()
{
// "C:\Users\migue\OneDrive\Miguel\Obsidean\Trabajo\VM\Palabras Tecnicas\Lista.md"
string pathToMarkdown = GetVaultPath("VM");
if (!string.IsNullOrEmpty(pathToMarkdown))
{
string pathToLista = pathToMarkdown + "\\Palabras Tecnicas\\Lista.md";
string[] lines = File.ReadAllLines(pathToLista);
technicalTerms = ExtractTechnicalTerms(lines);
}
// Ahora puedes usar technicalTerms para tu lógica de corrección
}
public HashSet<string> ExtractTechnicalTerms(string[] lines)
{
var terms = new HashSet<string>();
foreach (var line in lines)
{
// Suponiendo que cada línea contiene un término técnico
terms.Add(line.Trim());
}
return terms;
}
public string MarkTechnicalTerms(string text)
{
// Utilizar Regex para identificar palabras individualmente
return Regex.Replace(text, @"\b(\w+)\b", match =>
{
string word = match.Groups[1].Value;
// Verificar si la palabra está en el conjunto de términos técnicos
if (technicalTerms.Contains(word))
{
return $"[[{word}]]"; // Encerrar la palabra en corchetes si es técnica
}
return word; // Devolver la palabra sin modificar si no es técnica
});
}
}
}

6
Ollama/Modelfile Normal file
View File

@ -0,0 +1,6 @@
FROM llama3
# set the system message
SYSTEM """
You are an engineer who works in industrial automation. You correct the texts in a simple and concise way when asked without explanations. Respond in the language that was told please. Response in json format.
"""

View File

@ -7,29 +7,44 @@ using System.Threading.Tasks;
using System.Windows.Threading;
using LanguageDetection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace GTPCorrgir
{
internal class gtpask
{
private readonly string openAiApiKey = "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";
private readonly string accionGTP = "Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: ";
private Dictionary<string, string> languageMap = new Dictionary<string, string>
{
{ "en", "Inglés" },
{ "es", "Español" },
{ "it", "Italiano" },
{ "pt", "Portugués" }
{ "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 string CrearMensajeDeSistema()
{
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 specially if they are in English. Please rewrite the following text in " + IdiomaDetectado + " and respond in the following JSON format: { 'Rewritten_text': 'Your text here' }.";
}
private string CrearMensajeDeUsuario(string texto)
{
return "Please rewrite and improve the following text to make it clearer and more concise the words inside brackets are technical words: \"" + texto + "\"";
}
private string DetectarIdioma(string TextoACorregir)
{
LanguageDetector detector = new LanguageDetector();
detector.AddLanguages("en", "es", "it", "pt");
detector.AddLanguages("en", "es", "it");
string detectedLanguageCode = detector.Detect(TextoACorregir);
string detectedLanguageName = languageMap.ContainsKey(detectedLanguageCode)
@ -51,8 +66,7 @@ namespace GTPCorrgir
}
public async Task CorregirTexto()
{
var Instrucciones = accionGTP;
{
if (DetectarIdioma()) {
if (IdiomaDetectado == "Desconocido" || this.TextoACorregir.Length == 0)
@ -62,18 +76,55 @@ namespace GTPCorrgir
return;
}
TextoACorregir = "El resultado debe estar en " + IdiomaDetectado + ". " + Instrucciones + "\"" + TextoACorregir + "\"";
var md = new Obsidean();
md.LeerPalabrasTecnicas();
TextoCorregido = await CallOpenAiApi(TextoACorregir);
//TextoCorregido = await CallOllamaApi(TextoACorregir);
TextoACorregir = md.MarkTechnicalTerms(TextoACorregir);
//TextoCorregido = await CallOpenAiApi(TextoACorregir);
string RespuestaLLM = await CallOllamaApi(TextoACorregir);
TextoCorregido = ExtractCorrectedText(RespuestaLLM);
// Elimina comillas al principio y al final si existen
TextoCorregido = TextoCorregido.Trim('\"');
}
}
static string ExtractCorrectedText(string input)
{
try
{
// Encuentra el índice del inicio y del final del JSON
int startJson = input.IndexOf('{');
int endJson = input.IndexOf('}') + 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);
// Parsea el JSON y extrae el campo "Rewritten_text"
JObject jsonObject = JObject.Parse(jsonString);
string rewrittenText = (string)jsonObject["Rewritten_text"];
return rewrittenText;
}
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
return null;
}
}
private async Task<string> 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
@ -81,7 +132,8 @@ namespace GTPCorrgir
model = "llama3",
messages = new[]
{
new { role = "user", content = input },
new { role = "system", content = Mensaje_Sistema },
new { role = "user", content = Mensaje_Usuario }
},
stream = false
};
@ -114,9 +166,13 @@ namespace GTPCorrgir
}
}
private async Task<string> 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
@ -124,8 +180,8 @@ namespace GTPCorrgir
model = "gpt-4",
messages = new[]
{
new { role = "system", content = "Este es un mensaje del sistema inicializando la conversación" },
new { role = "user", content = input }
new { role = "system", content = Mensaje_Sistema },
new { role = "user", content = Mensaje_Usuario }
}
};

14
notificacion.xaml Normal file
View File

@ -0,0 +1,14 @@
<Window x:Class="GTPCorrgir.notificacion"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="100" Width="300"
Topmost="True" ShowInTaskbar="False"
WindowStyle="None" AllowsTransparency="True"
Background="Transparent">
<Border CornerRadius="10" Background="#AAF0F0F0">
<StackPanel>
<TextBlock x:Name="TitleText" FontSize="16" FontWeight="Bold" Margin="10"/>
<TextBlock x:Name="MessageText" FontSize="14" Margin="10"/>
</StackPanel>
</Border>
</Window>

45
notificacion.xaml.cs Normal file
View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace GTPCorrgir
{
/// <summary>
/// Interaction logic for notificacion.xaml
/// </summary>
public partial class notificacion : Window
{
public notificacion()
{
InitializeComponent();
PositionWindow();
}
private void PositionWindow()
{
// Obtener la posición del cursor
var cursorPosition = System.Windows.Forms.Cursor.Position;
// Determinar en qué pantalla está el cursor
var screen = Screen.FromPoint(cursorPosition);
// Configurar la ubicación de la ventana para que aparezca en la esquina inferior derecha
this.Left = screen.WorkingArea.Right - this.Width;
this.Top = screen.WorkingArea.Bottom - this.Height;
}
public void UpdateNotification(string title, string message)
{
TitleText.Text = title;
MessageText.Text = message;
}
}
}