parent
bd9cb4e8b7
commit
3319a5d492
@ -1,5 +1,42 @@
|
|||||||
<!--
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
This is the fullscreen UI of the 01.
|
<head>
|
||||||
|
<title>Chat</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
-->
|
<body>
|
||||||
|
<form action="" onsubmit="sendMessage(event)">
|
||||||
|
<textarea id="messageInput" rows="10" cols="50" autocomplete="off"></textarea>
|
||||||
|
<button>Send</button>
|
||||||
|
</form>
|
||||||
|
<div id="messages"></div>
|
||||||
|
<script>
|
||||||
|
var ws = new WebSocket("ws://localhost:8000/");
|
||||||
|
var lastMessageElement = null;
|
||||||
|
ws.onmessage = function (event) {
|
||||||
|
if (lastMessageElement == null) {
|
||||||
|
lastMessageElement = document.createElement('p');
|
||||||
|
document.getElementById('messages').appendChild(lastMessageElement);
|
||||||
|
}
|
||||||
|
lastMessageElement.innerHTML += event.data;
|
||||||
|
};
|
||||||
|
function sendMessage(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var input = document.getElementById("messageInput");
|
||||||
|
var message = input.value;
|
||||||
|
if (message.startsWith('{') && message.endsWith('}')) {
|
||||||
|
message = JSON.stringify(JSON.parse(message));
|
||||||
|
}
|
||||||
|
ws.send(message);
|
||||||
|
var userMessageElement = document.createElement('p');
|
||||||
|
userMessageElement.innerHTML = '<b>' + input.value + '</b><br>';
|
||||||
|
document.getElementById('messages').appendChild(userMessageElement);
|
||||||
|
lastMessageElement = document.createElement('p');
|
||||||
|
document.getElementById('messages').appendChild(lastMessageElement);
|
||||||
|
input.value = '';
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -0,0 +1,33 @@
|
|||||||
|
import threading
|
||||||
|
from datetime import datetime
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
class Clock:
|
||||||
|
def __init__(self, computer):
|
||||||
|
self.computer = computer
|
||||||
|
|
||||||
|
def schedule(self, dt, message):
|
||||||
|
# Calculate the delay in seconds
|
||||||
|
delay = (dt - datetime.now()).total_seconds()
|
||||||
|
|
||||||
|
# Create a timer
|
||||||
|
timer = threading.Timer(delay, self.add_message_to_queue, args=[message])
|
||||||
|
|
||||||
|
# Start the timer
|
||||||
|
timer.start()
|
||||||
|
|
||||||
|
def add_message_to_queue(self, message):
|
||||||
|
|
||||||
|
# Define the message data and convert it to JSON
|
||||||
|
message_json = json.dumps({
|
||||||
|
"role": "computer",
|
||||||
|
"type": "message",
|
||||||
|
"content": message
|
||||||
|
})
|
||||||
|
|
||||||
|
# Write the JSON data to the file
|
||||||
|
timestamp = str(int(time.time()))
|
||||||
|
with open(f"/01/core/queue/{timestamp}.json", "w") as file:
|
||||||
|
file.write(message_json)
|
||||||
|
|
@ -1,33 +1,62 @@
|
|||||||
"""
|
"""
|
||||||
Responsible for taking an interpreter, then serving it at "/" as a POST SSE endpoint, accepting and streaming LMC Messages.
|
Responsible for taking an interpreter, then serving it at "/" as a websocket, accepting and streaming LMC Messages.
|
||||||
|
|
||||||
https://docs.openinterpreter.com/protocols/lmc-messages
|
https://docs.openinterpreter.com/protocols/lmc-messages
|
||||||
|
|
||||||
Also needs to be saving conversations, and checking the queue.
|
Also needs to be saving conversations, and checking the queue.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Generator
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from fastapi import FastAPI, Request, Response
|
from fastapi import FastAPI, WebSocket
|
||||||
from starlette.exceptions import DisconnectedClientError
|
import asyncio
|
||||||
|
import json
|
||||||
|
|
||||||
def main(interpreter):
|
def main(interpreter):
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
@app.post("/")
|
@app.websocket("/")
|
||||||
async def i_endpoint(request: Request) -> Response:
|
async def i_test(websocket: WebSocket):
|
||||||
async def event_stream() -> Generator[str, None, None]:
|
await websocket.accept()
|
||||||
data = await request.json()
|
while True:
|
||||||
# TODO: Save conversation to /conversations
|
data = await websocket.receive_text()
|
||||||
|
while data.strip().lower() != "stop": # Stop command
|
||||||
|
task = asyncio.create_task(websocket.receive_text())
|
||||||
|
|
||||||
|
# This would be terrible for production. Just for testing.
|
||||||
try:
|
try:
|
||||||
for response in interpreter.chat(message=data["message"], stream=True):
|
data_dict = json.loads(data)
|
||||||
yield response
|
if set(data_dict.keys()) == {"role", "content", "type"} or set(
|
||||||
# TODO: Check queue. Do we need to break (I guess we need a while loop around this..?)
|
data_dict.keys()
|
||||||
# and handle the new message from the queue? Then delete the message from the queue.
|
) == {"role", "content", "type", "format"}:
|
||||||
except DisconnectedClientError:
|
data = data_dict
|
||||||
print("Client disconnected")
|
except json.JSONDecodeError:
|
||||||
# TODO: Save conversation to /conversations
|
pass
|
||||||
return Response(event_stream(), media_type="text/event-stream")
|
|
||||||
|
for response in interpreter.chat(
|
||||||
|
message=data, stream=True, display=False
|
||||||
|
):
|
||||||
|
if task.done():
|
||||||
|
data = task.result() # Get the new message
|
||||||
|
break # Break the loop and start processing the new message
|
||||||
|
# Send out assistant message chunks
|
||||||
|
if (
|
||||||
|
response.get("type") == "message"
|
||||||
|
and response["role"] == "assistant"
|
||||||
|
and "content" in response
|
||||||
|
):
|
||||||
|
await websocket.send_text(response["content"])
|
||||||
|
await asyncio.sleep(0.01) # Add a small delay
|
||||||
|
if (
|
||||||
|
response.get("type") == "message"
|
||||||
|
and response["role"] == "assistant"
|
||||||
|
and response.get("end") == True
|
||||||
|
):
|
||||||
|
await websocket.send_text("\n")
|
||||||
|
await asyncio.sleep(0.01) # Add a small delay
|
||||||
|
if not task.done():
|
||||||
|
data = (
|
||||||
|
await task
|
||||||
|
) # Wait for the next message if it hasn't arrived yet
|
||||||
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|
Loading…
Reference in new issue