In de HTML-editor koppelingen toevoegen met ChatGPT om spelling te controleren en formuleringen te herzien

0000003309     -      22-10-2025

De hier beschreven code maakt het mogelijke om in de HTML-editor twee toegangen toe te voegen die een koppeling met ChatGPT aanbieden voor 

  • het controleren van de spelling
  • het herzien van de formulering

Voor de herformulering vraagt Mercator eerst naar de context die men aan ChatGPT wil meegeven om de formulering bij te sturen. In beide situaties, zodra een resultaat beschikbaar is:

  • de knop "OK" laat toe het voorstel van ChatGPT te accepteren.
  • de knop "Annuleren" stopt het proces en behoudt de oorspronkelijke tekst.
  • de knop "Ondervragen" maakt het mogelijk een bijkomende vraag te stellen en een nieuwe instructie mee te geven via het veld onderaan dit scherm.

Dit vereist de installatie van de plugin MercatorAI.OpenAI en werkt alleen met een Core-versie van Mercator. (De code is echter ook compileerbaar in een klassieke versie).

De code is als volgt:
Zoom
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using MercatorApi;
using MercatorUi;
using MercatorExtensions;
using MercatorDatabase;
using MercatorAI;

// <CompileWithRoslyn />

namespace Action
{
    public class Customizer : MercatorUi.ICustomizers.IActionEngineCreated, MercatorUi.ICustomizers.IActionEngineClosed
    {
        public void ActionEngineCreated(MercatorUi.Engine.Crm.ActionEngine actionEngine)
        {
            actionEngine.ActionFormLoaded += actionEngine_ActionFormLoaded;
        }

        public void ActionEngineClosed(MercatorUi.Engine.Crm.ActionEngine actionEngine)
        {
            actionEngine.ActionFormLoaded -= actionEngine_ActionFormLoaded;
        }

        void actionEngine_ActionFormLoaded(object sender, EventArgs arg)
        {
            MercatorUi.Engine.Crm.ActionEngine actionEngine = (MercatorUi.Engine.Crm.ActionEngine)sender;
            foreach (MercatorUi.MovableControls.MovableHtmlBox2 htmlBox in actionEngine.ActionForm.MovableControls.Values.OfType<MercatorUi.MovableControls.MovableHtmlBox2>())
            {
                ToolStripDropDownButton toolStripDropDownButtonAI = new ToolStripDropDownButton("", GraphicKit.CurrentGraphicKit.Images.AI16) { AutoSize = true, Padding = new Padding(3) };

                ToolStripItem[] items = new ToolStripItem[2]
                {
                    new ToolStripSeparator(),
                    toolStripDropDownButtonAI
                };
                htmlBox.AddToolStripItems(items);

                ToolStripMenuItem menuItemSpelling = new ToolStripMenuItem(_Divers.Iif_langue(Globals.Langue, "Rechtschreibung prüfen", "Check spelling", "Spelling controleren", "Vérifier orthographe"), null, (s, e) =>
                {
                    string htmlText = System.Net.WebUtility.HtmlDecode(htmlBox.HtmlText);
                    if (string.IsNullOrWhiteSpace(htmlText))
                        return;

                    FactoryOpenAI factory = new FactoryOpenAI();
                    MercatorAI.Interfaces.IOpenAiChat openAiChat = factory.CreateOpenAiChat("gpt-4o-mini", out string error);
                    if (!string.IsNullOrEmpty(error))
                    {
                        Dialogs.Stop("Kan de OpenAI-chat niet initialiseren: " + error, actionEngine.ActionForm);
                        return;
                    }

                    string systemMessage = _Divers.Iif_langue(Globals.Langue,
                        "Du bist ein Experte für Rechtschreibung. Du antwortest ausschließlich in der angeforderten JSON-Struktur.",
                        "You are an expert in spelling. You respond only in the requested JSON structure.",
                        "Je bent een expert in spelling. Je antwoordt uitsluitend in de gevraagde JSON-structuur.",
                        "Tu es un expert en orthographe. Tu réponds uniquement dans la structure json demandée.");

                    string prompt = _Divers.Iif_langue(Globals.Langue, "Kannst du die Rechtschreibfehler in diesem Text korrigieren, ohne den Stil zu ändern?", "Can you correct the spelling mistakes in this text without changing the style?", "Kan je de spelfouten in deze tekst corrigeren zonder de stijl te wijzigen?", "Peux-tu corriger les fautes d'orthographe dans ce texte sans modifier le style.") + "\n" + htmlText;

                    FactoryOpenAI
.ChatOptions chatOptions = newFactoryOpenAI.ChatOptions
                    {
                        Temperature = 0f, // deterministisch
                        TopP = 1.0f // Geen noodzaak tot verdere beperkingen, de temperatuur is voldoende
                    };

                    while (true)
                    {
                        ResponseDescriptor r = null;
                        MercatorUi.Wait.WaitStatic.WaitWindowBaseThread(Api.Iif_langue(Globals.Langue, IifLangueEnum.AIisThinking));
                        MercatorUi._BaseClasses.ExclusiveBackgroundWorkerAsync exclusiveBackgroundWorkerAsync = new MercatorUi._BaseClasses.ExclusiveBackgroundWorkerAsync(async () => r = await openAiChat.AskAsync<ResponseDescriptor>(prompt, "SpellCheck", systemMessage: systemMessage, chatOptions: chatOptions), formWhereToCenterLoadingCircle: actionEngine.ActionForm);
                        MercatorUi.Wait.WaitStatic.WaitClearBaseThread();
                        if (exclusiveBackgroundWorkerAsync.ExceptionDuringDoWork != null)
                        {
                            Dialogs.Stop(exclusiveBackgroundWorkerAsync.ExceptionDuringDoWork.Message, actionEngine.ActionForm);
                            return;
                        }
                        if (r.IsCorrect)
                        {
                            Dialogs.Stop(_Divers.Iif_langue(Globals.Langue, "Der Text darf nicht verändert werden!", "The text must not be modified!", "De tekst mag niet worden gewijzigd!", "Le texte ne doit pas être modifié !"), actionEngine.ActionForm);
                            return;
                        }
                        systemMessage = null;
                        DialogResult dialogResult = Dialogs.MiniChat(r.Comment, r.Content, out prompt);
                        if (dialogResult == DialogResult.Cancel)
                        {
                            return;
                        }
                        else if (dialogResult == DialogResult.OK)
                        {
                            htmlBox.HtmlText = r.Content;
                            return;
                        }   
                    }
                });

                ToolStripMenuItem menuItemReformulate = new ToolStripMenuItem(_Divers.Iif_langue(Globals.Langue, "Text umformulieren", "Reformulate text", "Tekst herformuleren", "Reformuler texte"), null, (s, e) =>
                {
                    string htmlText = System.Net.WebUtility.HtmlDecode(htmlBox.HtmlText);
                    if (string.IsNullOrWhiteSpace(htmlText))
                        return;

                    FactoryOpenAI factory = new FactoryOpenAI();
                    MercatorAI.Interfaces.IOpenAiChat openAiChat = factory.CreateOpenAiChat("gpt-4o-mini", out string error);
                    if (!string.IsNullOrEmpty(error))
                    {
                        Dialogs.Stop("Kan de OpenAI-chat niet initialiseren: " + error, actionEngine.ActionForm);
                        return;
                    }

                    string systemMessage = _Divers.Iif_langue(Globals.Langue,
                        "Du bist ein Assistent für Texterstellung. Du formulierst diesen Text für den angegebenen Kontext um.",
                        "You are a writing assistant. You rephrase this text for the given context.",
                        "Je bent een tekstschrijfassistent. Je herformuleert deze tekst voor de aangegeven context.",
                        "Tu es un assistant en rédaction de texte. Tu reformules ce texte pour le contexte indiqué.");

                    string prompt = Dialogs.AskMemo(_Divers.Iif_langue(Globals.Langue, "Ihre Anweisung für die KI?", "Your instruction for the AI?", "Uw instructie voor de AI?", "Votre consigne pour l'IA ?"),
                        _Divers.Iif_langue(Globals.Langue, "Formulieren Sie den Text um, um ihn professioneller zu gestalten.", "Revise the wording to make it more professional.", "Herformuleer de tekst om deze professioneler te maken.", "Revoir la formulation pour la rendre plus professionnelle."));
                    if (string.IsNullOrWhiteSpace(prompt))
                        return;
                    prompt += "\n" + htmlText;

                    FactoryOpenAI.ChatOptions chatOptions = newFactoryOpenAI.ChatOptions
                    {
                        Temperature = 0.2f, // Zeer sobere herformulering / dicht bij de oorspronkelijke tekst
                        TopP = 1.0f // Het is niet nodig om het probabilistische spectrum af te korten, want dat zou de nuances onnodig beperken.
                    };


                    while (true)
                    {
                        ResponseDescriptor r = null;
                        MercatorUi.Wait.WaitStatic.WaitWindowBaseThread(Api.Iif_langue(Globals.Langue, IifLangueEnum.AIisThinking));
                        MercatorUi._BaseClasses.ExclusiveBackgroundWorkerAsync exclusiveBackgroundWorkerAsync = new MercatorUi._BaseClasses.ExclusiveBackgroundWorkerAsync(async () => r = await openAiChat.AskAsync<ResponseDescriptor>(prompt, "Reformulate", systemMessage: systemMessage, chatOptions: chatOptions), formWhereToCenterLoadingCircle: actionEngine.ActionForm);
                        MercatorUi.Wait.WaitStatic.WaitClearBaseThread();
                        if (exclusiveBackgroundWorkerAsync.ExceptionDuringDoWork != null)
                        {
                            Dialogs.Stop(exclusiveBackgroundWorkerAsync.ExceptionDuringDoWork.Message, actionEngine.ActionForm);
                            return;
                        }
                        if (r.IsCorrect)
                        {
                            Dialogs.Stop(_Divers.Iif_langue(Globals.Langue, "Der Text darf nicht verändert werden!", "The text must not be modified!", "De tekst mag niet worden gewijzigd!", "Le texte ne doit pas être modifié !"), actionEngine.ActionForm);
                            return;
                        }
                        systemMessage = null;
                        DialogResult dialogResult = Dialogs.MiniChat(r.Comment, r.Content, out prompt);
                        if (dialogResult == DialogResult.Cancel)
                        {
                            return;
                        }
                        else if (dialogResult == DialogResult.OK)
                        {
                            htmlBox.HtmlText = r.Content;
                            return;
                        }
                    }
                });
                toolStripDropDownButtonAI.DropDownItems.AddRange(new ToolStripItem[] { menuItemSpelling, menuItemReformulate });
            }
        }
    }
    
    public class ResponseDescriptor
    {
        [FactoryOpenAI.ChatJsonFormat(DescriptionF = "True si le texte ne doit pas être modifié", DescriptionN = "True als de tekst niet gewijzigd hoeft te worden", DescriptionE = "True if the text does not need to be modified", DescriptionD = "True, wenn der Text nicht geändert werden muss", IsRequired = false)]
        public bool IsCorrect { get; set; }
        [FactoryOpenAI.ChatJsonFormat(DescriptionF = "Contenu HTML corrigé/modifié", DescriptionN = "Gewijzigde/gecorrigeerde HTML-inhoud", DescriptionE = "Corrected/modified HTML content", DescriptionD = "Korrigierter/geänderter HTML-Inhalt", IsRequired = false)]
        public string Content { get; set; }
        [FactoryOpenAI.ChatJsonFormat(DescriptionF = "Commentaire ou remarque", DescriptionN = "Commentaar of opmerking", DescriptionE = "Comment or remark", DescriptionD = "Kommentar oder Bemerkung", IsRequired = false)]
        public string Comment { get; set; }
    }
}

 

 

 De te corrigeren gegevens worden verzonden naar een derde partij (OpenAI). Er mogen dus geen vertrouwelijke gegevens worden doorgestuurd. 

De correcties die door deze code worden gegenereerd, zijn automatisch gegenereerd met behulp van een model voor kunstmatige intelligentie (AI). Hoewel het ontworpen is om nuttige en relevante antwoorden te geven, kunnen deze correcties onvolledig, onjuist of gedeeltelijk fout zijn.

De gebruiker blijft als enige verantwoordelijk voor de evaluatie en het gebruik van deze correcties. Mercator of de leverancier van de AI-dienst kan in geen geval aansprakelijk worden gesteld voor de gevolgen van het gebruik van deze correcties.

Het gebruik van deze dienst moet compatibel zijn met de GDPR-voorschriften die binnen het bedrijf van toepassing zijn.



Functionele cookies: Cookies die nodig zijn voor het gebruik van de website en voorkeurscookies. Ze bevatten geen persoonsgegevens. (Meer informatie)

Analytische cookies: Verzamelen van statistieken met betrekking tot het gedrag van internetgebruikers. (Meer informatie)

Marketingcookies: Om bezoekers op verschillende websites te volgen voor advertentiedoeleinden. (Meer informatie)