// Références aux éléments du DOM const messageArea = document.getElementById('message-area'); const inputForm = document.getElementById('input-form'); const userInput = document.getElementById('user-input'); const sendButton = document.getElementById('send-button'); const hfTokenInput = document.getElementById('hf-token-input'); // Configuration du modèle const MODEL_ID = "meta-llama/Meta-Llama-3-8B-Instruct"; const API_BASE_URL = "https://api-inference.huggingface.co/models/"; /** * Ajoute un message à la zone de chat. * @param {string} text Le contenu du message. * @param {string} sender 'user' ou 'bot'. */ function addMessage(text, sender) { const messageDiv = document.createElement('div'); messageDiv.classList.add('message', `${sender}-message`); messageDiv.textContent = text; messageArea.appendChild(messageDiv); messageArea.scrollTop = messageArea.scrollHeight; } /** * Gère la soumission du formulaire. * @param {Event} event L'événement de soumission. */ async function handleFormSubmit(event) { event.preventDefault(); const userMessage = userInput.value.trim(); const apiToken = hfTokenInput.value.trim(); if (!userMessage) return; if (!apiToken) { addMessage("Erreur : Veuillez entrer votre clé d'API Hugging Face pour continuer.", 'bot'); return; } addMessage(userMessage, 'user'); userInput.value = ''; userInput.style.height = 'auto'; sendButton.disabled = true; const typingIndicator = showTypingIndicator(); try { const response = await fetch(`${API_BASE_URL}${MODEL_ID}`, { method: 'POST', headers: { 'Authorization': `Bearer ${apiToken}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ inputs: userMessage, parameters: { max_new_tokens: 150, return_full_text: false, }, options: { wait_for_model: true // Important pour éviter les erreurs si le modèle est en chargement } }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || `Erreur HTTP : ${response.status}`); } const result = await response.json(); removeTypingIndicator(typingIndicator); const botResponse = result[0]?.generated_text; if (botResponse) { addMessage(botResponse.trim(), 'bot'); } else { throw new Error("La réponse de l'API est dans un format inattendu."); } } catch (error) { console.error("Erreur lors de l'appel à l'API:", error); removeTypingIndicator(typingIndicator); addMessage(`Désolé, une erreur est survenue : ${error.message}`, 'bot'); } finally { sendButton.disabled = false; userInput.focus(); } } /** Affiche l'indicateur de frappe */ function showTypingIndicator() { const indicatorDiv = document.createElement('div'); indicatorDiv.classList.add('message', 'typing-indicator'); indicatorDiv.innerHTML = ''; messageArea.appendChild(indicatorDiv); messageArea.scrollTop = messageArea.scrollHeight; return indicatorDiv; } /** Supprime l'indicateur de frappe */ function removeTypingIndicator(indicator) { if (indicator) { messageArea.removeChild(indicator); } } // Ajuste dynamiquement la hauteur du textarea userInput.addEventListener('input', () => { userInput.style.height = 'auto'; userInput.style.height = `${userInput.scrollHeight}px`; }); // Permet d'envoyer avec la touche "Entrée" userInput.addEventListener('keydown', (event) => { if (event.key === 'Enter' && !event.shiftKey) { event.preventDefault(); inputForm.requestSubmit(); } }); // Écouteur d'événement sur le formulaire inputForm.addEventListener('submit', handleFormSubmit);