bybot / index.html
Franklin212's picture
A production-ready **PWA** (installable, offline-capable) that runs on Android and desktop.
2ac1520 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bytebot - Autonomous AI OS</title>
<meta name="theme-color" content="#2563eb">
<meta name="description" content="Bytebot - Your autonomous AI operating system">
<link rel="manifest" href="/manifest.json">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
<style>
:root {
--primary: #2563eb;
--primary-light: #3b82f6;
--secondary: #10b981;
--background: #f8fafc;
--card: #ffffff;
--text: #0f172a;
--text-light: #64748b;
}
body {
font-family: 'Inter', sans-serif;
background-color: var(--background);
color: var(--text);
overflow-x: hidden;
}
.glass-card {
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}
.neumorphic {
box-shadow: 8px 8px 16px #e2e8f0, -8px -8px 16px #ffffff;
}
.hover-pop {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.hover-pop:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
}
.progress-ring {
transition: stroke-dashoffset 0.5s ease;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.pulse-animation {
animation: pulse 2s infinite;
}
#vanta-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.1;
}
.message-enter {
animation: fadeInUp 0.3s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
</head>
<body class="min-h-screen">
<div id="vanta-bg"></div>
<!-- Main App Container -->
<div class="container mx-auto px-4 py-6 max-w-7xl">
<!-- Header -->
<header class="flex justify-between items-center mb-8">
<div class="flex items-center space-x-3">
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-blue-500 to-green-400 flex items-center justify-center shadow-lg">
<i data-feather="cpu" class="text-white w-5 h-5"></i>
</div>
<h1 class="text-2xl font-bold text-gray-800">Bytebot</h1>
<span class="px-3 py-1 text-xs font-medium rounded-full bg-blue-100 text-blue-800 flex items-center space-x-1">
<span class="w-2 h-2 rounded-full bg-blue-500 pulse-animation"></span>
<span>Active</span>
</span>
</div>
<div class="flex space-x-4">
<button id="mic-btn" class="p-2 rounded-full bg-white shadow-md hover-pop">
<i data-feather="mic" class="w-5 h-5 text-gray-600"></i>
</button>
<button id="settings-btn" class="p-2 rounded-full bg-white shadow-md hover-pop">
<i data-feather="settings" class="w-5 h-5 text-gray-600"></i>
</button>
</div>
</header>
<!-- Main Content Area -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Left Sidebar - Task Progress -->
<div class="lg:col-span-1 space-y-6">
<!-- System Status -->
<div class="glass-card p-5 hover-pop">
<h2 class="text-lg font-semibold mb-4 flex items-center">
<i data-feather="activity" class="w-5 h-5 mr-2 text-blue-500"></i>
System Status
</h2>
<div class="space-y-4">
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">CPU Usage</span>
<div>
<svg class="w-12 h-12" viewBox="0 0 36 36">
<path class="text-gray-200" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="currentColor" stroke-width="3" stroke-dasharray="88, 100" stroke-linecap="round"/>
<path class="text-blue-500 progress-ring" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="currentColor" stroke-width="3" stroke-dasharray="30, 100" stroke-linecap="round"/>
<text x="18" y="20.5" font-size="8" text-anchor="middle" fill="currentColor" class="text-blue-500 font-medium">30%</text>
</svg>
</div>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Memory</span>
<div>
<svg class="w-12 h-12" viewBox="0 0 36 36">
<path class="text-gray-200" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="currentColor" stroke-width="3" stroke-dasharray="88, 100" stroke-linecap="round"/>
<path class="text-green-500 progress-ring" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="currentColor" stroke-width="3" stroke-dasharray="65, 100" stroke-linecap="round"/>
<text x="18" y="20.5" font-size="8" text-anchor="middle" fill="currentColor" class="text-green-500 font-medium">65%</text>
</svg>
</div>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Network</span>
<div>
<svg class="w-12 h-12" viewBox="0 0 36 36">
<path class="text-gray-200" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="currentColor" stroke-width="3" stroke-dasharray="88, 100" stroke-linecap="round"/>
<path class="text-purple-500 progress-ring" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="currentColor" stroke-width="3" stroke-dasharray="85, 100" stroke-linecap="round"/>
<text x="18" y="20.5" font-size="8" text-anchor="middle" fill="currentColor" class="text-purple-500 font-medium">85%</text>
</svg>
</div>
</div>
</div>
</div>
<!-- Active Tasks -->
<div class="glass-card p-5 hover-pop">
<h2 class="text-lg font-semibold mb-4 flex items-center">
<i data-feather="list" class="w-5 h-5 mr-2 text-blue-500"></i>
Active Tasks
</h2>
<div class="space-y-3">
<div class="flex items-start space-x-3">
<div class="w-2 h-2 mt-2 rounded-full bg-blue-500 animate-pulse"></div>
<div class="flex-1">
<h3 class="text-sm font-medium">Processing voice command</h3>
<p class="text-xs text-gray-500">"Set a timer for 10 minutes"</p>
<div class="w-full bg-gray-200 rounded-full h-1.5 mt-2">
<div class="bg-blue-500 h-1.5 rounded-full" style="width: 45%"></div>
</div>
</div>
</div>
<div class="flex items-start space-x-3">
<div class="w-2 h-2 mt-2 rounded-full bg-green-500"></div>
<div class="flex-1">
<h3 class="text-sm font-medium">Web search</h3>
<p class="text-xs text-gray-500">"Latest AI research papers"</p>
<div class="w-full bg-gray-200 rounded-full h-1.5 mt-2">
<div class="bg-green-500 h-1.5 rounded-full" style="width: 85%"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Memory Summary -->
<div class="glass-card p-5 hover-pop">
<h2 class="text-lg font-semibold mb-4 flex items-center">
<i data-feather="database" class="w-5 h-5 mr-2 text-blue-500"></i>
Memory
</h2>
<div class="flex justify-between items-center mb-2">
<span class="text-sm text-gray-600">4.2 MB used</span>
<span class="text-xs text-gray-500">of 10 MB</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div class="bg-yellow-500 h-2 rounded-full" style="width: 42%"></div>
</div>
<div class="flex justify-between items-center mt-4">
<button class="text-xs text-blue-500 hover:text-blue-700 flex items-center">
<i data-feather="search" class="w-3 h-3 mr-1"></i>
Search
</button>
<button class="text-xs text-blue-500 hover:text-blue-700 flex items-center">
<i data-feather="edit" class="w-3 h-3 mr-1"></i>
Manage
</button>
</div>
</div>
</div>
<!-- Chat Interface -->
<div class="lg:col-span-2">
<div class="glass-card p-5 hover-pop h-full flex flex-col">
<div class="flex border-b pb-3 mb-4">
<button class="px-4 py-2 text-sm font-medium text-blue-500 border-b-2 border-blue-500">
Chat
</button>
<button class="px-4 py-2 text-sm font-medium text-gray-500 hover:text-blue-500">
Dashboard
</button>
<button class="px-4 py-2 text-sm font-medium text-gray-500 hover:text-blue-500">
Logs
</button>
<button class="px-4 py-2 text-sm font-medium text-gray-500 hover:text-blue-500">
Skills
</button>
</div>
<!-- Chat Messages -->
<div id="chat-messages" class="flex-1 overflow-y-auto mb-4 space-y-4 max-h-[400px]">
<div class="message-enter flex items-start space-x-3">
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-blue-100 flex items-center justify-center">
<i data-feather="user" class="w-4 h-4 text-blue-500"></i>
</div>
<div class="bg-white p-3 rounded-lg shadow-sm max-w-[85%]">
<p class="text-sm">Hey Bytebot, can you help me summarize this article?</p>
</div>
</div>
<div class="message-enter flex items-start space-x-3">
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-green-100 flex items-center justify-center">
<i data-feather="cpu" class="w-4 h-4 text-green-500"></i>
</div>
<div class="bg-green-50 p-3 rounded-lg shadow-sm max-w-[85%]">
<p class="text-sm">Of course! I'll analyze the article and extract the key points. Please share the article URL or text with me.</p>
<div class="mt-2 border-t pt-2 flex items-center justify-between">
<span class="text-xs text-gray-500">Task ID: BOT-487</span>
<span class="text-xs px-2 py-1 rounded-full bg-green-100 text-green-800">Parsing</span>
</div>
</div>
</div>
</div>
<!-- Task Plan Visualization -->
<div class="bg-blue-50 p-4 rounded-lg mb-4" data-aos="fade-up">
<h3 class="text-sm font-medium text-blue-800 mb-2 flex items-center">
<i data-feather="layers" class="w-4 h-4 mr-2"></i>
Task Plan
</h3>
<div class="flex items-center space-x-4 text-xs">
<div class="flex flex-col items-center">
<div class="w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center text-white font-medium">1</div>
<span class="mt-1">Plan</span>
</div>
<div class="flex-1 h-1 bg-blue-300 rounded-full"></div>
<div class="flex flex-col items-center">
<div class="w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center text-white font-medium">2</div>
<span class="mt-1">Execute</span>
</div>
<div class="flex-1 h-1 bg-blue-200 rounded-full"></div>
<div class="flex flex-col items-center">
<div class="w-8 h-8 rounded-full bg-blue-200 flex items-center justify-center text-white font-medium">3</div>
<span class="mt-1">Confirm</span>
</div>
</div>
</div>
<!-- Input Area -->
<div class="mt-auto">
<div class="flex items-center bg-white rounded-lg shadow-sm border overflow-hidden">
<input type="text" id="chat-input" placeholder="Type or say 'Hey Bytebot'..." class="flex-1 px-4 py-3 focus:outline-none" autocomplete="off">
<button id="send-btn" class="px-4 py-3 bg-blue-500 text-white">
<i data-feather="send" class="w-5 h-5"></i>
</button>
</div>
<div id="voice-feedback" class="hidden mt-2 p-2 bg-blue-50 rounded-lg flex items-center space-x-2">
<span class="w-2 h-2 rounded-full bg-blue-500 animate-pulse"></span>
<span class="text-sm text-blue-800">Listening...</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Floating Status Widget -->
<div class="fixed bottom-6 right-6">
<div class="glass-card p-3 rounded-full shadow-xl hover-pop group">
<div class="w-12 h-12 rounded-full bg-gradient-to-br from-blue-500 to-green-400 flex items-center justify-center relative">
<i data-feather="cpu" class="text-white w-5 h-5"></i>
<span class="absolute -top-1 -right-1 w-4 h-4 rounded-full bg-green-400 border-2 border-white"></span>
</div>
<div class="absolute bottom-full right-0 mb-2 w-64 p-3 bg-white rounded-lg shadow-lg hidden group-hover:block">
<div class="text-sm font-medium text-gray-900">System Status</div>
<div class="mt-1 text-xs text-gray-500">3 tasks running, 68% memory free</div>
<div class="mt-2 flex justify-between text-xs">
<span class="text-gray-500">Network:</span>
<span class="text-green-500">Connected</span>
</div>
</div>
</div>
</div>
<!-- Settings Modal (hidden by default) -->
<div id="settings-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
<div class="glass-card w-full max-w-2xl p-6 rounded-lg">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-semibold">Settings</h3>
<button id="close-settings" class="text-gray-500 hover:text-gray-700">
<i data-feather="x" class="w-6 h-6"></i>
</button>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h4 class="text-sm font-medium mb-3 text-gray-700">Voice Settings</h4>
<div class="space-y-3">
<div>
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" class="sr-only" checked>
<div class="block bg-gray-300 w-10 h-6 rounded-full"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition"></div>
</div>
<div class="ml-3 text-sm text-gray-700">Wake word "Hey Bytebot"</div>
</label>
</div>
<div>
<label class="text-xs text-gray-700">Voice Speed</label>
<input type="range" min="0.5" max="1.5" step="0.1" value="1.0" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
</div>
</div>
</div>
<div>
<h4 class="text-sm font-medium mb-3 text-gray-700">Memory Settings</h4>
<div class="space-y-3">
<button class="w-full text-left py-2 px-3 bg-red-50 text-red-600 rounded text-sm flex items-center justify-between">
Clear all memory
<i data-feather="trash-2" class="w-4 h-4"></i>
</button>
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" class="sr-only">
<div class="block bg-gray-300 w-10 h-6 rounded-full"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition"></div>
</div>
<div class="ml-3 text-sm text-gray-700">Enable PIN protection</div>
</label>
</div>
</div>
<div>
<h4 class="text-sm font-medium mb-3 text-gray-700">Appearance</h4>
<div class="grid grid-cols-3 gap-2">
<button class="py-2 px-3 rounded border border-gray-300 text-sm">
Light
</button>
<button class="py-2 px-3 rounded border border-gray-300 bg-gray-800 text-white text-sm">
Dark
</button>
<button class="py-2 px-3 rounded border border-blue-500 bg-blue-50 text-blue-700 text-sm">
System
</button>
</div>
</div>
<div>
<h4 class="text-sm font-medium mb-3 text-gray-700">Developer Mode</h4>
<div class="space-y-3">
<label class="flex items-center cursor-pointer">
<div class="relative">
<input type="checkbox" class="sr-only">
<div class="block bg-gray-300 w-10 h-6 rounded-full"></div>
<div class="dot absolute left-1 top-1 bg-white w-4 h-4 rounded-full transition"></div>
</div>
<div class="ml-3 text-sm text-gray-700">Show raw LLM I/O</div>
</label>
</div>
</div>
</div>
</div>
</div>
<!-- Load new JS modules -->
<script type="module">
import { sendToAI, getAIConfig } from '/src/ai/aiClient.js';
// Initialize Vanta.js background
VANTA.GLOBE({
el: "#vanta-bg",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.00,
minWidth: 200.00,
scale: 1.00,
scaleMobile: 1.00,
color: 0x3b82f6,
size: 0.8
});
// Initialize AOS animations
AOS.init({
duration: 600,
easing: 'ease-in-out',
once: true
});
// Initialize Feather Icons
document.addEventListener('DOMContentLoaded', function() {
feather.replace();
// Simulate the app as a PWA
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').then(registration => {
console.log('ServiceWorker registration successful');
}, err => {
console.log('ServiceWorker registration failed: ', err);
});
});
}
// Modal toggle functionality
const settingsBtn = document.getElementById('settings-btn');
const closeSettings = document.getElementById('close-settings');
const settingsModal = document.getElementById('settings-modal');
settingsBtn.addEventListener('click', () => {
settingsModal.classList.remove('hidden');
});
closeSettings.addEventListener('click', () => {
settingsModal.classList.add('hidden');
});
// Voice recognition simulation
const micBtn = document.getElementById('mic-btn');
const voiceFeedback = document.getElementById('voice-feedback');
let isListening = false;
micBtn.addEventListener('click', () => {
isListening = !isListening;
if (isListening) {
micBtn.classList.add('bg-blue-500', 'text-white');
micBtn.classList.remove('bg-white', 'text-gray-600');
voiceFeedback.classList.remove('hidden');
// In a real app, we would initialize the Web Speech API here
} else {
micBtn.classList.remove('bg-blue-500', 'text-white');
micBtn.classList.add('bg-white', 'text-gray-600');
voiceFeedback.classList.add('hidden');
}
});
// Chat input functionality
const chatInput = document.getElementById('chat-input');
const sendBtn = document.getElementById('send-btn');
const chatMessages = document.getElementById('chat-messages');
function addUserMessage(text) {
const messageDiv = document.createElement('div');
messageDiv.className = 'message-enter flex items-start space-x-3';
messageDiv.innerHTML = `
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-blue-100 flex items-center justify-center">
<i data-feather="user" class="w-4 h-4 text-blue-500"></i>
</div>
<div class="bg-white p-3 rounded-lg shadow-sm max-w-[85%]">
<p class="text-sm">${text}</p>
</div>
`;
chatMessages.appendChild(messageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
function addBotMessage(text, status = 'Completed') {
const messageDiv = document.createElement('div');
messageDiv.className = 'message-enter flex items-start space-x-3';
messageDiv.innerHTML = `
<div class="flex-shrink-0 w-8 h-8 rounded-full bg-green-100 flex items-center justify-center">
<i data-feather="cpu" class="w-4 h-4 text-green-500"></i>
</div>
<div class="bg-green-50 p-3 rounded-lg shadow-sm max-w-[85%]">
<p class="text-sm">${text}</p>
<div class="mt-2 border-t pt-2 flex items-center justify-between">
<span class="text-xs text-gray-500">Task ID: BOT-${Math.floor(100 + Math.random() * 900)}</span>
<span class="text-xs px-2 py-1 rounded-full bg-green-100 text-green-800">${status}</span>
</div>
</div>
`;
chatMessages.appendChild(messageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
feather.replace();
}
async function handleSendMessage() {
const text = chatInput.value.trim();
if (text) {
addUserMessage(text);
chatInput.value = '';
// Add "thinking" indicator
const thinkingMsg = addBotMessage("Processing...", "Thinking");
try {
// Get current AI config and send message
const config = getAIConfig();
const messages = [{
role: "user",
content: text
}];
const response = await sendToAI(messages, config);
// Replace thinking message with actual response
thinkingMsg.querySelector('p').textContent = response;
updateMessageStatus(thinkingMsg, "Completed");
} catch (error) {
thinkingMsg.querySelector('p').textContent = `Error: ${error.message}`;
updateMessageStatus(thinkingMsg, "Failed");
}
}
}
function updateMessageStatus(messageElement, status) {
const statusElement = messageElement.querySelector('.flex.items-center.justify-between span:last-child');
if (statusElement) {
statusElement.textContent = status;
statusElement.className = `text-xs px-2 py-1 rounded-full ${
status === "Completed" ? "bg-green-100 text-green-800" :
status === "Failed" ? "bg-red-100 text-red-800" :
"bg-blue-100 text-blue-800"
}`;
}
}
sendBtn.addEventListener('click', handleSendMessage);
chatInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
handleSendMessage();
}
});
// Simulate initial message
setTimeout(() => {
addBotMessage("Hello! I'm Bytebot, your autonomous AI assistant. How can I help you today?");
}, 1000);
});
</script>
<!-- Add AI Settings section -->
<template id="ai-settings-template">
<div class="p-4">
<h3 class="text-lg font-medium mb-4">AI Configuration</h3>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium mb-1">Backend</label>
<select id="ai-backend" class="w-full border rounded px-3 py-2">
<option value="provider">Cloud Provider (OpenAI)</option>
<option value="local">Local LLM</option>
<option value="bytebot-lambda">Bytebot Lambda</option>
</select>
</div>
<div id="provider-token-group">
<label class="block text-sm font-medium mb-1">API Key</label>
<input id="ai-token" type="password" class="w-full border rounded px-3 py-2" placeholder="sk-...">
</div>
<div id="local-endpoint-group" class="hidden">
<label class="block text-sm font-medium mb-1">Local Endpoint</label>
<input id="local-endpoint" type="url" class="w-full border rounded px-3 py-2" placeholder="http://localhost:11434">
</div>
<button id="save-ai-config" class="w-full bg-blue-500 text-white py-2 rounded">Save Configuration</button>
</div>
</div>
</template>
</body>
</html>