diff --git a/OS/01/device.py b/OS/01/device.py index 8d675e1..cf1f41a 100644 --- a/OS/01/device.py +++ b/OS/01/device.py @@ -1,6 +1,7 @@ import asyncio import threading import os +import logging import pyaudio from starlette.websockets import WebSocket from queue import Queue @@ -22,6 +23,9 @@ from interpreter import interpreter # Just for code execution. Maybe we should l from utils.kernel import put_kernel_messages_into_queue from stt import stt_wav +# Configure logging +logging.basicConfig(format='%(message)s', level=logging.getLevelName(os.getenv('DEBUG_LEVEL', 'INFO').upper())) + # Configuration for Audio Recording CHUNK = 1024 # Record in chunks of 1024 samples FORMAT = pyaudio.paInt16 # 16 bits per sample @@ -51,7 +55,7 @@ def record_audio(): """Record audio from the microphone and add it to the queue.""" stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) - print("Recording started...") + logging.info("Recording started...") global RECORDING # Create a temporary WAV file to store the audio data @@ -69,7 +73,7 @@ def record_audio(): wav_file.close() stream.stop_stream() stream.close() - print("Recording stopped.") + logging.info("Recording stopped.") duration = wav_file.getnframes() / RATE if duration < 0.3: @@ -120,7 +124,7 @@ def on_release(key): if key == keyboard.Key.space: toggle_recording(False) elif key == keyboard.Key.esc: - print("Exiting...") + logging.info("Exiting...") os._exit(0) import asyncio @@ -137,20 +141,21 @@ async def websocket_communication(WS_URL): while True: try: async with websockets.connect(WS_URL) as websocket: - print("Press the spacebar to start/stop recording. Press ESC to exit.") + logging.info("Press the spacebar to start/stop recording. Press ESC to exit.") asyncio.create_task(message_sender(websocket)) message_so_far = {"role": None, "type": None, "format": None, "content": None} while True: message = await websocket.recv() - - print("Got this message from the server:", type(message), message) + + logging.debug(f"Got this message from the server: {type(message)} {message}") if type(message) == str: message = json.loads(message) if "content" in message: + print(message['content'], end="", flush=True) if any(message_so_far[key] != message[key] for key in message_so_far): message_so_far = message else: @@ -178,7 +183,7 @@ async def websocket_communication(WS_URL): except: # traceback.print_exc() - print(f"Connecting to `{WS_URL}`...") + logging.info(f"Connecting to `{WS_URL}`...") await asyncio.sleep(2) diff --git a/OS/01/server.py b/OS/01/server.py index eaeae28..39352ae 100644 --- a/OS/01/server.py +++ b/OS/01/server.py @@ -4,6 +4,7 @@ import json import time import queue import os +import logging import traceback from queue import Queue from threading import Thread @@ -22,6 +23,9 @@ from utils.kernel import put_kernel_messages_into_queue from i import configure_interpreter from interpreter import interpreter +# Configure logging +logging.basicConfig(format='%(message)s', level=logging.getLevelName(os.getenv('DEBUG_LEVEL', 'INFO').upper())) + app = FastAPI() conversation_history_path = Path(__file__).parent / 'conversations' / 'user.json' @@ -64,10 +68,10 @@ if os.getenv('CODE_RUNNER') == "device": to_device.put({"role": "assistant", "type": "code", "format": "python", "end": True}) # Stream the response - print("Waiting for the device to respond...") + logging.info("Waiting for the device to respond...") while True: chunk = from_computer.get() - print("Server recieved from device:", chunk) + logging.info(f"Server received from device: {chunk}") if "end" in chunk: break yield chunk @@ -94,7 +98,7 @@ async def websocket_endpoint(websocket: WebSocket): await asyncio.gather(receive_task, send_task) except Exception as e: traceback.print_exc() - print(f"Connection lost. Error: {e}") + logging.info(f"Connection lost. Error: {e}") async def receive_messages(websocket: WebSocket): while True: @@ -109,7 +113,7 @@ async def receive_messages(websocket: WebSocket): async def send_messages(websocket: WebSocket): while True: message = await to_device.get() - print("Sending to the device:", type(message), message) + logging.debug(f"Sending to the device: {type(message)} {message}") await websocket.send_json(message) async def listener(): @@ -159,7 +163,7 @@ async def listener(): for chunk in interpreter.chat(messages, stream=True, display=False): - print("Got chunk:", chunk) + logging.debug("Got chunk:", chunk) # Send it to the user await to_device.put(chunk) @@ -195,7 +199,7 @@ async def listener(): with open(conversation_history_path, 'w') as file: json.dump(interpreter.messages, file) - print("New user message recieved. Breaking.") + logging.info("New user message recieved. Breaking.") break # Also check if there's any new computer messages @@ -204,7 +208,7 @@ async def listener(): with open(conversation_history_path, 'w') as file: json.dump(interpreter.messages, file) - print("New computer message recieved. Breaking.") + logging.info("New computer message recieved. Breaking.") break @@ -236,7 +240,7 @@ 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) - print("Starting `server.py`...") + logging.info("Starting `server.py`...") config = Config(app, host=parsed_url.hostname, port=parsed_url.port, lifespan='on') server = Server(config) diff --git a/OS/01/start.sh b/OS/01/start.sh index e4a5df7..bbf5448 100755 --- a/OS/01/start.sh +++ b/OS/01/start.sh @@ -18,6 +18,10 @@ export STT_RUNNER=device # If server, audio will be sent over websocket. # Will expose the server publically and display that URL. export SERVER_EXPOSE_PUBLICALLY=False +# Debug level +# export DEBUG_LEVEL=DEBUG +export DEBUG_LEVEL="DEBUG" + ### SETUP # (for dev, reset the ports we were using) diff --git a/OS/01/stt.py b/OS/01/stt.py index e4b282b..6f3a5a0 100644 --- a/OS/01/stt.py +++ b/OS/01/stt.py @@ -4,6 +4,7 @@ Defines a function which takes a path to an audio file and turns it into text. from datetime import datetime import os +import logging import contextlib import tempfile import ffmpeg @@ -11,6 +12,9 @@ import subprocess import openai from openai import OpenAI +# Configure logging +logging.basicConfig(format='%(message)s', level=logging.getLevelName(os.getenv('DEBUG_LEVEL', 'INFO').upper())) + client = OpenAI() def convert_mime_type_to_format(mime_type: str) -> str: @@ -59,10 +63,10 @@ def stt_wav(wav_file_path: str): response_format="text" ) except openai.BadRequestError as e: - print("openai.BadRequestError:", e) + logging.info(f"openai.BadRequestError: {e}") return None - print("Transcription result:", transcript) + logging.info(f"Transcription result: {transcript}") return transcript else: # Local whisper here, given `wav_file_path` diff --git a/OS/01/utils/kernel.py b/OS/01/utils/kernel.py index da7d55f..dc58272 100644 --- a/OS/01/utils/kernel.py +++ b/OS/01/utils/kernel.py @@ -1,6 +1,11 @@ import asyncio import subprocess import platform +import os +import logging + +# Configure logging +logging.basicConfig(format='%(message)s', level=logging.getLevelName(os.getenv('DEBUG_LEVEL', 'INFO').upper())) def get_kernel_messages(): """ @@ -16,7 +21,7 @@ def get_kernel_messages(): with open('/var/log/dmesg', 'r') as file: return file.read() else: - print("Unsupported platform.") + logging.info("Unsupported platform.") def custom_filter(message): # Check for {TO_INTERPRETER{ message here }TO_INTERPRETER} pattern