14
14
import janus
15
15
import uvicorn
16
16
from fastapi import APIRouter , FastAPI , WebSocket
17
+ from fastapi .responses import PlainTextResponse
17
18
except :
18
19
# Server dependencies are not required by the main package.
19
20
pass
@@ -27,7 +28,7 @@ def __init__(self, *args, **kwargs):
27
28
self .stop_event = threading .Event ()
28
29
self .output_queue = None
29
30
self .id = os .getenv ("INTERPRETER_ID" , datetime .now ().timestamp ())
30
- self .print = True # Will print output
31
+ self .print = False # Will print output
31
32
32
33
self .server = Server (self )
33
34
@@ -129,6 +130,9 @@ def accumulate(self, chunk):
129
130
"""
130
131
Accumulates LMC chunks onto interpreter.messages.
131
132
"""
133
+ if type (chunk ) == str :
134
+ chunk = json .loads (chunk )
135
+
132
136
if type (chunk ) == dict :
133
137
if chunk .get ("format" ) == "active_line" :
134
138
# We don't do anything with these.
@@ -158,6 +162,121 @@ def create_router(async_interpreter):
158
162
async def heartbeat ():
159
163
return {"status" : "alive" }
160
164
165
+ @router .get ("/" )
166
+ async def home ():
167
+ return PlainTextResponse (
168
+ """
169
+ <!DOCTYPE html>
170
+ <html>
171
+ <head>
172
+ <title>Chat</title>
173
+ </head>
174
+ <body>
175
+ <form action="" onsubmit="sendMessage(event)">
176
+ <textarea id="messageInput" rows="10" cols="50" autocomplete="off"></textarea>
177
+ <button>Send</button>
178
+ </form>
179
+ <div id="messages"></div>
180
+ <script>
181
+ var ws = new WebSocket("ws://"""
182
+ + async_interpreter .server .host
183
+ + ":"
184
+ + str (async_interpreter .server .port )
185
+ + """/");
186
+ var lastMessageElement = null;
187
+ ws.onmessage = function(event) {
188
+ if (lastMessageElement == null) {
189
+ lastMessageElement = document.createElement('p');
190
+ document.getElementById('messages').appendChild(lastMessageElement);
191
+ lastMessageElement.innerHTML = "<br>"
192
+ }
193
+ var eventData = JSON.parse(event.data);
194
+ if (eventData.role == "assistant") {
195
+ if (eventData.type == "message") {
196
+ if (eventData.start) {
197
+ lastMessageElement = document.createElement('p');
198
+ document.getElementById('messages').appendChild(lastMessageElement);
199
+ lastMessageElement.innerHTML = "<br>";
200
+ }
201
+ if (eventData.content) {
202
+ lastMessageElement.innerHTML += eventData.content;
203
+ }
204
+ if (eventData.end) {
205
+ lastMessageElement.innerHTML += "<br>";
206
+ }
207
+ } else if (eventData.type == "code") {
208
+ if (eventData.start) {
209
+ lastMessageElement = document.createElement('p');
210
+ document.getElementById('messages').appendChild(lastMessageElement);
211
+ lastMessageElement.innerHTML = "<br><br>```" + eventData.format + "<br>";
212
+ }
213
+ if (eventData.content) {
214
+ lastMessageElement.innerHTML += eventData.content;
215
+ }
216
+ if (eventData.end) {
217
+ lastMessageElement.innerHTML += "<br>```<br><br>";
218
+ }
219
+ }
220
+ else if (eventData.role == "computer" && eventData.type == "console") {
221
+ if (eventData.start) {
222
+ lastMessageElement = document.createElement('p');
223
+ document.getElementById('messages').appendChild(lastMessageElement);
224
+ lastMessageElement.innerHTML = "<br><br>------<br><br>";
225
+ }
226
+ if (eventData.content && eventData.format == "output") {
227
+ lastMessageElement.innerHTML += eventData.content;
228
+ }
229
+ if (eventData.end) {
230
+ lastMessageElement.innerHTML += "<br><br>------<br><br>";
231
+ }
232
+ }
233
+ } else {
234
+ lastMessageElement.innerHTML += "<br>" + JSON.stringify(eventData) + "<br>";
235
+ }
236
+ };
237
+ function sendMessage(event) {
238
+ event.preventDefault();
239
+ var input = document.getElementById("messageInput");
240
+ var message = input.value;
241
+ if (message.startsWith('{') && message.endsWith('}')) {
242
+ message = JSON.stringify(JSON.parse(message));
243
+ ws.send(message);
244
+ } else {
245
+ var startMessageBlock = {
246
+ "role": "user",
247
+ "type": "message",
248
+ "start": true
249
+ };
250
+ ws.send(JSON.stringify(startMessageBlock));
251
+
252
+ var messageBlock = {
253
+ "role": "user",
254
+ "type": "message",
255
+ "content": message
256
+ };
257
+ ws.send(JSON.stringify(messageBlock));
258
+
259
+ var endMessageBlock = {
260
+ "role": "user",
261
+ "type": "message",
262
+ "end": true
263
+ };
264
+ ws.send(JSON.stringify(endMessageBlock));
265
+ }
266
+ var userMessageElement = document.createElement('p');
267
+ userMessageElement.innerHTML = '<b>' + input.value + '</b><br>';
268
+ document.getElementById('messages').appendChild(userMessageElement);
269
+ lastMessageElement = document.createElement('p');
270
+ document.getElementById('messages').appendChild(lastMessageElement);
271
+ input.value = '';
272
+ }
273
+ </script>
274
+ </body>
275
+ </html>
276
+ """ ,
277
+ media_type = "text/html" ,
278
+ )
279
+
161
280
@router .websocket ("/" )
162
281
async def websocket_endpoint (websocket : WebSocket ):
163
282
await websocket .accept ()
@@ -168,6 +287,8 @@ async def receive_input():
168
287
try :
169
288
data = await websocket .receive ()
170
289
290
+ print ("RECIEVED:" , data )
291
+
171
292
if data .get ("type" ) == "websocket.receive" and "text" in data :
172
293
data = json .loads (data ["text" ])
173
294
await async_interpreter .input (data )
@@ -200,6 +321,7 @@ async def send_output():
200
321
if isinstance (output , bytes ):
201
322
await websocket .send_bytes (output )
202
323
else :
324
+ # output["time"] = time.time()
203
325
await websocket .send_text (json .dumps (output ))
204
326
except Exception as e :
205
327
error = traceback .format_exc () + "\n " + str (e )
0 commit comments