File size: 6,193 Bytes
dd32e09
 
 
d1d7385
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dd32e09
 
d1d7385
426b3f8
d1d7385
 
 
 
426b3f8
 
d1d7385
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dd32e09
 
d1d7385
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dd32e09
 
 
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<!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():&#10;    return 1&#10;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>