File size: 4,898 Bytes
d85712e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>MEPLIFEOS | FUGTH AI Gateway</title>
<style>
:root{color-scheme:dark;font-family:system-ui,-apple-system,Segoe UI,sans-serif}
*{box-sizing:border-box}body{margin:0;background:#071525;color:#e8f2fc}
main{max-width:850px;margin:0 auto;padding:36px 18px}
h1{font-size:clamp(26px,5vw,38px);margin:6px 0}p{color:#a9bfd0;line-height:1.5}
.top{display:flex;align-items:center;gap:10px;color:#6ee7d7;font-weight:650;letter-spacing:.06em}
.panel{background:#102237;border:1px solid #294358;border-radius:18px;padding:22px;margin:22px 0}
.grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}@media(max-width:650px){.grid{grid-template-columns:1fr}}
label{display:block;font-size:13px;font-weight:650;color:#c0d3e4;margin-bottom:7px}
input,textarea,select{width:100%;padding:12px;border:1px solid #3a556c;border-radius:9px;background:#08192a;color:white;font:inherit}
textarea{resize:vertical;min-height:85px}button{background:#33d3bf;color:#032327;border:0;border-radius:10px;padding:12px 20px;font:inherit;font-weight:750;cursor:pointer}
button:disabled{opacity:.6;cursor:wait}pre{white-space:pre-wrap;overflow-wrap:anywhere;background:#07192a;border:1px solid #334b60;border-radius:10px;padding:15px;min-height:70px;line-height:1.5}
small{color:#97b3c7}a{color:#66e0cf}.status{font-size:14px;margin:12px 0}
</style>
</head>
<body><main>
<div class="top">● FUGTH MANAGEMENT OS / AI INFRASTRUCTURE</div>
<h1>MEPLIFEOS AI Gateway</h1>
<p>Two Qwen GGUF models, CPU inference, shared FIFO queue, and request-specific reference context. This is a developer test console, not a public customer chat.</p>
<div class="panel">
<h2>Service health</h2>
<div class="status" id="health">Checking service…</div>
<button type="button" id="refresh">Refresh status</button>
</div>
<div class="panel">
<h2>Test generation</h2>
<p>Enter your Space secret <code>FUGTH_API_KEY</code> locally to test. The page does not store it.</p>
<div class="grid">
<div><label for="key">API key</label><input id="key" type="password" autocomplete="off" placeholder="Secret from Space settings" /></div>
<div><label for="model">Model</label><select id="model"><option value="1.5b">Qwen2.5 1.5B (quality)</option><option value="0.5b">Qwen2.5 0.5B (faster)</option></select></div>
<div><label for="business">Business name</label><input id="business" value="Example Hair Studio" maxlength="120" /></div>
<div><label for="message">Customer question</label><input id="message" value="What time do you close on Saturday?" maxlength="1200" /></div>
</div>
<p><label for="context">Reference information (simulates retrieved RAG context)</label>
<textarea id="context" maxlength="4000">Opening hours: Monday-Friday 9AM-6PM. Saturday 10AM-3PM. Sunday closed. Walk-ins accepted.</textarea></p>
<button type="button" id="send">Send test request</button>
<p><small>Generation may be slow on 2-vCPU free hardware. Requests wait in a bounded queue. For real customers, your FUGTH backend must hold the secret and handle authentication/rate limits.</small></p>
<h3>Response</h3><pre id="reply">No request yet.</pre>
</div>
<p><a href="/docs">API documentation</a> · <a href="https://huggingface.co/spaces/fugthchat/MEPLIFEOS">Space repository</a></p>
</main><script>
const el = id => document.getElementById(id);
async function updateHealth(){
try {
const r=await fetch('/health',{cache:'no-store'});
const j=await r.json();
el('health').textContent=`${j.ready?'READY':'NOT READY'} · Models: ${j.loaded_models.join(', ')||'none'} · In progress: ${j.active_model||'none'} · Waiting: ${j.queued}/${j.max_queue_size} · Key configured: ${j.api_key_configured?'yes':'no'}`;
}catch(e){el('health').textContent=`Unable to reach service: ${e.message}`;}
}
el('refresh').addEventListener('click',updateHealth);
el('send').addEventListener('click', async ()=>{
const button=el('send');button.disabled=true;el('reply').textContent='Sending…';
try {
const r=await fetch('/v1/chat',{
method:'POST',
headers:{'Content-Type':'application/json','X-API-Key':el('key').value},
body:JSON.stringify({model:el('model').value,business_name:el('business').value,message:el('message').value,context:el('context').value,max_tokens:128})
});
const j=await r.json();
el('reply').textContent=r.ok?`${j.answer}\n\nModel: ${j.model} · Queue: ${j.queue_ms}ms · Inference: ${j.inference_ms}ms`:JSON.stringify(j,null,2);
}catch(e){el('reply').textContent=`Connection error: ${e.message}`;}
finally{button.disabled=false;updateHealth();}
});
updateHealth();
</script></body></html>
|