`;
container.classList.add("show");
// Ajouter les event listeners pour les boutons markdown-toggle
setupMarkdownToggleListeners(container);
// Animation d'entrée
const resultCard = container.querySelector(".result-card");
resultCard.style.transform = "translateY(20px)";
resultCard.style.opacity = "0";
setTimeout(() => {
resultCard.style.transform = "translateY(0)";
resultCard.style.opacity = "1";
}, 10);
}
// Fonction pour configurer les event listeners des boutons markdown
function setupMarkdownToggleListeners(container) {
// Event listeners pour les boutons markdown toggle
const toggleButtons = container.querySelectorAll(".markdown-toggle");
toggleButtons.forEach((button) => {
button.removeEventListener("click", handleMarkdownToggleClick);
button.addEventListener("click", handleMarkdownToggleClick);
});
// Event listeners pour les boutons de copie
const copyButtons = container.querySelectorAll(".copy-text-btn");
copyButtons.forEach((button) => {
button.removeEventListener("click", handleCopyTextClick);
button.addEventListener("click", handleCopyTextClick);
});
}
// Event handler pour les clics sur les boutons markdown toggle
function handleMarkdownToggleClick(event) {
event.preventDefault();
handleMarkdownToggle(event.target);
}
// Event handler pour les clics sur les boutons de copie
function handleCopyTextClick(event) {
event.preventDefault();
const textToCopy = decodeHtml(event.target.dataset.text);
copyToClipboard(textToCopy);
}
function formatErrorResult(error) {
let errorMessage = "Une erreur inattendue s'est produite";
let suggestions = [];
if (typeof error === "object" && error.error) {
errorMessage = error.error;
// Suggestions basées sur le type d'erreur
if (errorMessage.includes("API non connectée")) {
suggestions.push("Vérifiez que le serveur API est démarré");
suggestions.push("Testez la connexion avec le bouton 'Tester la connexion'");
} else if (errorMessage.includes("requis")) {
suggestions.push("Assurez-vous que tous les champs obligatoires sont remplis");
} else if (errorMessage.includes("MASK")) {
suggestions.push("Utilisez [MASK] dans votre texte pour le fill-mask");
} else if (errorMessage.includes("CUDA out of memory") || errorMessage.includes("mémoire")) {
suggestions.push("🔧 Essayez un modèle plus petit (GPT-2 au lieu de GPT-2 Medium)");
suggestions.push("📉 Réduisez le nombre de tokens à générer");
suggestions.push("🔢 Réduisez le nombre de séquences à générer");
suggestions.push("💻 Le modèle utilisera automatiquement le CPU si le GPU manque de mémoire");
} else if (errorMessage.includes("model") || errorMessage.includes("modèle")) {
suggestions.push("Essayez avec le modèle par défaut");
suggestions.push("Vérifiez que le nom du modèle est correct");
}
}
let suggestionsHtml = "";
if (suggestions.length > 0) {
suggestionsHtml = `
💡 Suggestions:
${suggestions.map((s) => `
${s}
`).join("")}
`;
}
return `
Message d'erreur:
${errorMessage}
${suggestionsHtml}
`;
}
function formatResult(data, containerId) {
const type = containerId.replace("Result", "");
switch (type) {
case "sentiment":
return formatSentimentResult(data);
case "ner":
return formatNerResult(data);
case "qa":
return formatQaResult(data);
case "fillmask":
return formatFillmaskResult(data);
case "moderation":
return formatModerationResult(data);
case "textgen":
return formatTextgenResult(data);
case "batch":
return formatBatchResult(data);
default:
return `
`;
}
// Fonctions de traitement pour chaque endpoint
async function analyzeSentiment(event) {
event.preventDefault();
showLoading("sentimentResult");
const text = document.getElementById("sentimentText").value.trim();
const model = document.getElementById("sentimentModel").value;
if (!text) {
showResult("sentimentResult", { error: "Le texte est requis" }, true);
return;
}
try {
const data = { text };
if (model) data.model_name = model;
const result = await makeApiRequest("/sentiment", data);
showResult("sentimentResult", result);
} catch (error) {
showResult("sentimentResult", { error: error.message }, true);
}
}
async function analyzeNER(event) {
event.preventDefault();
showLoading("nerResult");
const text = document.getElementById("nerText").value.trim();
const model = document.getElementById("nerModel").value;
if (!text) {
showResult("nerResult", { error: "Le texte est requis" }, true);
return;
}
try {
const data = { text };
if (model) data.model_name = model;
const result = await makeApiRequest("/ner", data);
showResult("nerResult", result);
} catch (error) {
showResult("nerResult", { error: error.message }, true);
}
}
async function answerQuestion(event) {
event.preventDefault();
showLoading("qaResult");
const question = document.getElementById("qaQuestion").value.trim();
const context = document.getElementById("qaContext").value.trim();
const model = document.getElementById("qaModel").value;
if (!question || !context) {
showResult("qaResult", { error: "La question et le contexte sont requis" }, true);
return;
}
try {
const data = { question, context };
if (model) data.model_name = model;
const result = await makeApiRequest("/qa", data);
showResult("qaResult", result);
} catch (error) {
showResult("qaResult", { error: error.message }, true);
}
}
async function fillMask(event) {
event.preventDefault();
showLoading("fillmaskResult");
const text = document.getElementById("fillmaskText").value.trim();
const model = document.getElementById("fillmaskModel").value;
if (!text) {
showResult("fillmaskResult", { error: "Le texte est requis" }, true);
return;
}
if (!text.includes("[MASK]")) {
showResult("fillmaskResult", { error: "Le texte doit contenir [MASK]" }, true);
return;
}
try {
const data = { text };
if (model) data.model_name = model;
const result = await makeApiRequest("/fillmask", data);
showResult("fillmaskResult", result);
} catch (error) {
showResult("fillmaskResult", { error: error.message }, true);
}
}
async function moderateContent(event) {
event.preventDefault();
showLoading("moderationResult");
const text = document.getElementById("moderationText").value.trim();
const model = document.getElementById("moderationModel").value;
if (!text) {
showResult("moderationResult", { error: "Le texte est requis" }, true);
return;
}
try {
const data = { text };
if (model) data.model_name = model;
const result = await makeApiRequest("/moderation", data);
showResult("moderationResult", result);
} catch (error) {
showResult("moderationResult", { error: error.message }, true);
}
}
async function generateText(event) {
event.preventDefault();
showLoading("textgenResult");
const text = document.getElementById("textgenPrompt").value.trim();
const systemPrompt = document.getElementById("textgenSystemPrompt").value.trim();
const model = document.getElementById("textgenModel").value;
const maxNewTokens = parseInt(document.getElementById("maxNewTokens").value) || 500;
const numReturnSequences = parseInt(document.getElementById("numReturnSequences").value) || 1;
const temperature = parseFloat(document.getElementById("temperature").value) || 1.0;
const doSample = document.getElementById("doSample").checked;
if (!text) {
showResult("textgenResult", { error: "Le prompt est requis" }, true);
return;
}
// Validate parameters
if (maxNewTokens < 1 || maxNewTokens > 2048) {
showResult("textgenResult", { error: "Le nombre de tokens doit être entre 1 et 2048" }, true);
return;
}
if (numReturnSequences < 1 || numReturnSequences > 5) {
showResult("textgenResult", { error: "Le nombre de séquences doit être entre 1 et 5" }, true);
return;
}
if (temperature < 0.1 || temperature > 2.0) {
showResult("textgenResult", { error: "La température doit être entre 0.1 et 2.0" }, true);
return;
}
try {
const data = {
text,
max_new_tokens: maxNewTokens,
num_return_sequences: numReturnSequences,
temperature: temperature,
do_sample: doSample
};
// Add system prompt if provided
if (systemPrompt) {
data.system_prompt = systemPrompt;
}
if (model) {
data.model_name = model;
}
const result = await makeApiRequest("/textgen", data);
showResult("textgenResult", result);
} catch (error) {
showResult("textgenResult", { error: error.message }, true);
}
}
async function processBatch() {
showLoading("batchResult");
const type = document.getElementById("batchType").value;
const textsInput = document.getElementById("batchTexts").value.trim();
if (!textsInput) {
showResult("batchResult", { error: "Les textes sont requis" }, true);
return;
}
const texts = textsInput
.split("\n")
.filter((line) => line.trim())
.map((line) => line.trim());
if (texts.length === 0) {
showResult("batchResult", { error: "Aucun texte valide fourni" }, true);
return;
}
try {
const data = { texts };
const result = await makeApiRequest(`/${type}/batch`, data);
showResult("batchResult", result);
} catch (error) {
showResult("batchResult", { error: error.message }, true);
}
}
// Exemples prédéfinis (en anglais pour optimiser la compatibilité avec les modèles)
const examples = {
sentiment: "I love this project! It's really well designed and useful for testing NLP APIs.",
ner: "Apple Inc. is an American multinational technology company headquartered in Cupertino, California. Tim Cook is the current CEO of Apple.",
qa: {
question: "What is the capital of France?",
context:
"France is a country located in Western Europe. Paris is the capital and largest city of France. The city is famous for the Eiffel Tower and the Louvre Museum."
},
fillmask: "The capital of France is [MASK].",
moderation: "This project is fantastic! Thank you for this excellent work.",
textgen: {
prompt: "Generate 10 ideas of what to build with a rapsberry pi",
systemPrompt: "You are a helpful AI assistant. Format your responses using complex Markdown (Title, lists etc..). Be clear and structured."
},
batch: `I love this product!
This is really terrible.
Not bad at all.
Excellent work!
I hate all of this.`
};
function loadExample(type) {
const example = examples[type];
if (!example) return;
switch (type) {
case "sentiment":
document.getElementById("sentimentText").value = example;
break;
case "ner":
document.getElementById("nerText").value = example;
break;
case "qa":
document.getElementById("qaQuestion").value = example.question;
document.getElementById("qaContext").value = example.context;
break;
case "fillmask":
document.getElementById("fillmaskText").value = example;
break;
case "moderation":
document.getElementById("moderationText").value = example;
break;
case "textgen":
if (typeof example === "object") {
document.getElementById("textgenPrompt").value = example.prompt;
document.getElementById("textgenSystemPrompt").value = example.systemPrompt;
} else {
document.getElementById("textgenPrompt").value = example;
}
break;
case "batch":
document.getElementById("batchTexts").value = example;
break;
}
}
function loadExamplesData() {
// Cette fonction peut être étendue pour charger des exemples depuis une source externe
console.log("Exemples chargés");
}
// Fonctions utilitaires pour l'UX
function getSentimentInterpretation(sentiment, confidence) {
const confidenceLevel = confidence > 0.8 ? "très élevée" : confidence > 0.6 ? "élevée" : confidence > 0.4 ? "modérée" : "faible";
let interpretation = "";
if (sentiment?.toLowerCase() === "positive") {
interpretation = `😊 Le texte exprime un sentiment positif avec une confiance ${confidenceLevel}.`;
} else if (sentiment?.toLowerCase() === "negative") {
interpretation = `😔 Le texte exprime un sentiment négatif avec une confiance ${confidenceLevel}.`;
} else {
interpretation = `😐 Le sentiment du texte est neutre avec une confiance ${confidenceLevel}.`;
}
return `
${interpretation}
`;
}
function copyToClipboard(text) {
navigator.clipboard
.writeText(text)
.then(() => {
showNotification("📋 Texte copié dans le presse-papiers!", "success", 2000);
})
.catch(() => {
showNotification("❌ Impossible de copier le texte", "error", 2000);
});
}
function copyResultToClipboard(containerId) {
const container = document.getElementById(containerId);
const resultData = container.querySelector(".result-json");
if (resultData) {
copyToClipboard(resultData.textContent);
}
}
function toggleResultDetails(containerId) {
const container = document.getElementById(containerId);
const details = container.querySelector(".result-details");
if (details) {
details.open = !details.open;
}
}
function regenerateText() {
const currentPrompt = document.getElementById("textgenPrompt").value;
if (currentPrompt) {
const form = document.querySelector("#textgen form");
const event = new Event("submit");
generateText(event);
}
}
// Amélioration des fonctions de traitement avec feedback
async function analyzeSentiment(event) {
event.preventDefault();
showLoading("sentimentResult");
const text = document.getElementById("sentimentText").value.trim();
const model = document.getElementById("sentimentModel").value;
if (!text) {
showResult("sentimentResult", { error: "Le texte est requis pour l'analyse de sentiment" }, true);
return;
}
try {
showNotification("🔄 Analyse de sentiment en cours...", "info", 2000);
const data = { text };
if (model) data.model_name = model;
const result = await makeApiRequest("/sentiment", data);
showResult("sentimentResult", result);
showNotification("✅ Analyse de sentiment terminée!", "success", 3000);
} catch (error) {
showResult("sentimentResult", { error: error.message }, true);
showNotification("❌ Erreur lors de l'analyse de sentiment", "error", 4000);
}
}
async function analyzeNER(event) {
event.preventDefault();
showLoading("nerResult");
const text = document.getElementById("nerText").value.trim();
const model = document.getElementById("nerModel").value;
if (!text) {
showResult("nerResult", { error: "Le texte est requis pour la reconnaissance d'entités" }, true);
return;
}
try {
showNotification("🔄 Reconnaissance d'entités en cours...", "info", 2000);
const data = { text };
if (model) data.model_name = model;
const result = await makeApiRequest("/ner", data);
showResult("nerResult", result);
const entityCount = result.entities ? result.entities.length : 0;
showNotification(`✅ ${entityCount} entité(s) détectée(s)!`, "success", 3000);
} catch (error) {
showResult("nerResult", { error: error.message }, true);
showNotification("❌ Erreur lors de la reconnaissance d'entités", "error", 4000);
}
}
async function answerQuestion(event) {
event.preventDefault();
showLoading("qaResult");
const question = document.getElementById("qaQuestion").value.trim();
const context = document.getElementById("qaContext").value.trim();
const model = document.getElementById("qaModel").value;
if (!question || !context) {
showResult("qaResult", { error: "La question et le contexte sont requis" }, true);
return;
}
try {
showNotification("🔄 Recherche de réponse en cours...", "info", 2000);
const data = { question, context };
if (model) data.model_name = model;
const result = await makeApiRequest("/qa", data);
showResult("qaResult", result);
showNotification("✅ Réponse trouvée!", "success", 3000);
} catch (error) {
showResult("qaResult", { error: error.message }, true);
showNotification("❌ Erreur lors de la recherche de réponse", "error", 4000);
}
}