Spaces:
Sleeping
Sleeping
<html> | |
<head> | |
<title>Papalia3 Inference</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
</head> | |
<body class="bg-gray-100 p-4 md:p-8"> | |
<div class="max-w-4xl mx-auto"> | |
<div class="flex justify-between items-center mb-8"> | |
<h1 class="text-2xl md:text-3xl font-bold">Papalia3 - Desarrollo Humano</h1> | |
<div id="service-status" class="text-sm">Verificando estado...</div> | |
</div> | |
<div class="bg-white rounded-lg shadow-md p-4 md:p-6"> | |
<div class="mb-4"> | |
<label class="block text-gray-700 text-sm font-bold mb-2" for="prompt">Prompt</label> | |
<textarea | |
id="prompt" | |
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" | |
rows="4" | |
placeholder="Escribe tu pregunta sobre Desarrollo Humano..."></textarea> | |
</div> | |
<div class="grid grid-cols-2 gap-4 mb-4"> | |
<div> | |
<label class="block text-gray-700 text-sm font-bold mb-2" for="temperature">Temperature</label> | |
<input | |
type="number" | |
id="temperature" | |
value="0.7" | |
min="0" | |
max="1" | |
step="0.1" | |
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"> | |
</div> | |
<div> | |
<label class="block text-gray-700 text-sm font-bold mb-2" for="max_tokens">Max Tokens</label> | |
<input | |
type="number" | |
id="max_tokens" | |
value="500" | |
min="1" | |
max="2000" | |
class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"> | |
</div> | |
</div> | |
<div class="flex justify-between items-center"> | |
<button | |
id="generate-button" | |
onclick="generateResponse()" | |
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline disabled:opacity-50"> | |
Generar Respuesta | |
</button> | |
<div id="loading" class="hidden text-gray-600"> | |
Generando... | |
</div> | |
</div> | |
<div class="mt-6"> | |
<label class="block text-gray-700 text-sm font-bold mb-2">Respuesta</label> | |
<div id="response" class="mt-2 p-4 bg-gray-100 rounded min-h-[200px] whitespace-pre-wrap"></div> | |
</div> | |
</div> | |
</div> | |
<script> | |
async function checkHealth() { | |
try { | |
const response = await fetch('/health'); | |
const data = await response.json(); | |
const statusEl = document.getElementById('service-status'); | |
const buttonEl = document.getElementById('generate-button'); | |
if (data.status === 'healthy') { | |
statusEl.textContent = '✅ Servicio activo'; | |
statusEl.className = 'text-sm text-green-600'; | |
buttonEl.disabled = false; | |
} else { | |
statusEl.textContent = '❌ ' + (data.error || 'Servicio no disponible'); | |
statusEl.className = 'text-sm text-red-600'; | |
buttonEl.disabled = true; | |
} | |
} catch (error) { | |
const statusEl = document.getElementById('service-status'); | |
statusEl.textContent = '❌ Error de conexión'; | |
statusEl.className = 'text-sm text-red-600'; | |
document.getElementById('generate-button').disabled = true; | |
} | |
} | |
async function generateResponse() { | |
const promptEl = document.getElementById('prompt'); | |
const temperatureEl = document.getElementById('temperature'); | |
const maxTokensEl = document.getElementById('max_tokens'); | |
const responseEl = document.getElementById('response'); | |
const buttonEl = document.getElementById('generate-button'); | |
const loadingEl = document.getElementById('loading'); | |
if (!promptEl.value.trim()) { | |
responseEl.textContent = 'Por favor, escribe una pregunta.'; | |
return; | |
} | |
buttonEl.disabled = true; | |
loadingEl.classList.remove('hidden'); | |
responseEl.textContent = 'Generando respuesta...'; | |
try { | |
const response = await fetch('/generate', { | |
method: 'POST', | |
headers: {'Content-Type': 'application/json'}, | |
body: JSON.stringify({ | |
prompt: promptEl.value, | |
temperature: parseFloat(temperatureEl.value), | |
max_tokens: parseInt(maxTokensEl.value), | |
}), | |
}); | |
const data = await response.json(); | |
if (!response.ok) throw new Error(data.detail || 'Error en la generación'); | |
responseEl.textContent = data.response || 'No se recibió respuesta del modelo'; | |
responseEl.className = 'mt-2 p-4 bg-gray-100 rounded min-h-[200px] whitespace-pre-wrap'; | |
} catch (error) { | |
responseEl.innerHTML = `❌ Error: ${error.message}`; | |
responseEl.className = 'mt-2 p-4 bg-red-50 text-red-700 rounded min-h-[200px] whitespace-pre-wrap'; | |
} finally { | |
buttonEl.disabled = false; | |
loadingEl.classList.add('hidden'); | |
} | |
} | |
checkHealth(); | |
setInterval(checkHealth, 30000); | |
</script> | |
</body> | |
</html> | |