Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Gemma Chatbot</title> | |
<style> | |
/* (Same CSS as before - good styling) */ | |
body { | |
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
min-height: 100vh; | |
margin: 0; | |
background-color: #f4f7f6; | |
} | |
h1 { | |
color: #333; | |
margin-bottom: 0.5em; | |
} | |
#chat-container { | |
width: 90%; | |
max-width: 700px; | |
border: none; | |
padding: 25px; | |
border-radius: 15px; | |
background-color: #fff; | |
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | |
overflow: hidden; | |
} | |
#chat-messages { | |
height: 400px; | |
overflow-y: auto; | |
margin-bottom: 15px; | |
padding: 15px; | |
border: 1px solid #e0e0e0; | |
border-radius: 10px; | |
background-color: #fafafa; | |
} | |
.message { | |
margin-bottom: 10px; | |
padding: 12px; | |
border-radius: 20px; | |
max-width: 70%; | |
word-wrap: break-word; | |
box-shadow: 0 1px 2px rgba(0,0,0,0.1); | |
} | |
.user-message { | |
background-color: #d4e5ff; | |
color: #000; | |
text-align: right; | |
align-self: flex-end; | |
margin-left: auto; | |
margin-right: 10px; | |
} | |
.bot-message { | |
background-color: #e5e5ea; | |
color: #000; | |
text-align: left; | |
align-self: flex-start; | |
margin-right: auto; | |
margin-left: 10px; | |
} | |
#input-container { | |
display: flex; | |
gap: 10px; | |
padding-top: 15px; | |
border-top: 1px solid #e0e0e0; | |
} | |
#user-input { | |
flex-grow: 1; | |
padding: 12px; | |
border: 1px solid #ccc; | |
border-radius: 20px; | |
font-size: 16px; | |
outline: none; | |
transition: border-color 0.2s ease-in-out; | |
} | |
#user-input:focus { | |
border-color: #007bff; | |
} | |
#send-button { | |
padding: 12px 25px; | |
background-color: #007bff; | |
color: white; | |
border: none; | |
border-radius: 20px; | |
cursor: pointer; | |
font-size: 16px; | |
transition: background-color 0.2s ease-in-out; | |
} | |
#send-button:hover { | |
background-color: #0056b3; | |
} | |
#send-button:disabled { | |
background-color: #cccccc; | |
cursor: not-allowed; | |
} | |
#loading-indicator { | |
display: none; | |
margin-top: 15px; | |
text-align: center; | |
color: #888; | |
font-style: italic; | |
} | |
.system-message { | |
display: none; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Gemma Chatbot</h1> | |
<div id="chat-container"> | |
<div id="chat-messages"> | |
<!-- Messages will appear here --> | |
</div> | |
<div id="input-container"> | |
<input type="text" id="user-input" placeholder="Type your message..." aria-label="Your message"> | |
<button id="send-button" aria-label="Send message">Send</button> | |
</div> | |
<div id="loading-indicator">Loading...</div> | |
</div> | |
<script type="module"> | |
import { pipeline, env } from "https://cdn.jsdelivr.net/npm/@huggingface/[email protected]/dist/transformers.js"; | |
// VERY IMPORTANT: Explicitly set the cache directory and allow remote models. | |
env.allowRemoteModels = true; // MUST be true to use models from the Hub | |
env.cacheDir = './cache'; // Or another directory if you prefer | |
const chatMessagesDiv = document.getElementById('chat-messages'); | |
const userInput = document.getElementById('user-input'); | |
const sendButton = document.getElementById('send-button'); | |
const loadingIndicator = document.getElementById('loading-indicator'); | |
let chatHistory = [ | |
{ role: "system", content: "You are a helpful assistant." }, | |
]; | |
let generator; | |
async function initializePipeline() { | |
loadingIndicator.style.display = 'block'; | |
try { | |
generator = await pipeline( | |
"text-generation", | |
"Xenova/gemma-1b-it-quantized", // Correct model name | |
{ | |
dtype: "q4", | |
// Add progress_callback to show loading progress. This is important for UX. | |
progress_callback: (progress) => { | |
if (progress.status === 'progress') { | |
let progressText = `Loading... ${progress.file} - ${Math.round(progress.loaded/1000000)}MB/${Math.round(progress.total/1000000)}MB`; | |
loadingIndicator.textContent = progressText | |
} | |
} | |
} | |
); | |
} catch (error) { | |
console.error("Error loading model:", error); | |
loadingIndicator.textContent = "Error loading model. Check console and ensure a modern browser."; | |
loadingIndicator.style.color = "red"; | |
sendButton.disabled = true; | |
return; | |
} | |
loadingIndicator.style.display = 'none'; | |
addMessage("bot", "Hello! I'm ready to chat. Ask me anything!"); | |
} | |
initializePipeline(); | |
function addMessage(role, content) { | |
const messageDiv = document.createElement('div'); | |
messageDiv.classList.add('message', `${role}-message`); | |
messageDiv.textContent = content; | |
chatMessagesDiv.appendChild(messageDiv); | |
chatMessagesDiv.scrollTop = chatMessagesDiv.scrollHeight; | |
if (role === 'user' || role === 'assistant') { | |
chatHistory.push({ role: role, content: content }); | |
} | |
} | |
async function sendMessage() { | |
const message = userInput.value.trim(); | |
if (!message || !generator) return; | |
addMessage('user', message); | |
userInput.value = ''; | |
loadingIndicator.style.display = 'block'; | |
sendButton.disabled = true; | |
try { | |
const output = await generator(chatHistory, { | |
max_new_tokens: 512, | |
do_sample: false // Try setting to `true` for varied responses | |
}); | |
const botResponse = output[0].generated_text.at(-1).content; | |
addMessage('assistant', botResponse); | |
} catch (error) { | |
console.error("Error generating response:", error); | |
addMessage('bot', "Sorry, I encountered an error. Please try again."); | |
} finally { | |
loadingIndicator.style.display = 'none'; | |
sendButton.disabled = false; | |
} | |
} | |
sendButton.addEventListener('click', sendMessage); | |
userInput.addEventListener('keypress', (event) => { | |
if (event.key === 'Enter') { | |
sendMessage(); | |
} | |
}); | |
</script> | |
</body> | |
</html> |