Merge remote-tracking branch 'upstream/main' into u/shivenmian/local

pull/22/head
Shiven Mian 11 months ago
commit 4f84bb8982

@ -6,21 +6,19 @@ from starlette.websockets import WebSocket
from queue import Queue
from pynput import keyboard
import json
import traceback
import websockets
import queue
import pydub
import ast
from pydub import AudioSegment
from pydub.playback import play
import io
import time
import wave
import tempfile
from datetime import datetime
from interpreter import interpreter # Just for code execution. Maybe we should let people do from interpreter.computer import run?
from utils.kernel import put_kernel_messages_into_queue
from stt import stt_wav
import asyncio
from utils.logs import setup_logging
from utils.logs import logger
@ -34,10 +32,6 @@ RATE = 44100 # Sample rate
RECORDING = False # Flag to control recording state
SPACEBAR_PRESSED = False # Flag to track spacebar press state
# Configuration for WebSocket
WS_URL = os.getenv('SERVER_URL')
if not WS_URL:
raise ValueError("The environment variable SERVER_URL is not set. Please set it to proceed.")
# Initialize PyAudio
p = pyaudio.PyAudio()
@ -127,7 +121,6 @@ def on_release(key):
logger.info("Exiting...")
os._exit(0)
import asyncio
send_queue = queue.Queue()
@ -140,8 +133,12 @@ async def message_sender(websocket):
async def websocket_communication(WS_URL):
while True:
try:
async with websockets.connect(WS_URL) as websocket:
logger.info(f"Connecting to `{WS_URL}` ...")
headers = {"ngrok-skip-browser-warning": str(80), "User-Agent": "project01"} if os.getenv('NGROK_AUTHTOKEN') else {}
async with websockets.connect(WS_URL, extra_headers=headers) as websocket:
logger.info("Press the spacebar to start/stop recording. Press ESC to exit.")
asyncio.create_task(message_sender(websocket))
initial_message = {"role": None, "type": None, "format": None, "content": None}
@ -187,14 +184,20 @@ async def websocket_communication(WS_URL):
result = interpreter.computer.run(language, code)
send_queue.put(result)
except:
# traceback.print_exc()
logger.info(f"Connecting to `{WS_URL}`...")
except Exception as e:
logging.exception(f"An error occurred during websocket communication. {e}")
logging.info(f"Connecting to `{WS_URL}`...")
await asyncio.sleep(2)
if __name__ == "__main__":
# Configuration for WebSocket
async def main():
WS_URL = os.getenv('SERVER_CONNECTION_URL')
if not WS_URL:
raise ValueError("The environment variable SERVER_URL is not set. Please set it to proceed.")
# Start the WebSocket communication
asyncio.create_task(websocket_communication(WS_URL))

@ -1,12 +1,16 @@
git+https://github.com/KillianLucas/open-interpreter.git
asyncio
PyAudio
pynput
fastapi
uvicorn
websockets
playsound
python-dotenv
ffmpeg-python
textual
pydub
asyncio==3.4.3
PyAudio==0.2.14
pynput==1.7.6
fastapi==0.109.2
uvicorn==0.27.1
websockets==12.0
playsound==1.3.0
python-dotenv==1.0.1
ffmpeg-python==0.2.0
textual==0.50.1
pydub==0.25.1
ngrok==1.0.0
wheel

@ -1,17 +1,12 @@
from starlette.websockets import WebSocketDisconnect
import ast
import json
import time
import queue
import os
import traceback
from queue import Queue
from threading import Thread
import threading
import uvicorn
import re
from fastapi import FastAPI
from threading import Thread
from fastapi.responses import PlainTextResponse
from starlette.websockets import WebSocket
from stt import stt_bytes
from tts import tts
@ -21,6 +16,8 @@ import urllib.parse
from utils.kernel import put_kernel_messages_into_queue
from i import configure_interpreter
from interpreter import interpreter
import ngrok
import signal
from utils.logs import setup_logging
from utils.logs import logger
@ -90,6 +87,10 @@ if os.getenv('CODE_RUNNER') == "device":
# Configure interpreter
interpreter = configure_interpreter(interpreter)
@app.get("/ping")
async def ping():
return PlainTextResponse("pong")
@app.websocket("/")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
@ -233,6 +234,7 @@ from uvicorn import Config, Server
if __name__ == "__main__":
async def main():
# Start listening
asyncio.create_task(listener())
@ -244,6 +246,19 @@ if __name__ == "__main__":
if not server_url:
raise ValueError("The environment variable SERVER_URL is not set. Please set it to proceed.")
parsed_url = urllib.parse.urlparse(server_url)
# Set up Ngrok
ngrok_auth_token = os.getenv('NGROK_AUTHTOKEN')
if ngrok_auth_token is not None:
logger.info("Setting up Ngrok")
ngrok_listener = await ngrok.forward(f"{parsed_url.hostname}:{parsed_url.port}", authtoken=ngrok_auth_token)
ngrok_parsed_url = urllib.parse.urlparse(ngrok_listener.url())
# Setup SERVER_URL environment variable for device to use
connection_url = f"wss://{ngrok_parsed_url.hostname}/"
logger.info(f"Ngrok established at {ngrok_parsed_url.geturl()}")
logger.info(f"\033[1mSERVER_CONNECTION_URL should be set to \"{connection_url}\"\033[0m")
logger.info("Starting `server.py`...")
config = Config(app, host=parsed_url.hostname, port=parsed_url.port, lifespan='on')

@ -5,8 +5,12 @@
export ALL_LOCAL=False
export WHISPER_MODEL_NAME="ggml-tiny.en.bin"
# Set the OpenAI API key for OpenInterpreter to work
# export OPENAI_API_KEY=sk-...
# Uncomment and set the OpenAI API key for OpenInterpreter to work
# export OPENAI_API_KEY="sk-..."
# Expose through Ngrok
# Uncomment following line with your Ngrok auth token (https://dashboard.ngrok.com/get-started/your-authtoken)
# export NGROK_AUTHTOKEN="AUTH_TOKEN"
# For TTS, we use the en_US-lessac-medium voice model by default
# Please change the voice URL and voice name if you wish to use another voice
@ -16,6 +20,7 @@ export PIPER_VOICE_NAME="en_US-lessac-medium.onnx"
# If SERVER_START, this is where we'll serve the server.
# If DEVICE_START, this is where the device expects the server to be.
export SERVER_URL=ws://localhost:8000/
export SERVER_CONNECTION_URL=$SERVER_URL # Comment if setting up through Ngrok
export SERVER_START=True
export DEVICE_START=True
@ -31,6 +36,7 @@ export SERVER_EXPOSE_PUBLICALLY=False
# export LOG_LEVEL=DEBUG
export LOG_LEVEL="INFO"
### SETUP
# if using local models, install the models / executables
@ -89,6 +95,14 @@ fi
start_device() {
echo "Starting device..."
if [[ -n $NGROK_AUTHTOKEN ]]; then
echo "Waiting for Ngrok to setup"
sleep 7
read -p "Enter the Ngrok URL: " ngrok_url
export SERVER_CONNECTION_URL=$ngrok_url
echo "SERVER_CONNECTION_URL set to $SERVER_CONNECTION_URL"
fi
python device.py &
DEVICE_PID=$!
echo "Device started as process $DEVICE_PID"
@ -116,18 +130,18 @@ stop_processes() {
# Trap SIGINT and SIGTERM to stop processes when the script is terminated
trap stop_processes SIGINT SIGTERM
# DEVICE
# Start device if DEVICE_START is True
if [[ "$DEVICE_START" == "True" ]]; then
start_device
fi
# SERVER
# Start server if SERVER_START is True
if [[ "$SERVER_START" == "True" ]]; then
start_server
fi
# DEVICE
# Start device if DEVICE_START is True
if [[ "$DEVICE_START" == "True" ]]; then
start_device
fi
# Wait for device and server processes to exit
wait $DEVICE_PID
wait $SERVER_PID

Loading…
Cancel
Save