Compare commits

...

2 Commits

Author SHA1 Message Date
Miguel fe707ea7fb Funcionando con el markup y el --Chat 2024-04-29 11:32:37 +02:00
Miguel d9ee5208f0 Antes de modifica todo a Markdown 2024-04-29 10:56:48 +02:00
6 changed files with 340 additions and 64 deletions

View File

@ -31,13 +31,16 @@ namespace GTPCorrgir
{
base.OnStartup(e);
stopwatch.Start();
if (System.Windows.Clipboard.ContainsText())
{
GTP.TextoACorregir = System.Windows.Clipboard.GetText();
}
if (Opciones.Instance.modo == Opciones.modoDeUso.Corregir)
{
stopwatch.Start();
// Muestra notificación inicial y comienza el cronómetro en el hilo de la UI
ShowCustomNotification("Espera", $"Corrigiendo texto con .{Opciones.Instance.nombreDeLLM()} ..");
IniciarCronometro();
@ -78,6 +81,11 @@ namespace GTPCorrgir
});
}
});
} else if (Opciones.Instance.modo == Opciones.modoDeUso.Chat)
{
var chatWindows = new Chat(GTP);
chatWindows.Show();
}
}

62
Chat.xaml Normal file
View File

@ -0,0 +1,62 @@
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:md="clr-namespace:Markdown.Xaml;assembly=Markdown.Xaml"
xmlns:av="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="av" x:Class="GTPCorrgir.Chat"
Title="Chat with OpenAI" Height="300" Width="300"
ResizeMode="CanResizeWithGrip" WindowStyle="None"
Background="Transparent" AllowsTransparency="True"
MouseEnter="Window_MouseEnter" MouseLeave="Window_MouseLeave" KeyDown="Window_KeyDown"
Opacity="0.8" av:DesignHeight="320.439" av:DesignWidth="609.769">
<Window.Resources>
<md:Markdown x:Key="MarkdownConverter" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<!-- Model Selector con altura automática -->
<RowDefinition Height="2*"/>
<!-- Área de Respuesta con 2/3 del espacio disponible -->
<RowDefinition Height="*"/>
<!-- Área de Pregunta con 1/3 del espacio disponible -->
</Grid.RowDefinitions>
<!-- Selector del Modelo -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- Selector de modelo LLM -->
<ComboBox x:Name="modelSelector" Grid.Column="0" Margin="1" SelectionChanged="CambiarModelo" />
<!-- Área para mover la ventana -->
<Border Background="#444" Height="20" Width="20" Grid.Column="1" Margin="10,0,10,0"
MouseLeftButtonDown="Border_MouseLeftButtonDown" Cursor="SizeAll" ToolTip="Mover ventana">
<TextBlock Text="&#x2630;" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/>
</Border>
</Grid>
<!-- Área de Respuesta -->
<Grid Grid.Row="1" Margin="1">
<RichTextBox Name="responseArea" IsReadOnly="True" Grid.Row="1">
<RichTextBox.Resources>
<md:Markdown x:Key="Markdown" />
</RichTextBox.Resources>
</RichTextBox>
<Button x:Name="clearButton" Content="Limpiar" Width="40" Height="24"
HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0" Click="clearButton_Click" />
</Grid>
<!-- Área de Pregunta con Botón Superpuesto -->
<Grid Grid.Row="2" Margin="1">
<TextBox x:Name="questionArea" Padding="10"
VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" Background="White" PreviewKeyDown="QuestionArea_PreviewKeyDown"/>
<Button x:Name="sendButton" Content="Enviar" Width="40" Height="24"
HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0" Click="SendButton_Click"/>
</Grid>
</Grid>
</Window>

175
Chat.xaml.cs Normal file
View File

@ -0,0 +1,175 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
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.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using static GTPCorrgir.Opciones;
using static System.Net.WebRequestMethods;
using ComboBox = System.Windows.Controls.ComboBox;
using Cursors = System.Windows.Input.Cursors;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
namespace GTPCorrgir
{
/// <summary>
/// Interaction logic for Chat.xaml
/// </summary>
public partial class Chat : Window
{
gtpask AI_API;
string respuestas;
public Chat(gtpask GTP)
{
InitializeComponent();
PositionWindow();
// Inicializar componentes de la UI, por ejemplo, llenar el ComboBox
AI_API = GTP;
questionArea.Text = ""; //GTP.TextoACorregir;
respuestas = "";
foreach (KeyValuePair<LLM_a_Usar, string> kvp in Opciones.Instance.nombreLLM)
{
ComboBoxItem item = new ComboBoxItem();
item.Content = kvp.Value; // El texto que se mostrará
item.Tag = kvp.Key; // Guarda el valor enum en el Tag para acceso posterior
modelSelector.Items.Add(item);
// Verifica si este ítem debe ser el seleccionado
if (kvp.Key == Opciones.Instance.LLM)
{
modelSelector.SelectedItem = item;
}
}
}
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Iniciar movimiento de la ventana si se presiona el botón izquierdo del ratón
if (e.LeftButton == MouseButtonState.Pressed)
{
this.DragMove();
}
}
private void Window_MouseEnter(object sender, MouseEventArgs e)
{
// Hacer la ventana opaca cuando el ratón esté sobre ella
this.Opacity = 1.0;
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
this.Close();
}
}
private void QuestionArea_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter && !e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Shift))
{
SendButton_Click(this, new RoutedEventArgs());
e.Handled = true; // Prevenir el salto de línea en el TextBox
}
}
private void Window_MouseLeave(object sender, MouseEventArgs e)
{
// Hacer la ventana transparente cuando el ratón no esté sobre ella
this.Opacity = 0.2; // Ajusta este valor a tu preferencia
}
private void SendButton_Click(object sender, RoutedEventArgs e)
{
// Aquí lógica para enviar pregunta y recibir respuesta de OpenAI
AI_API.TextoACorregir = questionArea.Text;
if (AI_API.TextoACorregir.Length > 3)
{
sendButton.IsEnabled = false; // Deshabilitar el botón de envío
Mouse.OverrideCursor = Cursors.Wait; // Cambiar el cursor a espera
Task.Run(async () =>
{
try
{
await AI_API.CorregirTexto();
}
catch (Exception ex)
{
Console.WriteLine("Error durante la corrección de texto: " + ex.Message);
}
finally
{
Dispatcher.Invoke(async () => // Nota el 'async' aquí para permitir 'await'
{
if (AI_API.TextoCorregido != null)
{
System.Windows.Clipboard.SetText(AI_API.TextoCorregido);
//responseArea. .Text += AI_API.TextoCorregido + "\r\n";
AddMarkdownContent(AI_API.TextoCorregido + "\r\n");
Mouse.OverrideCursor = null; // Restaurar el cursor normal
sendButton.IsEnabled = true; // Habilitar el botón de envío
}
});
}
});
}
}
public void AddMarkdownContent(string markdownText)
{
// Transforma el texto Markdown a un FlowDocument
var markdown = new Markdown.Xaml.Markdown();
respuestas += markdownText + "\r\n";
responseArea.Document = markdown.Transform(respuestas);
}
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);
// Calcular la ubicación central en la pantalla actual
this.Left = (screen.WorkingArea.Width - this.Width) / 2 + screen.WorkingArea.Left;
this.Top = (screen.WorkingArea.Height - this.Height) / 2 + screen.WorkingArea.Top;
}
private void CambiarModelo(object sender, SelectionChangedEventArgs e)
{
ComboBox comboBox = sender as ComboBox;
ComboBoxItem selectedItem = comboBox.SelectedItem as ComboBoxItem;
if (selectedItem != null)
{
LLM_a_Usar selectedEnum = (LLM_a_Usar)selectedItem.Tag;
Opciones.Instance.LLM = selectedEnum; // Suponiendo que hay una propiedad para establecerlo
}
}
private void clearButton_Click(object sender, RoutedEventArgs e)
{
respuestas = "";
AddMarkdownContent("");
}
}
}

View File

@ -22,6 +22,7 @@
<ItemGroup>
<PackageReference Include="LanguageDetection" Version="1.2.0" />
<PackageReference Include="Markdown.Xaml" Version="1.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

View File

@ -15,7 +15,13 @@ namespace GTPCorrgir
Ollama,
Groq
}
private Dictionary<LLM_a_Usar, string> nombreLLM = new Dictionary<LLM_a_Usar, string>
public enum modoDeUso
{
Corregir,
Chat,
}
public Dictionary<LLM_a_Usar, string> nombreLLM = new Dictionary<LLM_a_Usar, string>
{
{ Opciones.LLM_a_Usar.Ollama, "Ollama" },
{ Opciones.LLM_a_Usar.Groq, "Groq" },
@ -32,12 +38,15 @@ namespace GTPCorrgir
if (_instance == null)
{
_instance = new Opciones();
_instance.LLM = LLM_a_Usar.OpenAI;
_instance.modo = modoDeUso.Corregir;
}
return _instance;
}
}
public LLM_a_Usar LLM { get; set; }
public modoDeUso modo { get; set; }
public string nombreDeLLM() {
return nombreLLM[LLM];
@ -55,6 +64,7 @@ namespace GTPCorrgir
var application = new App();
// Aquí puedes procesar los argumentos
foreach (var arg in args)
{
if (arg.StartsWith("--"))
@ -64,8 +74,8 @@ namespace GTPCorrgir
Opciones.Instance.LLM = Opciones.LLM_a_Usar.Ollama;
else if (arg.StartsWith("--Groq"))
Opciones.Instance.LLM = Opciones.LLM_a_Usar.Groq;
else
Opciones.Instance.LLM = Opciones.LLM_a_Usar.OpenAI;
else if (arg.StartsWith("--Chat"))
Opciones.Instance.modo = Opciones.modoDeUso.Chat;
}
}

View File

@ -9,11 +9,12 @@ using LanguageDetection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Diagnostics;
using System.Windows.Interop;
namespace GTPCorrgir
{
internal class gtpask
public class gtpask
{
private readonly string openAiApiKey = "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";
private readonly string groqApiKey = "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";
@ -37,12 +38,18 @@ namespace GTPCorrgir
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 and markdown language if present. Please rewrite the following text in " + IdiomaDetectado + " and respond in the following JSON format: { 'Rewritten_text': 'Your text here' }.";
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\" }.";
}
private string CrearMensajeDeUsuario(string texto)
{
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;
}
@ -109,7 +116,9 @@ namespace GTPCorrgir
Log.Log("Respuesta: " + RespuestaLLM);
TextoCorregido = ExtractCorrectedText_UsingJObject(RespuestaLLM);
TextoCorregido = ExtraerValorUnicoJSON(RespuestaLLM);
if (TextoCorregido is null)
TextoCorregido = "Error en la respuesta.";
// Elimina comillas al principio y al final si existen
TextoCorregido = TextoCorregido.Trim('\"');
@ -118,33 +127,44 @@ namespace GTPCorrgir
}
}
static string ExtractCorrectedText_UsingJObject(string input)
public string ExtraerValorUnicoJSON(string input)
{
try
{
// Encuentra el índice del inicio y del final del JSON
// Encuentra los índices del inicio y del final del JSON
int startJson = input.IndexOf('{');
int endJson = input.IndexOf('}') + 1;
int endJson = input.LastIndexOf('}') + 1;
if (startJson == -1 || endJson == -1 || endJson <= startJson)
{
throw new Exception("No valid JSON found in the input string.");
return "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)
try
{
Console.WriteLine("An error occurred: " + ex.Message);
return input;
// 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)
{