anycoder-b95e2145 / index.html
Shivam098's picture
Upload index.html with huggingface_hub
cc1f4f2 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Chat Canvas - Powered by Transformers.js</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="app-container">
<!-- Header -->
<header class="app-header">
<div class="header-content">
<div class="logo-area">
<svg class="logo-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2zm0 18a8 8 0 1 1 8-8 8 8 0 0 1-8 8z"/>
<path d="M12 6v6l4 2"/>
</svg>
<h1>AI Chat Canvas</h1>
</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="attribution-link">
Built with anycoder
</a>
</div>
<!-- Model Status -->
<div class="model-status" id="model-status">
<span class="status-dot"></span>
<span class="status-text">Initializing...</span>
</div>
</header>
<!-- Main Content -->
<main class="main-content">
<!-- Chat Messages -->
<div class="chat-container" id="chat-container">
<div class="welcome-screen" id="welcome-screen">
<div class="welcome-icon">🤖</div>
<h2>Welcome to AI Chat Canvas</h2>
<p>This is a browser-based chat application running entirely on your device using transformers.js.</p>
<div class="example-prompts">
<p class="example-label">Try asking:</p>
<button class="example-btn" data-prompt="Explain quantum computing in simple terms">What is quantum computing?</button>
<button class="example-btn" data-prompt="Write a Python function to sort a list">Help me write Python code</button>
<button class="example-btn" data-prompt="What are the benefits of remote work?">Discuss remote work benefits</button>
</div>
</div>
<div class="messages-list" id="messages-list"></div>
<!-- Loading Indicator -->
<div class="loading-indicator hidden" id="loading-indicator">
<div class="spinner"></div>
<div class="loading-text">
<span class="loading-dot"></span>
<span class="loading-dot"></span>
<span class="loading-dot"></span>
</div>
<p id="loading-message">Loading model...</p>
<div class="progress-bar" id="progress-bar">
<div class="progress-fill" id="progress-fill"></div>
</div>
</div>
</div>
</main>
<!-- Input Area -->
<footer class="input-area">
<div class="input-wrapper">
<textarea
id="user-input"
placeholder="Type your message here... (Shift+Enter for new line)"
rows="1"
></textarea>
<button id="send-btn" class="send-btn" disabled>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="22" y1="2" x2="11" y2="13"></line>
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
</svg>
</button>
</div>
<div class="disclaimer">
<p>AI responses may be inaccurate. Please verify important information.</p>
</div>
</footer>
</div>
<script type="module">
// ============================================
// WORKER CODE (Inline for single-file deployment)
// ============================================
const workerScript = `
import { pipeline, env } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.8.0';
// Configure environment
env.allowLocalModels = false;
env.useBrowserCache = true;
let generator = null;
let currentAbortController = null;
self.onmessage = async (e) => {
const { type, payload } = e.data;
if (type === 'load') {
currentAbortController = new AbortController();
try {
self.postMessage({
type: 'loading',
progress: 0,
message: 'Initializing model...'
});
// Load text generation pipeline
generator = await pipeline('text-generation', payload.model, {
progress_callback: (data) => {
if (data.status === 'progress') {
self.postMessage({
type: 'progress',
progress: data.progress,
message: data.file ? \`Downloading: \${data.file}\` : 'Loading model...'
});
} else if (data.status === 'progress-queue') {
self.postMessage({
type: 'progress',
progress: 0,
message: \`Queued: \${data.file}\`
});
}
},
signal: currentAbortController.signal
});
self.postMessage({ type: 'loaded' });
} catch (error) {
if (error.name === 'AbortError') {
self.postMessage({ type: 'cancelled' });
} else {
self.postMessage({ type: 'error', error: error.message });
}
}
}
if (type === 'generate') {
currentAbortController = new AbortController();
try {
// Clear previous abort controller
if (generator) {
const result = await generator(payload.prompt, {
max_new_tokens: payload.maxTokens || 512,
temperature: payload.temperature || 0.7,
top_p: payload.topP || 0.9,
do_sample: payload.doSample !== false,
return_full_text: false,
repetition_penalty: payload.repetitionPenalty || 1.1,
signal: currentAbortController.signal
});
self.postMessage({
type: 'result',
result: result[0].generated_text
});
}
} catch (error) {
if (error.name === 'AbortError') {
self.postMessage({ type: 'cancelled' });
} else {
self.postMessage({ type: 'error', error: error.message });
}
}
}
if (type === 'stop') {
if (currentAbortController) {
currentAbortController.abort();
}
}
};
`;
// Create worker from inline script
const blob = new Blob([workerScript], { type: 'application/javascript' });
const worker = new Worker(URL.createObjectURL(blob));
</script>
<script type="module" src="index.js"></script>
</body>
</html>