iris-py / index.html
Caiobriaego's picture
Add 2 files
a7873e1 verified
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Íris - Seu Assistente Virtual Autônomo</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
:root {
--primary: #6366f1;
--primary-dark: #4f46e5;
--secondary: #f59e0b;
--dark: #1e293b;
--light: #f8fafc;
}
body {
font-family: 'Poppins', sans-serif;
background-color: #f1f5f9;
color: var(--dark);
}
.gradient-bg {
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
}
.chat-container {
height: calc(100vh - 180px);
scrollbar-width: thin;
scrollbar-color: var(--primary) transparent;
}
.chat-container::-webkit-scrollbar {
width: 6px;
}
.chat-container::-webkit-scrollbar-thumb {
background-color: var(--primary);
border-radius: 3px;
}
.message-bubble {
max-width: 80%;
border-radius: 1rem;
padding: 0.75rem 1rem;
margin-bottom: 0.5rem;
word-wrap: break-word;
}
.user-message {
background-color: var(--primary);
color: white;
border-bottom-right-radius: 0.25rem;
margin-left: auto;
}
.iris-message {
background-color: white;
color: var(--dark);
border-bottom-left-radius: 0.25rem;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
}
.typing-indicator span {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: var(--primary);
margin-right: 4px;
animation: bounce 1.5s infinite ease-in-out;
}
.typing-indicator span:nth-child(2) {
animation-delay: 0.2s;
}
.typing-indicator span:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes bounce {
0%, 60%, 100% { transform: translateY(0); }
30% { transform: translateY(-5px); }
}
.automation-node {
background-color: white;
border-radius: 0.5rem;
padding: 0.5rem;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
border: 1px solid #e2e8f0;
cursor: grab;
}
.automation-node:hover {
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.automation-canvas {
background-image: linear-gradient(#e2e8f0 1px, transparent 1px),
linear-gradient(90deg, #e2e8f0 1px, transparent 1px);
background-size: 20px 20px;
background-color: #f8fafc;
}
.pulse-animation {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.7); }
70% { box-shadow: 0 0 0 10px rgba(99, 102, 241, 0); }
100% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0); }
}
.voice-wave {
position: relative;
height: 30px;
width: 100%;
}
.voice-wave span {
position: absolute;
bottom: 0;
display: block;
width: 3px;
height: 3px;
background: var(--primary);
border-radius: 50%;
animation: voiceWave 1.5s infinite ease-in-out;
}
@keyframes voiceWave {
0%, 100% { height: 3px; }
50% { height: 15px; }
}
.voice-wave span:nth-child(1) { left: 5px; animation-delay: 0.1s; }
.voice-wave span:nth-child(2) { left: 10px; animation-delay: 0.2s; }
.voice-wave span:nth-child(3) { left: 15px; animation-delay: 0.3s; }
.voice-wave span:nth-child(4) { left: 20px; animation-delay: 0.4s; }
.voice-wave span:nth-child(5) { left: 25px; animation-delay: 0.5s; }
</style>
</head>
<body class="min-h-screen">
<div class="flex flex-col h-screen">
<!-- Header -->
<header class="gradient-bg text-white p-4 shadow-md">
<div class="container mx-auto flex justify-between items-center">
<div class="flex items-center space-x-3">
<div class="w-10 h-10 rounded-full bg-white flex items-center justify-center">
<i class="fas fa-eye text-indigo-600 text-xl"></i>
</div>
<h1 class="text-2xl font-bold">Íris</h1>
</div>
<div class="flex items-center space-x-4">
<button id="automationBtn" class="p-2 rounded-full hover:bg-white/10 transition">
<i class="fas fa-project-diagram"></i>
</button>
<button id="settingsBtn" class="p-2 rounded-full hover:bg-white/10 transition">
<i class="fas fa-cog"></i>
</button>
<button id="memoryBtn" class="p-2 rounded-full hover:bg-white/10 transition">
<i class="fas fa-brain"></i>
</button>
</div>
</div>
</header>
<!-- Main Content -->
<main class="flex-1 flex flex-col md:flex-row overflow-hidden">
<!-- Chat Interface -->
<div id="chatInterface" class="flex-1 flex flex-col p-4">
<div class="chat-container overflow-y-auto mb-4 space-y-2" id="chatMessages">
<div class="message-bubble iris-message">
<div class="flex items-start space-x-2">
<div class="w-8 h-8 rounded-full gradient-bg flex items-center justify-center text-white">
<i class="fas fa-eye"></i>
</div>
<div>
<p class="font-medium">Íris</p>
<p>Olá! Eu sou a Íris, seu assistente virtual autônomo. Como posso te ajudar hoje?</p>
</div>
</div>
</div>
</div>
<div class="mt-auto">
<div class="flex items-center space-x-2 mb-2">
<button id="voiceInputBtn" class="p-3 rounded-full bg-indigo-100 text-indigo-600 hover:bg-indigo-200 transition">
<i class="fas fa-microphone"></i>
</button>
<div id="voiceStatus" class="hidden flex-1 bg-white p-3 rounded-lg flex items-center">
<div class="voice-wave mr-3">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<p class="text-sm">Ouvindo... Fale agora</p>
</div>
</div>
<div class="flex space-x-2">
<input type="text" id="messageInput" placeholder="Digite sua mensagem..."
class="flex-1 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500">
<button id="sendMessageBtn" class="p-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition">
<i class="fas fa-paper-plane"></i>
</button>
</div>
<div class="flex justify-between mt-2 text-xs text-gray-500">
<p>Íris está usando o modelo bybeagi localmente</p>
<p id="connectionStatus" class="flex items-center">
<span class="w-2 h-2 rounded-full bg-green-500 mr-1"></span>
Modo offline
</p>
</div>
</div>
</div>
<!-- Automation Interface (Hidden by default) -->
<div id="automationInterface" class="hidden flex-1 flex flex-col p-4 bg-gray-50">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold text-gray-800">Automações da Íris</h2>
<div class="flex space-x-2">
<button class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition">
<i class="fas fa-plus mr-2"></i> Novo Fluxo
</button>
<button class="px-4 py-2 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition">
<i class="fas fa-save mr-2"></i> Salvar
</button>
</div>
</div>
<div class="flex-1 grid grid-cols-4 gap-4 overflow-hidden">
<div class="col-span-1 bg-white rounded-lg p-4 overflow-y-auto">
<h3 class="font-medium text-gray-700 mb-3">Componentes</h3>
<div class="space-y-2">
<div class="automation-node" draggable="true">
<div class="flex items-center space-x-2">
<div class="w-6 h-6 rounded-full bg-indigo-100 text-indigo-600 flex items-center justify-center">
<i class="fas fa-envelope text-xs"></i>
</div>
<p class="text-sm">Email</p>
</div>
</div>
<div class="automation-node" draggable="true">
<div class="flex items-center space-x-2">
<div class="w-6 h-6 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center">
<i class="fas fa-calendar text-xs"></i>
</div>
<p class="text-sm">Calendário</p>
</div>
</div>
<div class="automation-node" draggable="true">
<div class="flex items-center space-x-2">
<div class="w-6 h-6 rounded-full bg-green-100 text-green-600 flex items-center justify-center">
<i class="fas fa-database text-xs"></i>
</div>
<p class="text-sm">Banco de Dados</p>
</div>
</div>
<div class="automation-node" draggable="true">
<div class="flex items-center space-x-2">
<div class="w-6 h-6 rounded-full bg-yellow-100 text-yellow-600 flex items-center justify-center">
<i class="fas fa-code text-xs"></i>
</div>
<p class="text-sm">Executar Código</p>
</div>
</div>
<div class="automation-node" draggable="true">
<div class="flex items-center space-x-2">
<div class="w-6 h-6 rounded-full bg-red-100 text-red-600 flex items-center justify-center">
<i class="fas fa-file-alt text-xs"></i>
</div>
<p class="text-sm">Documento</p>
</div>
</div>
<div class="automation-node" draggable="true">
<div class="flex items-center space-x-2">
<div class="w-6 h-6 rounded-full bg-purple-100 text-purple-600 flex items-center justify-center">
<i class="fas fa-globe text-xs"></i>
</div>
<p class="text-sm">HTTP Request</p>
</div>
</div>
</div>
</div>
<div class="col-span-3 automation-canvas rounded-lg p-4 overflow-auto relative">
<div class="w-full h-full flex items-center justify-center text-gray-400">
<p>Arraste componentes aqui para criar seu fluxo de automação</p>
</div>
</div>
</div>
</div>
<!-- Settings Panel (Hidden by default) -->
<div id="settingsPanel" class="hidden w-80 bg-white border-l border-gray-200 p-4 overflow-y-auto">
<h2 class="text-xl font-bold text-gray-800 mb-4">Configurações da Íris</h2>
<div class="space-y-6">
<div>
<h3 class="font-medium text-gray-700 mb-2">Personalidade</h3>
<div class="space-y-3">
<div>
<label class="block text-sm text-gray-600 mb-1">Estilo de Linguagem</label>
<select class="w-full p-2 border border-gray-300 rounded-lg">
<option>Formal</option>
<option selected>Amigável</option>
<option>Técnico</option>
<option>Descontraído</option>
</select>
</div>
<div>
<label class="block text-sm text-gray-600 mb-1">Tom de Voz</label>
<select class="w-full p-2 border border-gray-300 rounded-lg">
<option>Neutro</option>
<option selected>Calmo</option>
<option>Enérgico</option>
<option>Empático</option>
</select>
</div>
</div>
</div>
<div>
<h3 class="font-medium text-gray-700 mb-2">Aprendizado</h3>
<div class="space-y-3">
<div class="flex items-center justify-between">
<label class="text-sm text-gray-600">Aprendizado Contínuo</label>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" class="sr-only peer" checked>
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-indigo-600"></div>
</label>
</div>
<div class="flex items-center justify-between">
<label class="text-sm text-gray-600">Memória Vetorial</label>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" class="sr-only peer" checked>
<div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-indigo-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-indigo-600"></div>
</label>
</div>
</div>
</div>
<div>
<h3 class="font-medium text-gray-700 mb-2">Modelo Local</h3>
<div class="space-y-3">
<div>
<label class="block text-sm text-gray-600 mb-1">Modelo</label>
<select class="w-full p-2 border border-gray-300 rounded-lg">
<option selected>bybeagi (padrão)</option>
<option>bybeagi-lite</option>
<option>bybeagi-pro</option>
</select>
</div>
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-xs text-gray-500">Uso de memória: <span class="font-medium">1.2GB/2GB</span></p>
<div class="w-full bg-gray-200 rounded-full h-2 mt-1">
<div class="bg-indigo-600 h-2 rounded-full" style="width: 60%"></div>
</div>
</div>
</div>
</div>
<div>
<h3 class="font-medium text-gray-700 mb-2">Exportar/Importar</h3>
<div class="space-y-2">
<button class="w-full py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition">
<i class="fas fa-file-export mr-2"></i> Exportar Perfil
</button>
<button class="w-full py-2 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition">
<i class="fas fa-file-import mr-2"></i> Importar Perfil
</button>
</div>
</div>
</div>
</div>
<!-- Memory Panel (Hidden by default) -->
<div id="memoryPanel" class="hidden w-80 bg-white border-l border-gray-200 p-4 overflow-y-auto">
<h2 class="text-xl font-bold text-gray-800 mb-4">Memória da Íris</h2>
<div class="space-y-4">
<div>
<h3 class="font-medium text-gray-700 mb-2">Preferências</h3>
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm text-gray-600">Você prefere respostas curtas e diretas</p>
<p class="text-sm text-gray-600">Gosta de ser lembrado sobre reuniões 15 minutos antes</p>
<p class="text-sm text-gray-600">Prefere trabalhar com Python para automações</p>
</div>
</div>
<div>
<h3 class="font-medium text-gray-700 mb-2">Rotinas</h3>
<div class="space-y-2">
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm font-medium text-gray-700">Manhã</p>
<p class="text-xs text-gray-600">- Verificar emails importantes</p>
<p class="text-xs text-gray-600">- Revisar agenda do dia</p>
</div>
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-sm font-medium text-gray-700">Noite</p>
<p class="text-xs text-gray-600">- Fazer backup dos documentos</p>
<p class="text-xs text-gray-600">- Preparar lista de tarefas para o dia seguinte</p>
</div>
</div>
</div>
<div>
<h3 class="font-medium text-gray-700 mb-2">Histórico Recente</h3>
<div class="space-y-2">
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-xs text-gray-500">Hoje, 10:30</p>
<p class="text-sm text-gray-600">Você pediu para criar um script Python para organizar arquivos</p>
</div>
<div class="bg-gray-50 p-3 rounded-lg">
<p class="text-xs text-gray-500">Ontem, 18:45</p>
<p class="text-sm text-gray-600">Você pesquisou sobre modelos de NLP locais</p>
</div>
</div>
</div>
<button class="w-full py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition mt-4">
<i class="fas fa-eraser mr-2"></i> Limpar Memória
</button>
</div>
</div>
</main>
</div>
<script>
// Toggle between interfaces
document.getElementById('automationBtn').addEventListener('click', function() {
document.getElementById('chatInterface').classList.toggle('hidden');
document.getElementById('automationInterface').classList.toggle('hidden');
document.getElementById('settingsPanel').classList.add('hidden');
document.getElementById('memoryPanel').classList.add('hidden');
});
document.getElementById('settingsBtn').addEventListener('click', function() {
document.getElementById('settingsPanel').classList.toggle('hidden');
document.getElementById('memoryPanel').classList.add('hidden');
});
document.getElementById('memoryBtn').addEventListener('click', function() {
document.getElementById('memoryPanel').classList.toggle('hidden');
document.getElementById('settingsPanel').classList.add('hidden');
});
// Chat functionality
const messageInput = document.getElementById('messageInput');
const sendMessageBtn = document.getElementById('sendMessageBtn');
const chatMessages = document.getElementById('chatMessages');
function sendMessage() {
const message = messageInput.value.trim();
if (message === '') return;
// Add user message
const userMessageDiv = document.createElement('div');
userMessageDiv.className = 'message-bubble user-message';
userMessageDiv.innerHTML = `
<div class="flex items-start space-x-2 justify-end">
<div>
<p class="text-right">${message}</p>
</div>
<div class="w-8 h-8 rounded-full bg-gray-200 flex items-center justify-center">
<i class="fas fa-user text-gray-600"></i>
</div>
</div>
`;
chatMessages.appendChild(userMessageDiv);
// Clear input
messageInput.value = '';
// Scroll to bottom
chatMessages.scrollTop = chatMessages.scrollHeight;
// Show typing indicator
const typingIndicator = document.createElement('div');
typingIndicator.className = 'message-bubble iris-message';
typingIndicator.innerHTML = `
<div class="flex items-start space-x-2">
<div class="w-8 h-8 rounded-full gradient-bg flex items-center justify-center text-white">
<i class="fas fa-eye"></i>
</div>
<div>
<p class="font-medium">Íris</p>
<div class="typing-indicator">
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
`;
chatMessages.appendChild(typingIndicator);
chatMessages.scrollTop = chatMessages.scrollHeight;
// Simulate Iris response after delay
setTimeout(() => {
// Remove typing indicator
chatMessages.removeChild(typingIndicator);
// Add Iris response
const irisMessageDiv = document.createElement('div');
irisMessageDiv.className = 'message-bubble iris-message';
// Simple responses based on input
let response;
if (message.toLowerCase().includes('olá') || message.toLowerCase().includes('oi')) {
response = "Olá! Como posso te ajudar hoje?";
} else if (message.toLowerCase().includes('automação') || message.toLowerCase().includes('automatizar')) {
response = "Posso te ajudar a criar automações. Clique no botão de automações no canto superior direito para começar.";
} else if (message.toLowerCase().includes('configuração') || message.toLowerCase().includes('ajustar')) {
response = "Você pode personalizar minhas configurações clicando no ícone de engrenagem no topo.";
} else {
response = "Eu sou a Íris, seu assistente virtual autônomo. Posso te ajudar com automações, criação de conteúdo, organização e muito mais. Como posso ser útil?";
}
irisMessageDiv.innerHTML = `
<div class="flex items-start space-x-2">
<div class="w-8 h-8 rounded-full gradient-bg flex items-center justify-center text-white">
<i class="fas fa-eye"></i>
</div>
<div>
<p class="font-medium">Íris</p>
<p>${response}</p>
</div>
</div>
`;
chatMessages.appendChild(irisMessageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
}, 1500);
}
sendMessageBtn.addEventListener('click', sendMessage);
messageInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
sendMessage();
}
});
// Voice input functionality
const voiceInputBtn = document.getElementById('voiceInputBtn');
const voiceStatus = document.getElementById('voiceStatus');
voiceInputBtn.addEventListener('click', function() {
voiceStatus.classList.toggle('hidden');
if (!voiceStatus.classList.contains('hidden')) {
// Simulate voice recognition
setTimeout(() => {
voiceStatus.classList.add('hidden');
messageInput.value = "Crie uma automação para organizar meus arquivos";
sendMessage();
}, 3000);
}
});
// Make automation nodes draggable
document.querySelectorAll('.automation-node').forEach(node => {
node.addEventListener('dragstart', function(e) {
e.dataTransfer.setData('text/plain', node.innerHTML);
e.dataTransfer.effectAllowed = 'copy';
});
});
const automationCanvas = document.querySelector('.automation-canvas');
automationCanvas.addEventListener('dragover', function(e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
});
automationCanvas.addEventListener('drop', function(e) {
e.preventDefault();
const data = e.dataTransfer.getData('text/plain');
const newNode = document.createElement('div');
newNode.className = 'automation-node absolute';
newNode.innerHTML = data;
newNode.style.left = `${e.clientX - automationCanvas.getBoundingClientRect().left - 50}px`;
newNode.style.top = `${e.clientY - automationCanvas.getBoundingClientRect().top - 20}px`;
automationCanvas.appendChild(newNode);
// Make new node draggable
newNode.addEventListener('dragstart', function(ev) {
ev.dataTransfer.setData('text/plain', newNode.innerHTML);
ev.dataTransfer.effectAllowed = 'move';
});
// Add drag functionality
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
newNode.onmousedown = dragMouseDown;
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
newNode.style.top = (newNode.offsetTop - pos2) + "px";
newNode.style.left = (newNode.offsetLeft - pos1) + "px";
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Caiobriaego/iris-py" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>