package xx.xxxx.openaiaveclangchain.gpt;

import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import jakarta.enterprise.context.Dependent;

/**
 * Gère l'interface avec l'API OpenAI en utilisant LangChain4j.
 * Son rôle est essentiellement de lancer une requête à chaque nouvelle
 * question qu'on veut envoyer à l'API.
 *
 * De portée dépendent pour réinitialiser la conversation à chaque fois que
 * l'instance qui l'utilise est renouvelée.
 * Par exemple, si l'instance qui l'utilise est de portée View, la conversation est
 * réunitialisée à chaque fois que l'utilisateur quitte la page en cours.
 * Cette classe doit implémenter Serializable pour être injectée dans un bean JSF de portée View.
 */
@Dependent
public class OpenAiClient implements java.io.Serializable{
    /**
     * Modèle de l'API.
     */
    private String model = "gpt-3.5-turbo";

    private String systemRole;

    private Assistant assistant;

    private ChatMemory chatMemory;

    public OpenAiClient() {
        // Récupère la clé secrète pour travailler avec l'API d'OpenAI, mise dans une variable d'environnement
        // du système d'exploitation.
        String openAiKey = System.getenv("CHATGPT_KEY");
        // Par défaut c'est le modèle "gpt-3.5-turbo" qui est utilisé.
        // Si on voulait utiliser, par exemple, le modèle "gpt-4.0-turbo", et fixer la température à 0.5 (par défaut 0.7),
        // OpenAiChatModel model = 
        //      OpenAiChatModel.builder().apiKey(...).modelName("gpt-4.0-turbo").temperature(0.5).build();
        ChatLanguageModel model = OpenAiChatModel.withApiKey(openAiKey);
        this.chatMemory = MessageWindowChatMemory.withMaxMessages(10);
// AiServices crée un objet proxy de type Assistant (interface définie dans Assistant.java). this.assistant = AiServices.builder(Assistant.class) .chatLanguageModel(model) .chatMemory(chatMemory) .build(); } public void setSystemRole(String systemRole) { this.systemRole = systemRole; // Inutile ? chatMemory.add(new SystemMessage(systemRole)); } /** * Envoie une requête à l'API OpenAI. * @param question la question . * @return réponse de l'API (une String). */ public String envoyerRequete(String question) { // Envoie la requête pour la question return assistant.chat(question); } }