Spaces:
Runtime error
Runtime error
// Variables globales | |
let currentMode = 'seguros'; | |
let currentModel = 'Gemini 8b'; | |
let currentTTS = 'EDGE'; | |
let isListening = false; | |
let recognition = null; | |
function playAudio(button, text) { | |
const icon = button ? button.querySelector('i') : null; | |
text = text || (button ? button.getAttribute('data-text') : ''); | |
if (!text) { | |
console.error('No text provided for audio'); | |
return; | |
} | |
if (button) { | |
icon.className = 'fas fa-spinner fa-spin'; | |
button.disabled = true; | |
} | |
fetch('/generate_audio', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify({ | |
text: text, | |
model: currentTTS | |
}) | |
}) | |
.then(response => { | |
if (!response.ok) { | |
throw new Error(`HTTP error! status: ${response.status}`); | |
} | |
return response.json(); | |
}) | |
.then(data => { | |
if (data.audio_url) { | |
console.log(`Reproduciendo audio generado con modelo: ${data.model_used}`); | |
const audio = new Audio(window.location.origin + data.audio_url); | |
if (button) { | |
audio.onplay = () => { | |
icon.className = 'fas fa-pause'; | |
}; | |
audio.onended = () => { | |
icon.className = 'fas fa-play'; | |
button.disabled = false; | |
}; | |
} | |
audio.onerror = (e) => { | |
console.error('Error reproduciendo audio:', e); | |
if (button) { | |
icon.className = 'fas fa-play'; | |
button.disabled = false; | |
} | |
appendBotMessage("Error reproduciendo el audio. Intente de nuevo."); | |
}; | |
audio.play().catch(error => { | |
console.error('Error playing audio:', error); | |
if (button) { | |
icon.className = 'fas fa-play'; | |
button.disabled = false; | |
} | |
appendBotMessage("Error reproduciendo el audio. Intente de nuevo."); | |
}); | |
} else { | |
throw new Error('No audio URL in response'); | |
} | |
}) | |
.catch(error => { | |
console.error('Error:', error); | |
if (button) { | |
icon.className = 'fas fa-play'; | |
button.disabled = false; | |
} | |
appendBotMessage(`Error generando el audio: ${error.message}`); | |
}); | |
} | |
// Agregar esto para manejar nuevos mensajes din谩micamente | |
function appendBotMessage(message) { | |
const chatMessages = document.getElementById('chat-messages'); | |
const messageDiv = document.createElement('div'); | |
messageDiv.className = 'message bot-message'; | |
messageDiv.innerHTML = ` | |
<div class="message-content">${message}</div> | |
<button onclick="playAudio(this)" data-text="${message}" class="play-button"> | |
<i class="fas fa-play"></i> | |
</button> | |
`; | |
chatMessages.appendChild(messageDiv); | |
} | |
async function sendMessage() { | |
const input = document.getElementById('user-input'); | |
const text = input.value.trim(); | |
if (text) { | |
// Agregar mensaje del usuario | |
const chatMessages = document.getElementById('chat-messages'); | |
const userDiv = document.createElement('div'); | |
userDiv.className = 'message user-message'; | |
userDiv.textContent = text; | |
chatMessages.appendChild(userDiv); | |
// Limpiar input | |
input.value = ''; | |
try { | |
// Enviar mensaje al backend con el modo actual | |
const response = await fetch('/chat', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify({ | |
message: text, | |
mode: currentMode | |
}) | |
}); | |
const data = await response.json(); | |
if (data.response) { | |
// Agregar respuesta del bot | |
appendBotMessage(data.response); | |
// Auto-reproducir respuesta | |
const lastButton = document.querySelector('.bot-message:last-child .play-button'); | |
if (lastButton) { | |
playAudio(lastButton); | |
} | |
} | |
} catch (error) { | |
console.error('Error:', error); | |
appendBotMessage("Lo siento, hubo un error al procesar tu mensaje."); | |
} | |
} | |
} | |
async function changeMode(mode) { | |
try { | |
const response = await fetch('/change_mode', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify({ mode }) | |
}); | |
if (response.ok) { | |
currentMode = mode; | |
appendBotMessage(`Modo cambiado a: ${mode}`); | |
playAudio(null, `Modo de operaci贸n cambiado a ${mode}`); | |
} | |
} catch (error) { | |
console.error('Error changing mode:', error); | |
appendBotMessage("Error al cambiar el modo de operaci贸n"); | |
} | |
} | |
async function changeModel(model) { | |
try { | |
const response = await fetch('/change_model', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify({ model }) | |
}); | |
if (response.ok) { | |
currentModel = model; | |
appendBotMessage(`Modelo de IA cambiado a: ${model}`); | |
playAudio(null, `Modelo de inteligencia artificial cambiado a ${model}`); | |
} | |
} catch (error) { | |
console.error('Error changing model:', error); | |
appendBotMessage("Error al cambiar el modelo de IA"); | |
} | |
} | |
// Inicializar reconocimiento de voz | |
function initSpeechRecognition() { | |
if ('webkitSpeechRecognition' in window) { | |
recognition = new webkitSpeechRecognition(); | |
recognition.continuous = true; | |
recognition.interimResults = true; | |
recognition.lang = 'es-ES'; | |
recognition.onresult = function(event) { | |
const result = event.results[event.results.length - 1]; | |
if (result.isFinal) { | |
const text = result.item(0).transcript; | |
document.getElementById('user-input').value = text; | |
sendMessage(); | |
} | |
}; | |
recognition.onerror = function(event) { | |
console.error('Error en reconocimiento:', event.error); | |
toggleVAD(); | |
}; | |
} else { | |
console.error('Reconocimiento de voz no soportado'); | |
} | |
} | |
// Funci贸n para cambiar TTS | |
async function changeTTS(model) { | |
try { | |
const response = await fetch('/change_tts', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify({ model }) | |
}); | |
if (response.ok) { | |
currentTTS = model; | |
appendBotMessage(`Modelo de voz cambiado a: ${model}`); | |
playAudio(null, `Voz del sistema cambiada a ${model}`); | |
} | |
} catch (error) { | |
console.error('Error changing TTS:', error); | |
appendBotMessage("Error al cambiar el modelo de voz"); | |
} | |
} | |
// Funci贸n para activar/desactivar VAD | |
function toggleVAD() { | |
const vadButton = document.querySelector('.vad-button'); | |
const vadStatus = document.getElementById('vad-status'); | |
if (!isListening) { | |
if (recognition) { | |
recognition.start(); | |
isListening = true; | |
vadButton.classList.remove('inactive'); | |
vadButton.classList.add('active'); | |
vadButton.innerHTML = '<i class="fas fa-microphone"></i> Escuchando'; | |
// Mostrar estado de escucha | |
vadStatus.classList.add('listening'); | |
vadStatus.innerHTML = '馃帳 Escuchando...'; | |
// Reproducir sonido de inicio | |
playAudio(null, "Sistema activado. Puede hablar."); | |
} | |
} else { | |
if (recognition) { | |
recognition.stop(); | |
isListening = false; | |
vadButton.classList.remove('active'); | |
vadButton.classList.add('inactive'); | |
vadButton.innerHTML = '<i class="fas fa-microphone-slash"></i> Activar micr贸fono'; | |
// Ocultar estado de escucha | |
vadStatus.classList.remove('listening'); | |
vadStatus.innerHTML = ''; | |
// Mensaje de desactivaci贸n | |
playAudio(null, "Sistema en pausa."); | |
} | |
} | |
} | |
// Inicializar cuando el documento est茅 listo | |
document.addEventListener('DOMContentLoaded', function() { | |
initSpeechRecognition(); | |
// Iniciar VAD autom谩ticamente | |
setTimeout(() => { | |
toggleVAD(); // Activar el VAD al inicio | |
appendBotMessage("Sistema iniciado. Modelos cargados correctamente. Escuchando..."); | |
}, 1000); | |
}); | |
// Permitir enviar con Enter | |
document.getElementById('user-input')?.addEventListener('keypress', function(e) { | |
if (e.key === 'Enter') { | |
sendMessage(); | |
} | |
}); |