parent
b9f4e92ef0
commit
849282ab50
Binary file not shown.
@ -1 +0,0 @@
|
||||
The app is responsible for accepting user input, sending it to "/" as an [LMC message](https://docs.openinterpreter.com/protocols/lmc-messages), then recieving [streaming LMC messages](https://docs.openinterpreter.com/guides/streaming-response) and somehow displaying them to the user.
|
@ -1,61 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<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;
|
||||
function connectWebSocket() {
|
||||
ws = new WebSocket("ws://localhost:8000/");
|
||||
ws.onopen = function(event) {
|
||||
console.log("Connected to WebSocket server.");
|
||||
|
||||
ws.onmessage = function (event) {
|
||||
if (lastMessageElement == null) {
|
||||
lastMessageElement = document.createElement('p');
|
||||
document.getElementById('messages').appendChild(lastMessageElement);
|
||||
}
|
||||
var data = JSON.parse(event.data);
|
||||
if (data.hasOwnProperty('content')) {
|
||||
lastMessageElement.innerHTML += data.content;
|
||||
}
|
||||
};
|
||||
};
|
||||
ws.onerror = function(error) {
|
||||
console.log("WebSocket error: ", error);
|
||||
};
|
||||
ws.onclose = function(event) {
|
||||
console.log("WebSocket connection closed. Retrying in 1 second...");
|
||||
setTimeout(connectWebSocket, 1000);
|
||||
};
|
||||
}
|
||||
connectWebSocket();
|
||||
var lastMessageElement = null;
|
||||
|
||||
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,28 @@
|
||||
while True:
|
||||
|
||||
message = None
|
||||
while message is None:
|
||||
message = get_from_queue('to_main')
|
||||
|
||||
if message == user_start_message:
|
||||
continue
|
||||
|
||||
messages = get_conversation_history()
|
||||
messages.append(message)
|
||||
save_conversation_history(message)
|
||||
|
||||
sentence = ""
|
||||
|
||||
for chunk in interpreter.chat(messages):
|
||||
|
||||
if queue_length() > 0:
|
||||
save_conversation_history(interpreter.messages)
|
||||
break
|
||||
|
||||
send_to_io(chunk)
|
||||
|
||||
sentence += chunk
|
||||
if is_full_sentence(sentence):
|
||||
audio = tts(sentence)
|
||||
sentence = ""
|
||||
send_to_io(audio)
|
@ -0,0 +1,5 @@
|
||||
@app.post("/i/")
|
||||
async def i(request: Request):
|
||||
message = await request.json()
|
||||
message = to_lmc(message)
|
||||
r.lpush("to_main", message)
|
Binary file not shown.
Binary file not shown.
@ -1,184 +0,0 @@
|
||||
"""
|
||||
Responsible for taking an interpreter, then serving it at "/" as a websocket, accepting and streaming LMC Messages.
|
||||
|
||||
https://docs.openinterpreter.com/protocols/lmc-messages
|
||||
|
||||
Also needs to be saving conversations, and checking the queue.
|
||||
"""
|
||||
|
||||
from typing import Optional, Tuple
|
||||
import uvicorn
|
||||
from fastapi import FastAPI, WebSocket
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import glob
|
||||
from interpreter.core.core import OpenInterpreter
|
||||
|
||||
def check_queue() -> dict:
|
||||
queue_files = glob.glob("interpreter/queue/*.json")
|
||||
if queue_files:
|
||||
with open(queue_files[0], 'r') as file:
|
||||
data = json.load(file)
|
||||
os.remove(queue_files[0])
|
||||
return data
|
||||
|
||||
def save_conversation(messages):
|
||||
with open('interpreter/conversations/user.json', 'w') as file:
|
||||
json.dump(messages, file)
|
||||
|
||||
def load_conversation():
|
||||
try:
|
||||
with open('interpreter/conversations/user.json', 'r') as file:
|
||||
messages = json.load(file)
|
||||
return messages
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
return []
|
||||
|
||||
|
||||
|
||||
|
||||
def main(interpreter: OpenInterpreter):
|
||||
app = FastAPI()
|
||||
|
||||
@app.websocket("/")
|
||||
async def i_test(websocket: WebSocket):
|
||||
await websocket.accept()
|
||||
data = None
|
||||
|
||||
while True:
|
||||
# This is the task for waiting for the user to send any message at all.
|
||||
try:
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
task = asyncio.create_task(websocket.receive_text())
|
||||
|
||||
if data == None: # Data will have stuff in it if we inturrupted it.
|
||||
while data == None:
|
||||
# Has the user sent a message?
|
||||
if task.done():
|
||||
try:
|
||||
data = {"role": "user", "type": "message", "content": task.result()}
|
||||
except Exception as e:
|
||||
print(e)
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
# Has the queue recieved a message?
|
||||
queued_message = check_queue()
|
||||
if queued_message:
|
||||
data = queued_message
|
||||
|
||||
await asyncio.sleep(0.2)
|
||||
|
||||
### CONVERSATION / DISC MANAGEMENT
|
||||
message = data
|
||||
messages = load_conversation()
|
||||
messages.append(message)
|
||||
save_conversation(messages)
|
||||
|
||||
### RESPONDING
|
||||
|
||||
# This is the task for waiting for user inturruptions.
|
||||
try:
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
task = asyncio.create_task(websocket.receive_text())
|
||||
|
||||
recieved_chunks = []
|
||||
|
||||
for chunk in interpreter.chat(
|
||||
messages, stream=True, display=True
|
||||
):
|
||||
|
||||
recieved_chunks.append(chunk)
|
||||
|
||||
# Has the user sent a message?
|
||||
if task.done():
|
||||
try:
|
||||
data = {"role": "user", "type": "message", "content": task.result()}
|
||||
except Exception as e:
|
||||
print(e)
|
||||
task.cancel() # The user didn't inturrupt
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
save_conversation(interpreter.messages)
|
||||
break
|
||||
|
||||
# Has the queue recieved a message?
|
||||
queued_message = check_queue()
|
||||
if queued_message:
|
||||
data = queued_message
|
||||
save_conversation(interpreter.messages)
|
||||
break
|
||||
|
||||
# Send out chunks
|
||||
await websocket.send_json(chunk)
|
||||
await asyncio.sleep(0.01) # Add a small delay
|
||||
|
||||
# If the interpreter just finished sending a message, save it
|
||||
if "end" in chunk:
|
||||
save_conversation(interpreter.messages)
|
||||
data = None
|
||||
|
||||
if not any([message["type"] == "code" for message in recieved_chunks]):
|
||||
for chunk in interpreter.chat(
|
||||
"Did you need to run code? It's okay if not, but please do if you did.", stream=True, display=True
|
||||
):
|
||||
# Has the user sent a message?
|
||||
if task.done():
|
||||
try:
|
||||
data = {"role": "user", "type": "message", "content": task.result()}
|
||||
except Exception as e:
|
||||
print(e)
|
||||
task.cancel() # The user didn't inturrupt
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
save_conversation(interpreter.messages)
|
||||
break
|
||||
|
||||
# Has the queue recieved a message?
|
||||
queued_message = check_queue()
|
||||
if queued_message:
|
||||
data = queued_message
|
||||
save_conversation(interpreter.messages)
|
||||
break
|
||||
|
||||
# Send out chunks
|
||||
await websocket.send_json(chunk)
|
||||
await asyncio.sleep(0.01) # Add a small delay
|
||||
|
||||
# If the interpreter just finished sending a message, save it
|
||||
if "end" in chunk:
|
||||
save_conversation(interpreter.messages)
|
||||
data = None
|
||||
|
||||
if not task.done():
|
||||
task.cancel() # User didn't inturrupt
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
@ -0,0 +1,11 @@
|
||||
last_timestamp = time.time()
|
||||
|
||||
while True:
|
||||
messages = get_dmesg(after=last_timestamp)
|
||||
last_timestamp = time.time()
|
||||
|
||||
for message in messages:
|
||||
if passes_filter(message)
|
||||
send_to_main(to_lmc(message))
|
||||
|
||||
time.sleep(1)
|
File diff suppressed because it is too large
Load Diff
@ -1,17 +0,0 @@
|
||||
[tool.poetry]
|
||||
name = "01-core"
|
||||
version = "0.0.1"
|
||||
description = "The python at the heart of the 01."
|
||||
authors = ["Open Interpreter <killian@openinterpreter.com>"]
|
||||
license = "AGPL"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
open-interpreter = "^0.2.0"
|
||||
uvicorn = {extras = ["standard"], version = "^0.27.0"}
|
||||
fastapi = "*"
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
@ -1,8 +0,0 @@
|
||||
### START THE LANGUAGE MODEL
|
||||
|
||||
# Disabled as we're starting with hosted models
|
||||
# python llm/start.py
|
||||
|
||||
### START THE INTERPRETER
|
||||
|
||||
python interpreter/start.py
|
@ -0,0 +1,16 @@
|
||||
<div class="centered-circle"></div>
|
||||
|
||||
<script>
|
||||
ws = new WebSocket("ws://localhost/server")
|
||||
ws.onmessage = event => {
|
||||
if (event.data == "user_start_message") {
|
||||
document.body.style.backgroundColor = "white"
|
||||
document.querySelector('.centered-circle')
|
||||
.style.backgroundColor = "black"
|
||||
} else if (event.data == "user_end_message") {
|
||||
document.body.style.backgroundColor = "black"
|
||||
document.querySelector('.centered-circle')
|
||||
.style.backgroundColor = "white"
|
||||
}
|
||||
}
|
||||
</script>
|
@ -0,0 +1,27 @@
|
||||
while True:
|
||||
|
||||
if button.is_pressed():
|
||||
send_to_main(user_start_message)
|
||||
send_to_websocket(user_start_message)
|
||||
|
||||
audio_chunks = []
|
||||
for audio_chunk in listen():
|
||||
audio_chunks.append(chunk)
|
||||
if not button.is_pressed():
|
||||
break
|
||||
|
||||
text = stt(audio_chunks)
|
||||
send_to_main(text)
|
||||
send_to_websocket(user_end_message)
|
||||
|
||||
chunk = get_from_queue('to_io')
|
||||
if chunk:
|
||||
send_to_websocket(chunk)
|
||||
sentence += chunk["content"]
|
||||
if is_full_sentence(sentence)
|
||||
tts(sentence)
|
||||
sentence = []
|
||||
|
||||
message = check_websocket()
|
||||
if message:
|
||||
send_to_main(message)
|
@ -0,0 +1 @@
|
||||
pip install git+https://github.com/KillianLucas/open-interpreter.git
|
@ -1,13 +1,45 @@
|
||||
### Start whisper.cpp and stuff?
|
||||
### SETUP
|
||||
|
||||
### APP
|
||||
# INSTALL REQUIREMENTS
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install redis-server
|
||||
pip install -r requirements.txt
|
||||
|
||||
# START REDIS
|
||||
|
||||
redis-cli -h localhost -p 6379 rpush to_interface ""
|
||||
redis-cli -h localhost -p 6379 rpush to_core ""
|
||||
|
||||
open app/index.html
|
||||
# ^ This should be to run it in fullscreen / kiosk mode
|
||||
|
||||
### CORE
|
||||
|
||||
cd core/
|
||||
pip install poetry
|
||||
poetry install
|
||||
poetry run bash start.sh
|
||||
# START KERNEL WATCHER
|
||||
|
||||
python core/kernel_watcher.py &
|
||||
|
||||
# START SST AND TTS SERVICES
|
||||
|
||||
# (todo)
|
||||
# (i think we should start with hosted services)
|
||||
|
||||
# START LLM
|
||||
|
||||
# (disabled, we'll start with hosted services)
|
||||
# python core/llm/start.py &
|
||||
|
||||
# START CORE
|
||||
|
||||
python core/start_core.py &
|
||||
|
||||
|
||||
### INTERFACE
|
||||
|
||||
# START INTERFACE
|
||||
|
||||
python interface/interface.py &
|
||||
|
||||
# START DISPLAY
|
||||
|
||||
# (this should be changed to run it in fullscreen / kiosk mode)
|
||||
open interface/display.html
|
Loading…
Reference in new issue