gemma-chatbot / index.js
akhaliq's picture
akhaliq HF Staff
Upload index.js with huggingface_hub
e9d3310 verified
import { pipeline, TextStreamer } from 'https://cdn.jsdelivr.net/npm/@huggingface/[email protected]';
class GemmaChatbot {
constructor() {
this.generator = null;
this.messages = [
{ role: "system", content: "You are a helpful, friendly AI assistant. Keep your responses concise and helpful." }
];
this.isGenerating = false;
this.initializeElements();
this.initializeModel();
}
initializeElements() {
this.chatMessages = document.getElementById('chatMessages');
this.userInput = document.getElementById('userInput');
this.sendButton = document.getElementById('sendButton');
this.loadingIndicator = document.getElementById('loadingIndicator');
this.sendButton.addEventListener('click', () => this.sendMessage());
this.userInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
this.sendMessage();
}
});
}
async initializeModel() {
try {
console.log('Initializing Gemma model...');
this.generator = await pipeline(
'text-generation',
'onnx-community/gemma-3-270m-it-ONNX',
{ dtype: 'fp32' }
);
console.log('Model loaded successfully');
this.enableChat();
} catch (error) {
console.error('Failed to initialize model:', error);
this.showError('Failed to load AI model. Please refresh the page to try again.');
}
}
enableChat() {
this.loadingIndicator.style.display = 'none';
this.userInput.disabled = false;
this.sendButton.disabled = false;
this.userInput.focus();
}
addMessage(content, isUser = false) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${isUser ? 'user' : 'assistant'}`;
const contentDiv = document.createElement('div');
contentDiv.className = 'message-content';
contentDiv.textContent = content;
messageDiv.appendChild(contentDiv);
this.chatMessages.appendChild(messageDiv);
this.scrollToBottom();
return contentDiv;
}
scrollToBottom() {
this.chatMessages.scrollTop = this.chatMessages.scrollHeight;
}
async sendMessage() {
const message = this.userInput.value.trim();
if (!message || this.isGenerating || !this.generator) return;
this.isGenerating = true;
this.userInput.value = '';
this.userInput.disabled = true;
this.sendButton.disabled = true;
// Add user message
this.addMessage(message, true);
this.messages.push({ role: "user", content: message });
// Add assistant message placeholder
const assistantMessageDiv = document.createElement('div');
assistantMessageDiv.className = 'message assistant';
const contentDiv = document.createElement('div');
contentDiv.className = 'message-content';
const typingIndicator = document.createElement('span');
typingIndicator.className = 'typing-indicator';
typingIndicator.innerHTML = '<span></span><span></span><span></span>';
contentDiv.appendChild(typingIndicator);
assistantMessageDiv.appendChild(contentDiv);
this.chatMessages.appendChild(assistantMessageDiv);
this.scrollToBottom();
try {
let fullResponse = '';
// Create custom streamer
const streamer = new TextStreamer(this.generator.tokenizer, {
skip_prompt: true,
skip_special_tokens: true,
callback_function: (text) => {
fullResponse += text;
contentDiv.textContent = fullResponse;
this.scrollToBottom();
}
});
// Generate response
const output = await this.generator(this.messages, {
max_new_tokens: 256,
do_sample: true,
temperature: 0.7,
top_p: 0.9,
streamer: streamer
});
const generatedContent = output[0].generated_text.at(-1).content;
this.messages.push({ role: "assistant", content: generatedContent });
// Ensure final content is displayed
contentDiv.textContent = generatedContent;
} catch (error) {
console.error('Generation error:', error);
contentDiv.textContent = 'Sorry, I encountered an error. Please try again.';
} finally {
this.isGenerating = false;
this.userInput.disabled = false;
this.sendButton.disabled = false;
this.userInput.focus();
}
}
showError(message) {
this.loadingIndicator.innerHTML = `
<div class="error-message">
<p>⚠️ ${message}</p>
</div>
`;
}
}
// Initialize chatbot when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
new GemmaChatbot();
});