|
|
<!doctype html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="utf-8"/> |
|
|
<title>Brain UI – Test Panel</title> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/> |
|
|
<style> |
|
|
body{font-family:system-ui,Segoe UI,Roboto,Helvetica,Arial,sans-serif;margin:0;background:#0b0f19;color:#e5e7eb} |
|
|
header{padding:16px 20px;background:#111827;position:sticky;top:0} |
|
|
h1{margin:0;font-size:18px} |
|
|
main{padding:20px;display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(320px,1fr))} |
|
|
section{background:#111827;border:1px solid #1f2937;border-radius:12px;padding:16px} |
|
|
h2{margin:0 0 12px 0;font-size:16px} |
|
|
label{display:block;margin:8px 0 4px 0} |
|
|
input[type="text"],textarea{width:100%;padding:10px;border-radius:8px;border:1px solid #374151;background:#0b1220;color:#e5e7eb} |
|
|
input[type="file"]{margin:8px 0 12px 0} |
|
|
button{background:#2563eb;border:none;color:white;padding:10px 14px;border-radius:8px;cursor:pointer} |
|
|
button:disabled{opacity:0.6;cursor:not-allowed} |
|
|
.row{display:flex;gap:8px;flex-wrap:wrap} |
|
|
pre{white-space:pre-wrap;background:#0b1220;border:1px solid #1f2937;color:#cbd5e1;border-radius:8px;padding:10px;max-height:220px;overflow:auto} |
|
|
audio{width:100%;margin-top:8px} |
|
|
small{opacity:.7} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<header><h1>Brain UI · TTS · STT · Code Help · Memory</h1></header> |
|
|
<main> |
|
|
|
|
|
<section id="warmup"> |
|
|
<h2>Warmup / Health</h2> |
|
|
<div class="row"> |
|
|
<button onclick="doHealth()">GET /health</button> |
|
|
<button onclick="doWarmup()">POST /warmup</button> |
|
|
</div> |
|
|
<pre id="healthOut"></pre> |
|
|
</section> |
|
|
|
|
|
<section id="tts"> |
|
|
<h2>TTS</h2> |
|
|
<label>Text</label> |
|
|
<textarea id="ttsText" rows="3">Hello from Brain through ActualTTS.</textarea> |
|
|
<div class="row"><button id="ttsBtn" onclick="doTTS()">POST /speak</button></div> |
|
|
<audio id="ttsAudio" controls></audio> |
|
|
<pre id="ttsOut"></pre> |
|
|
</section> |
|
|
|
|
|
<section id="stt"> |
|
|
<h2>STT</h2> |
|
|
<label>Audio file (.wav recommended)</label> |
|
|
<input type="file" id="sttFile" accept="audio/*"/> |
|
|
<div class="row"><button id="sttBtn" onclick="doSTT()">POST /transcribe</button></div> |
|
|
<pre id="sttOut"></pre> |
|
|
</section> |
|
|
|
|
|
<section id="codehelp"> |
|
|
<h2>Code Help</h2> |
|
|
<label>Viewport text</label> |
|
|
<textarea id="vp" rows="4">def foo(): return 1 print(reslt)</textarea> |
|
|
<div class="row"><button id="codeBtn" onclick="doCodeHelp()">POST /code_help</button></div> |
|
|
<pre id="codeOut"></pre> |
|
|
</section> |
|
|
|
|
|
<section id="memory"> |
|
|
<h2>Memory</h2> |
|
|
<label>Item</label> |
|
|
<input type="text" id="memItem" placeholder="Something to remember"/> |
|
|
<div class="row"> |
|
|
<button onclick="saveMem('short')">Save to short</button> |
|
|
<button onclick="saveMem('sess')">Save to sess</button> |
|
|
<button onclick="saveMem('proj')">Save to proj</button> |
|
|
<button onclick="clearMem('')">Clear ALL</button> |
|
|
</div> |
|
|
<div class="row"> |
|
|
<button onclick="clearMem('short')">Clear short</button> |
|
|
<button onclick="clearMem('sess')">Clear sess</button> |
|
|
<button onclick="clearMem('proj')">Clear proj</button> |
|
|
<button onclick="loadMem()">GET /memory</button> |
|
|
</div> |
|
|
<pre id="memOut"></pre> |
|
|
</section> |
|
|
|
|
|
</main> |
|
|
<script> |
|
|
async function doHealth(){ |
|
|
const r = await fetch('/health'); const j = await r.json(); |
|
|
document.getElementById('healthOut').textContent = JSON.stringify(j,null,2); |
|
|
} |
|
|
async function doWarmup(){ |
|
|
const r = await fetch('/warmup',{method:'POST'}); const j = await r.json(); |
|
|
document.getElementById('healthOut').textContent = JSON.stringify(j,null,2); |
|
|
} |
|
|
async function doTTS(){ |
|
|
const btn = document.getElementById('ttsBtn'); btn.disabled=true; |
|
|
try{ |
|
|
const text = document.getElementById('ttsText').value; |
|
|
const r = await fetch('/speak',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({text})}); |
|
|
const j = await r.json(); |
|
|
document.getElementById('ttsOut').textContent = JSON.stringify(j,null,2); |
|
|
if(j.ok && j.audio_url){ |
|
|
const a = document.getElementById('ttsAudio'); a.src = j.audio_url; a.play().catch(()=>{}); |
|
|
} |
|
|
}finally{btn.disabled=false} |
|
|
} |
|
|
async function doSTT(){ |
|
|
const btn = document.getElementById('sttBtn'); btn.disabled=true; |
|
|
try{ |
|
|
const f = document.getElementById('sttFile').files[0]; |
|
|
if(!f){ alert('Pick an audio file'); return; } |
|
|
const fd = new FormData(); fd.append('file', f, f.name); |
|
|
const r = await fetch('/transcribe',{method:'POST', body: fd}); |
|
|
const j = await r.json(); |
|
|
document.getElementById('sttOut').textContent = JSON.stringify(j,null,2); |
|
|
}finally{btn.disabled=false} |
|
|
} |
|
|
async function doCodeHelp(){ |
|
|
const btn = document.getElementById('codeBtn'); btn.disabled=true; |
|
|
try{ |
|
|
const viewportText = document.getElementById('vp').value; |
|
|
const payload = { |
|
|
utterance: "please fix the error and make it run", |
|
|
telemetry: { |
|
|
file: "main.py", |
|
|
lang: "python", |
|
|
cursor: {l: 1, c: 1}, |
|
|
viewport: {start: 1, end: viewportText.split('\n').length, text: viewportText}, |
|
|
diag: [], |
|
|
term: "" |
|
|
}, |
|
|
memory: {short:[], sess:[], proj:[]}, |
|
|
response_mode: "patch" |
|
|
}; |
|
|
const r = await fetch('/code_help',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)}); |
|
|
const j = await r.json(); |
|
|
document.getElementById('codeOut').textContent = JSON.stringify(j,null,2); |
|
|
}finally{btn.disabled=false} |
|
|
} |
|
|
async function loadMem(){ |
|
|
const r = await fetch('/memory'); const j = await r.json(); |
|
|
document.getElementById('memOut').textContent = JSON.stringify(j,null,2); |
|
|
} |
|
|
async function saveMem(bucket){ |
|
|
const item = document.getElementById('memItem').value; |
|
|
const r = await fetch('/memory/save',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({bucket, item})}); |
|
|
const j = await r.json(); |
|
|
document.getElementById('memOut').textContent = JSON.stringify(j,null,2); |
|
|
} |
|
|
async function clearMem(bucket){ |
|
|
const r = await fetch('/memory/clear',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({bucket})}); |
|
|
const j = await r.json(); |
|
|
document.getElementById('memOut').textContent = JSON.stringify(j,null,2); |
|
|
} |
|
|
</script> |
|
|
</body> |
|
|
</html> |