Widget:OllamaChat

Материал из ultracity
Версия от 10:47, 24 марта 2026; Rodion (обсуждение | вклад) (Новая страница: «<div class="ollama-chat-widget"> <div class="chat-messages" style="height: 400px; overflow-y: auto; border: 1px solid #ccc; border-radius: 8px; padding: 10px; margin-bottom: 10px; background: #f9f9f9;"> <div class="message bot">Привет! Я AI-ассистент. Задайте мне вопрос.</div> </div> <div class="chat-input-area"> <select id="ollama-model-{$id}" style="margin-bottom: 10px; padding: 5px;">...»)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигации Перейти к поиску
Привет! Я AI-ассистент. Задайте мне вопрос.
       <select id="ollama-model-{$id}" style="margin-bottom: 10px; padding: 5px;">
           <option value="llama3.2">llama3.2</option>
           <option value="gemma:2b">gemma:2b</option>
           <option value="mistral">mistral</option>
           <option value="phi3">phi3</option>
       </select>
           <input type="text" id="ollama-input-{$id}" placeholder="Введите сообщение..." style="flex: 1; padding: 8px; border: 1px solid #ccc; border-radius: 4px;">
           <button id="ollama-send-{$id}" style="padding: 8px 16px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer;">Отправить</button>

<script> (function() {

   const container = document.currentScript.parentElement;
   const uniqueId = Math.random().toString(36).substr(2, 8);
   
   const messagesDiv = container.querySelector('.chat-messages');
   const inputField = container.querySelector('#ollama-input-{$id}');
   const sendButton = container.querySelector('#ollama-send-{$id}');
   const modelSelect = container.querySelector('#ollama-model-{$id}');
   
   const OLLAMA_URL = 'http://82.148.28.75:11434/api/generate';
   
   function addMessage(text, isUser) {
       const msgDiv = document.createElement('div');
       msgDiv.style.marginBottom = '10px';
       msgDiv.style.padding = '8px 12px';
       msgDiv.style.borderRadius = '8px';
       msgDiv.style.wordWrap = 'break-word';
       
       if (isUser) {
           msgDiv.style.backgroundColor = '#007bff';
           msgDiv.style.color = 'white';
           msgDiv.style.textAlign = 'right';
           msgDiv.style.marginLeft = '20%';
           msgDiv.textContent = 'Вы: ' + text;
       } else {
           msgDiv.style.backgroundColor = '#e5e5e5';
           msgDiv.style.color = '#333';
           msgDiv.style.marginRight = '20%';
           msgDiv.textContent = 'Bot: ' + text;
       }
       
       messagesDiv.appendChild(msgDiv);
       messagesDiv.scrollTop = messagesDiv.scrollHeight;
   }
   
   function showTyping() {
       const typingDiv = document.createElement('div');
       typingDiv.id = 'typing-indicator';
       typingDiv.style.marginBottom = '10px';
       typingDiv.style.padding = '8px 12px';
       typingDiv.style.backgroundColor = '#e5e5e5';
       typingDiv.style.borderRadius = '8px';
       typingDiv.style.marginRight = '20%';
       typingDiv.style.color = '#666';
       typingDiv.textContent = 'Bot: печатает...';
       messagesDiv.appendChild(typingDiv);
       messagesDiv.scrollTop = messagesDiv.scrollHeight;
   }
   
   function hideTyping() {
       const typing = document.getElementById('typing-indicator');
       if (typing) typing.remove();
   }
   
   async function sendMessage() {
       const question = inputField.value.trim();
       if (!question) return;
       
       addMessage(question, true);
       inputField.value = ;
       inputField.disabled = true;
       sendButton.disabled = true;
       
       showTyping();
       
       try {
           const response = await fetch(OLLAMA_URL, {
               method: 'POST',
               headers: { 'Content-Type': 'application/json' },
               body: JSON.stringify({
                   model: modelSelect.value,
                   prompt: question,
                   stream: false,
                   options: { temperature: 0.7 }
               })
           });
           
           if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
           
           const data = await response.json();
           hideTyping();
           addMessage(data.response || 'Извините, не удалось получить ответ.', false);
           
       } catch (error) {
           hideTyping();
           let errorMsg = 'Ошибка: ' + error.message;
           if (error.message.includes('Failed to fetch')) {
               errorMsg = 'Ошибка: не удалось подключиться к серверу Ollama (82.148.28.75:11434). Проверьте, что сервер доступен и CORS настроен.';
           }
           addMessage(errorMsg, false);
       } finally {
           inputField.disabled = false;
           sendButton.disabled = false;
           inputField.focus();
       }
   }
   
   sendButton.addEventListener('click', sendMessage);
   inputField.addEventListener('keypress', (e) => {
       if (e.key === 'Enter') sendMessage();
   });

})(); </script>