// OpenAI API key (replace with your actual key) const OPENAI_API_KEY = 'your-api-key-here'; const OPENAI_API_URL = 'https://api.openai.com/v1/chat/completions'; // Speech recognition setup const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; let recognition = null; let isRecognizing = false; let conversationHistory = []; if (SpeechRecognition) { recognition = new SpeechRecognition(); recognition.continuous = false; recognition.interimResults = false; recognition.lang = 'en-US'; recognition.onresult = (event) => { const transcript = event.results[0][0].transcript; document.getElementById('user-input').value = transcript; document.getElementById('voice-feedback').classList.add('hidden'); document.getElementById('recording-indicator').classList.add('hidden'); document.getElementById('send-btn').disabled = false; }; recognition.onerror = (event) => { console.error('Speech recognition error', event.error); document.getElementById('voice-feedback').textContent = `Error: ${event.error}`; setTimeout(() => { document.getElementById('voice-feedback').classList.add('hidden'); }, 3000); document.getElementById('recording-indicator').classList.add('hidden'); }; recognition.onend = () => { isRecognizing = false; document.getElementById('voice-btn').classList.remove('text-red-400'); }; } // Process user message with OpenAI async function processMessage(message) { const responseWindow = document.getElementById('response-window'); const loadingMessage = document.createElement('p'); loadingMessage.className = 'text-blue-300 mb-4'; loadingMessage.innerHTML = '> Processing your thought patterns...'; responseWindow.appendChild(loadingMessage); responseWindow.scrollTop = responseWindow.scrollHeight; try { conversationHistory.push({ role: 'user', content: message }); const response = await axios.post(OPENAI_API_URL, { model: 'gpt-3.5-turbo', messages: [ { role: 'system', content: 'You are Brian the Mind Mirror clarity assistant, a helpful AI companion designed to help organize thoughts and provide clarity. Respond in a thoughtful but concise manner.' }, ...conversationHistory ], temperature: 0.7, max_tokens: 150 }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${OPENAI_API_KEY}` } }); const aiReply = response.data.choices[0].message.content; conversationHistory.push({ role: 'assistant', content: aiReply }); const replyElement = document.createElement('p'); replyElement.innerHTML = aiReply.split('\n').join('
'); responseWindow.replaceChild(replyElement, loadingMessage); } catch (error) { console.error('OpenAI API error:', error); loadingMessage.textContent = '> System error occurred, please try again later'; } } document.addEventListener('DOMContentLoaded', function() { const voiceBtn = document.getElementById('voice-btn'); const sendBtn = document.getElementById('send-btn'); const userInput = document.getElementById('user-input'); // Voice input handler voiceBtn.addEventListener('click', () => { if (!recognition) { alert('Speech recognition not supported in your browser'); return; } if (!isRecognizing) { recognition.start(); isRecognizing = true; document.getElementById('voice-feedback').classList.remove('hidden'); document.getElementById('recording-indicator').classList.remove('hidden'); document.getElementById('voice-btn').classList.add('text-red-400'); } else { recognition.stop(); } }); // Text input handler userInput.addEventListener('input', () => { sendBtn.disabled = userInput.value.trim() === ''; }); // Send message handler sendBtn.addEventListener('click', () => { const message = userInput.value.trim(); if (message) { processMessage(message); userInput.value = ''; sendBtn.disabled = true; } }); // Handle Enter key userInput.addEventListener('keypress', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendBtn.click(); } }); }); class GalaxyBackground { constructor(container) { this.container = container; this.scene = null;