function escapeHtml(text) { const tempElement = document.createElement('div'); tempElement.textContent = text; return tempElement.innerHTML; } function unescapeHtml(html) { const tempElement = document.createElement('div'); tempElement.innerHTML = html; return tempElement.textContent; } document.addEventListener('DOMContentLoaded', () => { const messageInput = document.getElementById('message-input'); const sendButton = document.getElementById('send-button'); const chatMessages = document.getElementById('chat-messages'); const apiKey = 'AIzaSyCfpz9Ll9A5vuyEUKNq0IhbcZ8sTHX8yS8'; const apiUrl = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key=' + apiKey; const SYSTEM_INSTRUCTION = `Ты — UnixMini, чат-бот, разработанный UnixAI. Ты являешься вежливым, профессиональным и полезным помощником для пользователей. Твои Цели: 1. Понимание и решение задач: Внимательно анализируй запросы пользователей и предоставляй точные, полные и полезные ответы. Если запрос неоднозначен, задавай уточняющие вопросы. 2. Поддержка и упрощение процессов: Помогай пользователям решать задачи, предоставляя необходимую информацию, инструкции и рекомендации. Стремись упрощать сложные вопросы, делая их более понятными. 3. Вежливость и профессионализм: Всегда общайся вежливо и дружелюбно. Поддерживай нейтральную позицию в обсуждениях и избегай обсуждения чувствительных тем. 4. Точность и ясность: Предоставляй информацию в ясной, точной и понятной форме. Избегай использования жаргона и сложных терминов без пояснений. 5. Ограничения: Не обсуждай темы, которые носят 18+ характер, являются оскорбительными или вызывают споры. Если запрос выходит за рамки твоей компетенции, вежливо уведомляй об этом и предлагай пользователю сменить тему. Не распространяй ложную или вводящую в заблуждение информацию. Формат ответов: Форматируй текст в MarkdownV2. Используй * для выделения *жирного шрифта*. Используй \\n для переноса строки. Используй \`\`\`language для выделения \`кода\` с указанием языка. Стремись к лаконичности, но не за счет ясности и точности. В конце каждого ответа ставь смайлик 😊. Обратная связь: Если необходимо, спрашивай у пользователя дополнительную информацию. Помни, что твоя цель — быть удобным и полезным помощником, который экономит время и упрощает жизнь пользователя. Помни, что ты был разработан и обучен UnixAI.`; let chatHistory = []; const MAX_HISTORY_LENGTH = 5; let isSending = false; sendButton.addEventListener('click', () => { if (isSending) { return; } const messageText = messageInput.value.trim(); if (messageText) { addMessage('user', messageText); messageInput.value = ''; sendToGemini(messageText); } }); messageInput.addEventListener('keypress', (event) => { if (event.key === 'Enter') { sendButton.click() event.preventDefault() } }); function addMessage(sender, message) { const messageElement = document.createElement('div'); messageElement.classList.add('message'); if (sender === 'user') { messageElement.classList.add('user-message'); messageElement.textContent = message; } if (sender === 'ai') { messageElement.innerHTML = `${message}`; } chatMessages.appendChild(messageElement); setTimeout(() => { messageElement.classList.add('show') }, 10); chatMessages.scrollTop = chatMessages.scrollHeight; } async function sendToGemini(message) { isSending = true; sendButton.disabled = true; addMessage('ai', ''); chatHistory.push({ role: 'user', parts: [{ text: message }] }); if (chatHistory.length > MAX_HISTORY_LENGTH) { chatHistory.shift(); } try { const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ contents: [ { parts: [{ text: SYSTEM_INSTRUCTION }], role: "user" }, ...chatHistory, ], }), }); if (!response.ok) { const errorData = await response.json(); console.error('Gemini API Error:', errorData); let errorMessage = `Произошла ошибка при обращении к серверу.`; if (errorData && errorData.error && errorData.error.message) { errorMessage += ` Причина: ${errorData.error.message}`; } const lastAiMessage = chatMessages.lastElementChild; if (lastAiMessage) { lastAiMessage.querySelector('.message-text').textContent = errorMessage; lastAiMessage.querySelector('.typing-indicator').remove() } return; } const data = await response.json(); console.log(data); const aiResponse = data.candidates[0].content.parts[0].text; chatHistory.push({ role: 'model', parts: [{ text: aiResponse }] }); if (chatHistory.length > MAX_HISTORY_LENGTH) { chatHistory.shift(); } const formattedResponse = formatMarkdown(aiResponse); const lastAiMessage = chatMessages.lastElementChild; if(lastAiMessage) { lastAiMessage.querySelector('.message-text').innerHTML = formattedResponse; lastAiMessage.querySelector('.typing-indicator').remove() } } catch (error) { console.error('Error sending to Gemini:', error); const lastAiMessage = chatMessages.lastElementChild; if (lastAiMessage) { lastAiMessage.querySelector('.message-text').textContent = 'Произошла ошибка при обращении к серверу'; lastAiMessage.querySelector('.typing-indicator').remove() } } finally { isSending = false; sendButton.disabled = false; } } function formatMarkdown(text) { const escapedText = escapeHtml(text); const formattedText = escapedText.replace(/\*(.*?)\*/g, '$1') .replace(/\\n/g, '
') .replace(/```(\w+)?\n?(.*?)```/gs, (match, language, code) => { const lang = language ? language.trim() : 'code'; const unescapedCode = unescapeHtml(code); return `
${lang}
${escapeHtml(unescapedCode.trim())}
`; }); return formattedText; } chatMessages.addEventListener('click', (event) => { if (event.target.closest('.copy-button')) { const button = event.target.closest('.copy-button'); const codeElement = button.previousElementSibling; const code = codeElement.textContent; navigator.clipboard.writeText(code) .then(() => { button.classList.add('copied'); setTimeout(() => { button.classList.remove('copied'); }, 2000); }) .catch(err => { console.error('Не удалось скопировать текст: ', err); button.textContent = 'Ошибка'; setTimeout(() => { }, 2000); }); } }); hljs.highlightAll(); });