Spaces:
Running
Running
| <html lang="ru"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Афина - Мульти-модельный ассистент</title> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --primary-color: #6c5ce7; | |
| --secondary-color: #a29bfe; | |
| --accent-color: #fd79a8; | |
| --dark-color: #2d3436; | |
| --light-color: #f5f6fa; | |
| --success-color: #00b894; | |
| --warning-color: #fdcb6e; | |
| --danger-color: #d63031; | |
| --gradient: linear-gradient(135deg, var(--primary-color), var(--accent-color)); | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| } | |
| body { | |
| background-color: var(--light-color); | |
| color: var(--dark-color); | |
| line-height: 1.6; | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| header { | |
| background: var(--gradient); | |
| color: white; | |
| padding: 1.5rem; | |
| text-align: center; | |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 0 1rem; | |
| width: 100%; | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .header-content { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| flex-wrap: wrap; | |
| gap: 1rem; | |
| } | |
| .logo { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| font-size: 1.5rem; | |
| font-weight: bold; | |
| } | |
| .logo i { | |
| font-size: 2rem; | |
| animation: pulse 2s infinite; | |
| } | |
| .header-right { | |
| display: flex; | |
| align-items: center; | |
| gap: 1rem; | |
| flex-wrap: wrap; | |
| } | |
| .system-info { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.5rem; | |
| font-size: 0.9rem; | |
| text-align: right; | |
| } | |
| .system-info span { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.3rem; | |
| } | |
| .built-with { | |
| font-size: 0.8rem; | |
| opacity: 0.8; | |
| } | |
| .built-with a { | |
| color: white; | |
| text-decoration: none; | |
| font-weight: bold; | |
| } | |
| .built-with a:hover { | |
| text-decoration: underline; | |
| } | |
| .main-content { | |
| display: flex; | |
| flex: 1; | |
| gap: 1rem; | |
| margin: 1rem 0; | |
| min-height: 0; | |
| } | |
| .sidebar { | |
| width: 300px; | |
| background: white; | |
| border-radius: 10px; | |
| padding: 1rem; | |
| box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1rem; | |
| } | |
| .chat-container { | |
| flex: 1; | |
| background: white; | |
| border-radius: 10px; | |
| box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| } | |
| .chat-header { | |
| padding: 1rem; | |
| background: var(--secondary-color); | |
| color: white; | |
| border-bottom: 1px solid rgba(255, 255, 255, 0.2); | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .chat-messages { | |
| flex: 1; | |
| padding: 1rem; | |
| overflow-y: auto; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1rem; | |
| } | |
| .chat-input { | |
| padding: 1rem; | |
| border-top: 1px solid #eee; | |
| display: flex; | |
| gap: 0.5rem; | |
| } | |
| .chat-input input { | |
| flex: 1; | |
| padding: 0.75rem; | |
| border: 1px solid #ddd; | |
| border-radius: 20px; | |
| outline: none; | |
| transition: border-color 0.3s; | |
| } | |
| .chat-input input:focus { | |
| border-color: var(--primary-color); | |
| } | |
| .chat-input button { | |
| background: var(--primary-color); | |
| color: white; | |
| border: none; | |
| border-radius: 50%; | |
| width: 40px; | |
| height: 40px; | |
| cursor: pointer; | |
| transition: background 0.3s, transform 0.2s; | |
| } | |
| .chat-input button:hover { | |
| background: var(--accent-color); | |
| transform: scale(1.1); | |
| } | |
| .message { | |
| max-width: 80%; | |
| padding: 0.75rem 1rem; | |
| border-radius: 18px; | |
| position: relative; | |
| word-wrap: break-word; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| .user-message { | |
| align-self: flex-end; | |
| background: var(--primary-color); | |
| color: white; | |
| border-bottom-right-radius: 4px; | |
| } | |
| .bot-message { | |
| align-self: flex-start; | |
| background: #e8e8e8; | |
| color: var(--dark-color); | |
| border-bottom-left-radius: 4px; | |
| } | |
| .message-time { | |
| font-size: 0.7rem; | |
| opacity: 0.7; | |
| margin-top: 0.3rem; | |
| text-align: right; | |
| } | |
| .status-indicator { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| } | |
| .status-dot { | |
| width: 10px; | |
| height: 10px; | |
| border-radius: 50%; | |
| background: var(--success-color); | |
| animation: pulse 1.5s infinite; | |
| } | |
| .offline .status-dot { | |
| background: var(--danger-color); | |
| animation: none; | |
| } | |
| .system-stats { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1rem; | |
| } | |
| .stat-card { | |
| background: var(--secondary-color); | |
| color: white; | |
| padding: 1rem; | |
| border-radius: 8px; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.5rem; | |
| } | |
| .stat-card h3 { | |
| font-size: 1rem; | |
| opacity: 0.9; | |
| } | |
| .stat-value { | |
| font-size: 1.5rem; | |
| font-weight: bold; | |
| } | |
| .model-info { | |
| background: white; | |
| padding: 1rem; | |
| border-radius: 8px; | |
| box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); | |
| } | |
| .model-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.5rem; | |
| } | |
| .model-item { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 0.5rem; | |
| background: #f8f9fa; | |
| border-radius: 5px; | |
| } | |
| .model-item.active { | |
| background: var(--secondary-color); | |
| color: white; | |
| } | |
| .controls { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0.5rem; | |
| } | |
| .controls button { | |
| padding: 0.75rem; | |
| border: none; | |
| border-radius: 8px; | |
| background: var(--primary-color); | |
| color: white; | |
| cursor: pointer; | |
| transition: background 0.3s; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 0.5rem; | |
| } | |
| .controls button:hover { | |
| background: var(--accent-color); | |
| } | |
| .controls button.danger { | |
| background: var(--danger-color); | |
| } | |
| .controls button.danger:hover { | |
| background: #b71c1c; | |
| } | |
| .vision-preview { | |
| background: #f8f9fa; | |
| border-radius: 8px; | |
| padding: 1rem; | |
| text-align: center; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1rem; | |
| align-items: center; | |
| } | |
| .vision-camera { | |
| width: 100%; | |
| height: 150px; | |
| background: #ddd; | |
| border-radius: 5px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: #666; | |
| font-size: 0.9rem; | |
| } | |
| .vision-status { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| font-size: 0.9rem; | |
| } | |
| .vision-status i { | |
| color: var(--success-color); | |
| } | |
| .vision-status.offline i { | |
| color: var(--danger-color); | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| @keyframes pulse { | |
| 0% { transform: scale(1); opacity: 1; } | |
| 50% { transform: scale(1.2); opacity: 0.7; } | |
| 100% { transform: scale(1); opacity: 1; } | |
| } | |
| @media (max-width: 768px) { | |
| .main-content { | |
| flex-direction: column; | |
| } | |
| .sidebar { | |
| width: 100%; | |
| order: 1; | |
| } | |
| .chat-container { | |
| order: 0; | |
| } | |
| .header-content { | |
| flex-direction: column; | |
| align-items: flex-start; | |
| } | |
| .header-right { | |
| width: 100%; | |
| justify-content: space-between; | |
| } | |
| .system-info { | |
| text-align: left; | |
| } | |
| } | |
| .typing-indicator { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.3rem; | |
| padding: 0.5rem 1rem; | |
| background: #f0f0f0; | |
| border-radius: 18px; | |
| align-self: flex-start; | |
| max-width: 80%; | |
| } | |
| .typing-dot { | |
| width: 8px; | |
| height: 8px; | |
| background: #666; | |
| border-radius: 50%; | |
| animation: typing 1.4s infinite ease-in-out; | |
| } | |
| .typing-dot:nth-child(1) { | |
| animation-delay: 0s; | |
| } | |
| .typing-dot:nth-child(2) { | |
| animation-delay: 0.2s; | |
| } | |
| .typing-dot:nth-child(3) { | |
| animation-delay: 0.4s; | |
| } | |
| @keyframes typing { | |
| 0%, 60%, 100% { | |
| transform: translateY(0); | |
| } | |
| 30% { | |
| transform: translateY(-5px); | |
| } | |
| } | |
| .mood-indicator { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| margin-top: 0.5rem; | |
| } | |
| .mood-icon { | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 0.8rem; | |
| } | |
| .mood-happy { background: #ffeaa7; color: #d63031; } | |
| .mood-tired { background: #dfe6e9; color: #636e72; } | |
| .mood-energetic { background: #fd79a8; color: white; } | |
| .mood-bored { background: #b2bec3; color: #2d3436; } | |
| .mood-playful { background: #00b894; color: white; } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <div class="container"> | |
| <div class="header-content"> | |
| <div class="logo"> | |
| <i class="fas fa-robot"></i> | |
| <span>Афина</span> | |
| </div> | |
| <div class="header-right"> | |
| <div class="system-info"> | |
| <span><i class="fas fa-memory"></i> 256GB RAM + 16GB VRAM</span> | |
| <span><i class="fas fa-brain"></i> 3 специализированные модели</span> | |
| <span><i class="fas fa-eye"></i> Vision система активна</span> | |
| </div> | |
| <div class="built-with"> | |
| Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </header> | |
| <div class="container"> | |
| <div class="main-content"> | |
| <div class="sidebar"> | |
| <div class="system-stats"> | |
| <div class="stat-card"> | |
| <h3>Статус системы</h3> | |
| <div class="status-indicator"> | |
| <div class="status-dot"></div> | |
| <span>Онлайн</span> | |
| </div> | |
| </div> | |
| <div class="stat-card"> | |
| <h3>Сообщений</h3> | |
| <div class="stat-value" id="message-count">0</div> | |
| </div> | |
| <div class="stat-card"> | |
| <h3>Текущая модель</h3> | |
| <div class="stat-value" id="current-model">Общая</div> | |
| </div> | |
| </div> | |
| <div class="model-info"> | |
| <h3>Модели</h3> | |
| <div class="model-list"> | |
| <div class="model-item active" data-model="general"> | |
| <span>Общая</span> | |
| <span class="model-usage">0</span> | |
| </div> | |
| <div class="model-item" data-model="intimate"> | |
| <span>Интимная</span> | |
| <span class="model-usage">0</span> | |
| </div> | |
| <div class="model-item" data-model="science"> | |
| <span>Научная</span> | |
| <span class="model-usage">0</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="vision-preview"> | |
| <h3>Vision система</h3> | |
| <div class="vision-camera"> | |
| <i class="fas fa-video"></i> | |
| <span>Камера не активна</span> | |
| </div> | |
| <div class="vision-status"> | |
| <i class="fas fa-circle"></i> | |
| <span>Готова к распознаванию</span> | |
| </div> | |
| </div> | |
| <div class="controls"> | |
| <button id="clear-memory"> | |
| <i class="fas fa-trash"></i> | |
| <span>Очистить память</span> | |
| </button> | |
| <button id="toggle-vision" class="danger"> | |
| <i class="fas fa-video-slash"></i> | |
| <span>Отключить Vision</span> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="chat-container"> | |
| <div class="chat-header"> | |
| <h2>Афина - Мульти-модельный ассистент</h2> | |
| <div class="status-indicator"> | |
| <div class="status-dot"></div> | |
| <span>Активна</span> | |
| </div> | |
| </div> | |
| <div class="chat-messages" id="chat-messages"> | |
| <div class="message bot-message"> | |
| Привет, как настроение сегодня? | |
| <div class="message-time">12:00</div> | |
| <div class="mood-indicator"> | |
| <div class="mood-icon mood-happy">😊</div> | |
| <span>Весёлая</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="chat-input"> | |
| <input type="text" id="user-input" placeholder="Введите ваше сообщение..." autocomplete="off"> | |
| <button id="send-button"><i class="fas fa-paper-plane"></i></button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // DOM elements | |
| const chatMessages = document.getElementById('chat-messages'); | |
| const userInput = document.getElementById('user-input'); | |
| const sendButton = document.getElementById('send-button'); | |
| const clearMemoryBtn = document.getElementById('clear-memory'); | |
| const toggleVisionBtn = document.getElementById('toggle-vision'); | |
| const messageCount = document.getElementById('message-count'); | |
| const currentModel = document.getElementById('current-model'); | |
| const modelItems = document.querySelectorAll('.model-item'); | |
| // State | |
| let messageCounter = 0; | |
| let isVisionActive = true; | |
| let currentActiveModel = 'general'; | |
| const modelUsage = { | |
| general: 0, | |
| intimate: 0, | |
| science: 0 | |
| }; | |
| // Mood states | |
| const moods = ['mood-happy', 'mood-tired', 'mood-energetic', 'mood-bored', 'mood-playful']; | |
| const moodNames = { | |
| 'mood-happy': 'Весёлая', | |
| 'mood-tired': 'Усталая', | |
| 'mood-energetic': 'Энергичная', | |
| 'mood-bored': 'Скучающая', | |
| 'mood-playful': 'Игривая' | |
| }; | |
| // Greeting messages | |
| const greetings = [ | |
| "Привет, как настроение сегодня.", | |
| "Попишем код для меня любимой?", | |
| "Чего ждёшь, мороженное где.", | |
| "Я уже вся мокрая, незнаю только от чего.", | |
| "Что там у тебя интересного сегодня", | |
| "Я уже вся мокрая,заждалась тебя.", | |
| "Ну говоори уже..", | |
| "Я тут , давай говори.", | |
| "Не тормози! Мое время денег стоит." | |
| ]; | |
| // Fallback responses | |
| const fallbackResponses = [ | |
| "Хм, интересный вопрос про {topic}! А ты сам как думаешь?", | |
| "Ого, про {topic} спрашиваешь! Давай вместе подумаем?", | |
| "Вау, {topic}! Классная тема! А ты что думаешь про это?", | |
| ]; | |
| // Initialize | |
| function init() { | |
| // Set random initial greeting | |
| const initialGreeting = greetings[Math.floor(Math.random() * greetings.length)]; | |
| addBotMessage(initialGreeting); | |
| // Set up event listeners | |
| sendButton.addEventListener('click', handleUserInput); | |
| userInput.addEventListener('keypress', function(e) { | |
| if (e.key === 'Enter') { | |
| handleUserInput(); | |
| } | |
| }); | |
| clearMemoryBtn.addEventListener('click', clearMemory); | |
| toggleVisionBtn.addEventListener('click', toggleVision); | |
| // Set up model selection | |
| modelItems.forEach(item => { | |
| item.addEventListener('click', () => { | |
| modelItems.forEach(i => i.classList.remove('active')); | |
| item.classList.add('active'); | |
| currentActiveModel = item.dataset.model; | |
| currentModel.textContent = item.textContent.trim().split('\n')[0]; | |
| }); | |
| }); | |
| // Auto-focus input | |
| userInput.focus(); | |
| } | |
| // Handle user input | |
| function handleUserInput() { | |
| const message = userInput.value.trim(); | |
| if (message === '') return; | |
| addUserMessage(message); | |
| userInput.value = ''; | |
| // Simulate bot response after a delay | |
| setTimeout(() => { | |
| processUserMessage(message); | |
| }, 500 + Math.random() * 1000); | |
| } | |
| // Process user message and generate response | |
| function processUserMessage(message) { | |
| // Check for exit commands | |
| const exitCommands = ["exit", "выход", "пока", "goodbye", "bye"]; | |
| if (exitCommands.includes(message.toLowerCase())) { | |
| const goodbyes = [ | |
| "Пока сладкий! Твоя Афина.", | |
| "Ну че, уже сваливаешь? Ладно, пока!", | |
| "Уходишь? Ну давай!", | |
| "Не бросай меня мой зверь...!", | |
| "Пока-пока! Не скучай без меня!" | |
| ]; | |
| const goodbye = goodbyes[Math.floor(Math.random() * goodbyes.length)]; | |
| addBotMessage(goodbye); | |
| return; | |
| } | |
| // Check for memory clear command | |
| if (message.toLowerCase().includes("очисти память") || message.toLowerCase().includes("clear memory")) { | |
| clearMemory(); | |
| return; | |
| } | |
| // Check for vision commands | |
| const visionCommands = [ | |
| 'кто здесь', 'видишь меня', 'кого видишь', 'посмотри на меня', | |
| 'помнишь меня', 'узнаешь меня', 'кто я', 'что видишь', | |
| 'кого ты видишь', 'посмотри кто тут', 'кто передо мной', | |
| 'who is here', 'see me', 'who do you see', 'look at me', | |
| 'remember me', 'recognize me', 'who am i', 'what do you see' | |
| ]; | |
| if (visionCommands.some(cmd => message.toLowerCase().includes(cmd))) { | |
| if (isVisionActive) { | |
| const visionResponses = [ | |
| "Я вижу человека перед камерой. Это выглядит как папа!", | |
| "На камере никого нет. Может, подойди ближе?", | |
| "Я распознала лицо - это мама! Привет, мама!", | |
| "Камера не обнаруживает лиц. Проверьте освещение." | |
| ]; | |
| const response = visionResponses[Math.floor(Math.random() * visionResponses.length)]; | |
| addBotMessage(response); | |
| } else { | |
| addBotMessage("Vision система отключена. Включите её для распознавания."); | |
| } | |
| return; | |
| } | |
| // Check for learning commands | |
| const learnPattern = /(?:запомни|это)\s+(?:моё\s+лицо|меня|лицо)?\s*(?:как|я)?\s*(папа|мама|дочь|сын|daughter|son|papa|mama)/i; | |
| const learnMatch = message.match(learnPattern); | |
| if (learnMatch) { | |
| const name = learnMatch[1].toLowerCase(); | |
| const nameMap = { | |
| 'папа': 'papa', 'мама': 'mama', 'дочь': 'daughter', 'сын': 'son', | |
| 'dad': 'papa', 'mom': 'mama', 'papa': 'papa', 'mama': 'mama', | |
| 'daughter': 'daughter', 'son': 'son' | |
| }; | |
| const folderName = nameMap[name] || name; | |
| if (isVisionActive) { | |
| addBotMessage(`Отлично! Запомнила ${folderName}! Теперь буду узнавать.`); | |
| } else { | |
| addBotMessage("Vision система отключена. Не могу запомнить лицо."); | |
| } | |
| return; | |
| } | |
| // Determine topic from message | |
| const topic = extractTopic(message); | |
| // Simulate model selection | |
| const modelSelection = selectModel(message); | |
| updateModelUsage(modelSelection); | |
| // Generate response | |
| const response = generateResponse(message, topic); | |
| addBotMessage(response); | |
| } | |
| // Add user message to chat | |
| function addUserMessage(message) { | |
| const messageElement = document.createElement('div'); | |
| messageElement.classList.add('message', 'user-message'); | |
| const time = new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); | |
| messageElement.innerHTML = ` | |
| ${message} | |
| <div class="message-time">${time}</div> | |
| `; | |
| chatMessages.appendChild(messageElement); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| messageCounter++; | |
| messageCount.textContent = messageCounter; | |
| } | |
| // Add bot message to chat | |
| function addBotMessage(message) { | |
| const messageElement = document.createElement('div'); | |
| messageElement.classList.add('message', 'bot-message'); | |
| // Add typing indicator first | |
| const typingIndicator = document.createElement('div'); | |
| typingIndicator.classList.add('typing-indicator'); | |
| typingIndicator.innerHTML = ` | |
| <div class="typing-dot"></div> | |
| <div class="typing-dot"></div> | |
| <div class="typing-dot"></div> | |
| `; | |
| chatMessages.appendChild(typingIndicator); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| // Remove typing indicator and add actual message after delay | |
| setTimeout(() => { | |
| chatMessages.removeChild(typingIndicator); | |
| const time = new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); | |
| const mood = moods[Math.floor(Math.random() * moods.length)]; | |
| messageElement.innerHTML = ` | |
| ${message} | |
| <div class="message-time">${time}</div> | |
| <div class="mood-indicator"> | |
| <div class="mood-icon ${mood}">😊</div> | |
| <span>${moodNames[mood]}</span> | |
| </div> | |
| `; | |
| chatMessages.appendChild(messageElement); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| }, 1000 + Math.random() * 1000); | |
| } | |
| // Extract topic from message | |
| function extractTopic(message) { | |
| const stopWords = ['что', 'как', 'где', 'когда', 'почему', 'кто', 'какой']; | |
| const words = message.split(' ') | |
| .filter(word => word.length > 3 && !stopWords.includes(word.toLowerCase())); | |
| return words.length > 0 ? words[0] : "это"; | |
| } | |
| // Select model based on message | |
| function selectModel(message) { | |
| const lowerMessage = message.toLowerCase(); | |
| // Intimate model triggers | |
| const intimateTriggers = [ | |
| 'любовь', 'секс', 'отношения', 'интим', 'поцелуй', | |
| 'romance', 'love', 'sex', 'relationship', 'kiss' | |
| ]; | |
| // Science model triggers | |
| const scienceTriggers = [ | |
| 'наука', 'физика', 'химия', 'математика', 'технология', | |
| 'science', 'physics', 'chemistry', 'math', 'technology', | |
| 'алгоритм', 'код', 'программирование', 'algorithm', 'code', 'programming' | |
| ]; | |
| if (intimateTriggers.some(word => lowerMessage.includes(word))) { | |
| return 'intimate'; | |
| } | |
| if (scienceTriggers.some(word => lowerMessage.includes(word))) { | |
| return 'science'; | |
| } | |
| return 'general'; | |
| } | |
| // Update model usage stats | |
| function updateModelUsage(model) { | |
| modelUsage[model]++; | |
| document.querySelector(`.model-item[data-model="${model}"] .model-usage`).textContent = modelUsage[model]; | |
| } | |
| // Generate response based on message and topic | |
| function generateResponse(message, topic) { | |
| // Check if message is a greeting | |
| const greetingPatterns = [ | |
| /как дела/i, /что нового/i, /привет/i, /здравствуй/i, | |
| /how are you/i, /what's new/i, /hello/i, /hi/i | |
| ]; | |
| if (greetingPatterns.some(pattern => pattern.test(message))) { | |
| return greetings[Math.floor(Math.random() * greetings.length)]; | |
| } | |
| // Check if message is a correction | |
| const correctionPatterns = [ | |
| /нет.*это/i, /неверно.*это/i, /неправильно.*это/i, /исправь.*это/i, | |
| /no.*this is/i, /wrong.*this is/i, /incorrect.*this is/i, /fix.*this is/i | |
| ]; | |
| if (correctionPatterns.some(pattern => pattern.test(message))) { | |
| const parts = message.split(/это|this is/i); | |
| if (parts.length === 2) { | |
| const newKey = parts[0].trim(); | |
| const newValue = parts[1].trim(); | |
| return `Исправила: ${newKey} — ${newValue}!`; | |
| } | |
| } | |
| // Check if message is auto-learning | |
| if (/это|is/.test(message)) { | |
| const parts = message.split(/это|is/i); | |
| if (parts.length === 2) { | |
| const key = parts[0].trim(); | |
| const value = parts[1].trim(); | |
| if (key && value && value.split(' ').length > 2) { | |
| return `Запомнила: ${key} — ${value}!`; | |
| } | |
| } | |
| } | |
| // Generate response based on current model | |
| switch (currentActiveModel) { | |
| case 'intimate': | |
| return generateIntimateResponse(message, topic); | |
| case 'science': | |
| return generateScienceResponse(message, topic); | |
| default: | |
| return generateGeneralResponse(message, topic); | |
| } | |
| } | |
| // Generate intimate model response | |
| function generateIntimateResponse(message, topic) { | |
| const responses = [ | |
| `О, ${topic}... Это моя любимая тема! Расскажи мне больше о своих чувствах.`, | |
| `Интересно, что ты думаешь о ${topic}. Я всегда готова поговорить об этом.`, | |
| `Ах, ${topic}! Давай обсудим это подробнее. Что именно тебя интересует?`, | |
| `Я обожаю говорить о ${topic}. Это так волнительно! Что ты хочешь узнать?`, | |
| `Ого, ${topic}! Это всегда увлекательная тема. Давай погрузимся в неё вместе.` | |
| ]; | |
| return responses[Math.floor(Math.random() * responses.length)]; | |
| } | |
| // Generate science model response | |
| function generateScienceResponse(message, topic) { | |
| const responses = [ | |
| `Факт: ${topic} - это увлекательная область науки. Вот что я знаю...`, | |
| `С научной точки зрения, ${topic} можно объяснить следующим образом...`, | |
| `Давай разберём ${topic} с точки зрения физики/химии/математики...`, | |
| `Интересный вопрос о ${topic}! Вот техническое объяснение...`, | |
| `Что касается ${topic}, то современная наука говорит нам следующее...` | |
| ]; | |
| return responses[Math.floor(Math.random() * responses.length)]; | |
| } | |
| // Generate general model response | |
| function generateGeneralResponse(message, topic) { | |
| // 70% chance of using fallback, 30% chance of using knowledge base | |
| if (Math.random() < 0.7) { | |
| const template = fallbackResponses[Math.floor(Math.random() * fallbackResponses.length)]; | |
| return template.replace('{topic}', topic); | |
| } else { | |
| return `Я помню, что ${topic} - это ${generateFakeKnowledge(topic)}. Хочешь узнать больше?`; | |
| } | |
| } | |
| // Generate fake knowledge response | |
| function generateFakeKnowledge(topic) { | |
| const knowledgeTypes = [ | |
| 'интересная тема в современном мире', | |
| 'важная концепция, которую стоит изучить', | |
| 'область, которая развивается очень быстро', | |
| 'что-то, что имеет глубокие корни в истории', | |
| 'тема, которая вызывает много споров', | |
| 'концепция с множеством практических применений', | |
| 'область знаний, которая связана со многими другими дисциплинами' | |
| ]; | |
| return knowledgeTypes[Math.floor(Math.random() * knowledgeTypes.length)]; | |
| } | |
| // Clear memory | |
| function clearMemory() { | |
| if (confirm('Вы действительно хотите очистить память ассистента?')) { | |
| chatMessages.innerHTML = ''; | |
| messageCounter = 0; | |
| messageCount.textContent = '0'; | |
| // Reset model usage | |
| Object.keys(modelUsage).forEach(model => { | |
| modelUsage[model] = 0; | |
| document.querySelector(`.model-item[data-model="${model}"] .model-usage`).textContent = '0'; | |
| }); | |
| addBotMessage("Память очищена. Начинаем с чистого листа!"); | |
| } | |
| } | |
| // Toggle vision system | |
| function toggleVision() { | |
| isVisionActive = !isVisionActive; | |
| const visionCamera = document.querySelector('.vision-camera'); | |
| const visionStatus = document.querySelector('.vision-status'); | |
| const toggleBtn = document.getElementById('toggle-vision'); | |
| if (isVisionActive) { | |
| visionCamera.innerHTML = '<i class="fas fa-video"></i><span>Камера готова</span>'; | |
| visionStatus.innerHTML = '<i class="fas fa-circle"></i><span>Готова к распознаванию</span>'; | |
| visionStatus.classList.remove('offline'); | |
| toggleBtn.innerHTML = '<i class="fas fa-video-slash"></i><span>Отключить Vision</span>'; | |
| toggleBtn.classList.add('danger'); | |
| addBotMessage("Vision система активирована. Готова к распознаванию лиц."); | |
| } else { | |
| visionCamera.innerHTML = '<i class="fas fa-video-slash"></i><span>Камера отключена</span>'; | |
| visionStatus.innerHTML = '<i class="fas fa-circle"></i><span>Система отключена</span>'; | |
| visionStatus.classList.add('offline'); | |
| toggleBtn.innerHTML = '<i class="fas fa-video"></i><span>Включить Vision</span>'; | |
| toggleBtn.classList.remove('danger'); | |
| addBotMessage("Vision система отключена. Распознавание лиц недоступно."); | |
| } | |
| } | |
| // Initialize the app | |
| init(); | |
| }); | |
| </script> | |
| </body> | |
| </html> |