using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MercatorUi;
using MercatorApi;
using MercatorExtensions;
// <CompileWithRoslyn />
namespace MyAssembly
{
public static class ChatGPT
{
private const string tutosCollectionName = "Tutos";
public static async Task SearchInTutos()
{
MercatorAI.FactoryOpenAI factoryOpenAI = new MercatorAI.FactoryOpenAI();
MercatorAI.Interfaces.IOpenAiEmbeddingGeneratorClient openAiEmbeddingGeneratorClient = factoryOpenAI.CreateOpenAiEmbeddingGeneratorClient<string>("text-embedding-3-small", out string error);
if (!string.IsNullOrEmpty(error))
{
Dialogs.Stop("Kan de embeddings-generator van OpenAI niet initialiseren: " + error);
return;
}
MercatorAI.FactoryQdrant factoryQdrant = new MercatorAI.FactoryQdrant();
MercatorAI.Interfaces.IQdrantClient qdrantClient = factoryQdrant.CreateQdrantClient("http://192.168...:6334", out error);
if (!string.IsNullOrEmpty(error))
{
Dialogs.Stop("Kan de Qdrant-client niet initialiseren: " + error);
return;
}
MercatorUi.Wait.WaitStatic.WaitWindow(Api.Iif_langue(Globals.Langue, IifLangueEnum.AIisThinking));
if (!await qdrantClient.CollectionExistsAsync(tutosCollectionName))
{
qdrantClient.Dispose();
MercatorUi.Wait.WaitStatic.WaitClear();
Dialogs.Stop($"De collectie \"{tutosCollectionName}\" bestaat niet op de Qdrant-server!");
return;
}
MercatorUi.Forms.Other.ChatForm chatForm = MercatorUi.Forms.Other.ChatForm.SimpleOpenAiChat("gpt-4o", tutosCollectionName, systemMessage: null, question: "", false, chatOptions: null, standardStreamingAction: MercatorUi.Forms.Other.ChatForm.StandardStreamingActionEnum.RawStreamShow);
MercatorUi.Wait.WaitStatic.WaitClear();
if (chatForm == null)
{
qdrantClient.Dispose();
return;
}
chatForm.Disposed += (s, e) =>
{
qdrantClient.Dispose();
};
MercatorUi.Forms.Other.ChatForm.BeforeAskEventHandler beforeAskEventHandler = null;
beforeAskEventHandler = (s, e) =>
{
if (string.IsNullOrWhiteSpace(chatForm.TextBoxQuestion.Text))
{
_Divers.FocusError(chatForm.TextBoxQuestion);
return;
}
(double? score, DocChunk docChunk)[] hits = null;
MercatorUi.Wait.WaitStatic.WaitWindowBaseThread(Api.Iif_langue(Globals.Langue, IifLangueEnum.AIisThinking));
MercatorUi._BaseClasses.ExclusiveBackgroundWorkerAsync exclusiveBackgroundWorkerAsync = new MercatorUi._BaseClasses.ExclusiveBackgroundWorkerAsync(async () =>
{
float[] questionAsVectors = await openAiEmbeddingGeneratorClient.GenerateEmbeddingAsync(chatForm.TextBoxQuestion.Text);
hits = await qdrantClient.ClientSearchAsync<Guid, DocChunk>(tutosCollectionName, questionAsVectors, top: 5);
}, formWhereToCenterLoadingCircle: chatForm);
MercatorUi.Wait.WaitStatic.WaitClearBaseThread();
if (exclusiveBackgroundWorkerAsync.ExceptionDuringDoWork != null)
{
Dialogs.Stop(exclusiveBackgroundWorkerAsync.ExceptionDuringDoWork.Message, chatForm);
return;
}
if ((hits == null) || !hits.Any())
{
Dialogs.Stop("Geen overeenkomst gevonden in de documentatie!", chatForm);
return;
}
var sb = new StringBuilder();
foreach ((double? score, DocChunk docChunk) hit in hits)
{
sb.AppendLine(hit.docChunk.Content);
}
chatForm.SimpleChatSystemMessage = "Je bent een assistent. Antwoord uitsluitend op basis van de CONTEXT die is gehaald uit tutorials waarin bepaalde boekhoudprocedures in ons bedrijf worden uitgelegd. Als de info er niet is, zeg dit dan duidelijk. \nCONTEXT:\n" + sb;
chatForm.BeforeAsk -= beforeAskEventHandler; // SimpleChatSystemMessage enkel bij de eerste interactie in de chat
};
chatForm.BeforeAsk += beforeAskEventHandler;
}
}
}