Merge branch 'main' of https://github.com/OpenInterpreter/01 into react-native-app

pull/263/head
Ben Xu 8 months ago
commit 4994132c19

@ -8,6 +8,13 @@
<br><a href="https://openinterpreter.com/01">Preorder the Light</a> | <a href="https://changes.openinterpreter.com">Get Updates</a> | <a href="https://01.openinterpreter.com/">Documentation</a><br> <br><a href="https://openinterpreter.com/01">Preorder the Light</a> | <a href="https://changes.openinterpreter.com">Get Updates</a> | <a href="https://01.openinterpreter.com/">Documentation</a><br>
</p> </p>
<div align="center">
| [日本語](docs/README_JP.md) | [English](README.md) |
</div>
<br> <br>
![OI-O1-BannerDemo-2](https://www.openinterpreter.com/OI-O1-BannerDemo-3.jpg) ![OI-O1-BannerDemo-2](https://www.openinterpreter.com/OI-O1-BannerDemo-3.jpg)

@ -0,0 +1,83 @@
## For End Users
[Announcment video](https://www.youtube.com/watch?v=jWr-WeXAdeI)
[Wes Roth](https://www.youtube.com/@WesRoth)
<details>
<summary>Details</summary>
No technical coverage
</details>
---
[Announcment video](https://www.youtube.com/watch?v=JaBFT3fF2fk)
[TheAIGRID](https://www.youtube.com/@TheAiGrid)
<details>
<summary>Details</summary>
[here](https://youtu.be/JaBFT3fF2fk?si=8zPGO-U6WdLNnISw&t=656)
mentions the current lack of windows support
</details>
---
[Announcment video](https://www.youtube.com/watch?v=Q_p82HtBqoc)
[Matt Berman](https://www.youtube.com/@matthew_berman)
<details>
<summary>Details</summary>
[here](https://youtu.be/Q_p82HtBqoc?si=aAxjWZnBdwBbaOUr&t=579)
Berman shows an install of 01 using conda and python 3.9
in.. looks like linux.. shows how to get openai keys.
</details>
---
[Announcment video](https://www.youtube.com/watch?v=q0dJ7T7au2Y)
[WorldofAI](https://www.youtube.com/@intheworldofai)
<details>
<summary>Details</summary>
<!-- Add details here -->
</details>
---
[Breakdown video](https://www.youtube.com/watch?v=W-VwN0n4d9Y)
[Mervin Praison](https://www.youtube.com/@MervinPraison)
<details>
<summary>Details</summary>
- uses conda to install 01 and uses python 3.11 on linux.. maybe mac
- 0:00 Introduction to Open Interpreter
- 0:47 Creating Apps and Summarizing Documents
- 1:20 Image Modifications and Game Creation
- 2:55 Exploratory Data Analysis and Charting
- 4:00 Server Log Analysis
- 5:01 Image and Video Editing
- 6:00 Composing Music with AI
- 7:18 Calendar Management and Email Automation
- 9:01 Integrating with Fast API and LM Studio
</details>
---
[Breakdown video](https://www.youtube.com/watch?v=uyfoHQVgeY0)
[Gary Explains](https://www.youtube.com/@GaryExplains)
<br>for **open interpreter** not **01**
<details>
<summary>Details</summary>
- 3:45 states that it will run on mac/linux and windows and requires python 3.10
</details>
## For Developers
<BR>
Coming soon

@ -11,6 +11,7 @@ To set up audio recording + playback on the ESP32 (M5 Atom), do the following:
- M5Atom by M5Stack [Reference](https://www.arduino.cc/reference/en/libraries/m5atom/) - M5Atom by M5Stack [Reference](https://www.arduino.cc/reference/en/libraries/m5atom/)
- WebSockets by Markus Sattler [Reference](https://www.arduino.cc/reference/en/libraries/websockets/) - WebSockets by Markus Sattler [Reference](https://www.arduino.cc/reference/en/libraries/websockets/)
- AsyncTCP by dvarrel [Reference](https://github.com/dvarrel/AsyncTCP) - AsyncTCP by dvarrel [Reference](https://github.com/dvarrel/AsyncTCP)
- ESPAsyncWebServer by lacamera [Reference](https://github.com/lacamera/ESPAsyncWebServer)
Finally, to flash the .ino to the board, connect the board to the USB port, select the port from the dropdown on the IDE, then select the M5Atom board (or M5Stack-ATOM if you have that). Click on upload to flash the board. Finally, to flash the .ino to the board, connect the board to the USB port, select the port from the dropdown on the IDE, then select the M5Atom board (or M5Stack-ATOM if you have that). Click on upload to flash the board.

@ -3,6 +3,7 @@ from dotenv import load_dotenv
load_dotenv() # take environment variables from .env. load_dotenv() # take environment variables from .env.
import os import os
import sys
import asyncio import asyncio
import threading import threading
import pyaudio import pyaudio
@ -58,7 +59,16 @@ CAMERA_WARMUP_SECONDS = float(os.getenv("CAMERA_WARMUP_SECONDS", 0))
# Specify OS # Specify OS
current_platform = get_system_info() current_platform = get_system_info()
is_win10 = lambda: platform.system() == "Windows" and "10" in platform.version()
def is_win11():
return sys.getwindowsversion().build >= 22000
def is_win10():
try:
return platform.system() == "Windows" and "10" in platform.version() and not is_win11()
except:
return False
# Initialize PyAudio # Initialize PyAudio
p = pyaudio.PyAudio() p = pyaudio.PyAudio()
@ -72,6 +82,7 @@ class Device:
self.captured_images = [] self.captured_images = []
self.audiosegments = [] self.audiosegments = []
self.server_url = "" self.server_url = ""
self.ctrl_pressed = False
def fetch_image_from_camera(self, camera_index=CAMERA_DEVICE_INDEX): def fetch_image_from_camera(self, camera_index=CAMERA_DEVICE_INDEX):
"""Captures an image from the specified camera device and saves it to a temporary file. Adds the image to the captured_images list.""" """Captures an image from the specified camera device and saves it to a temporary file. Adds the image to the captured_images list."""
@ -256,23 +267,39 @@ class Device:
def on_press(self, key): def on_press(self, key):
"""Detect spacebar press and Ctrl+C combination.""" """Detect spacebar press and Ctrl+C combination."""
self.pressed_keys.add(key) # Add the pressed key to the set self.pressed_keys.add(key) # Add the pressed key to the set
if keyboard.Key.space in self.pressed_keys: if keyboard.Key.space in self.pressed_keys:
self.toggle_recording(True) self.toggle_recording(True)
elif {keyboard.Key.ctrl, keyboard.KeyCode.from_char("c")} <= self.pressed_keys: elif {keyboard.Key.ctrl, keyboard.KeyCode.from_char('c')} <= self.pressed_keys:
logger.info("Ctrl+C pressed. Exiting...") logger.info("Ctrl+C pressed. Exiting...")
kill_process_tree() kill_process_tree()
os._exit(0) os._exit(0)
# Windows alternative to the above
if key == keyboard.Key.ctrl_l:
self.ctrl_pressed = True
try:
if key.vk == 67 and self.ctrl_pressed:
logger.info("Ctrl+C pressed. Exiting...")
kill_process_tree()
os._exit(0)
# For non-character keys
except:
pass
def on_release(self, key): def on_release(self, key):
"""Detect spacebar release and 'c' key press for camera, and handle key release.""" """Detect spacebar release and 'c' key press for camera, and handle key release."""
self.pressed_keys.discard( self.pressed_keys.discard(key) # Remove the released key from the key press tracking set
key
) # Remove the released key from the key press tracking set
if key == keyboard.Key.ctrl_l:
self.ctrl_pressed = False
if key == keyboard.Key.space: if key == keyboard.Key.space:
self.toggle_recording(False) self.toggle_recording(False)
elif CAMERA_ENABLED and key == keyboard.KeyCode.from_char("c"): elif CAMERA_ENABLED and key == keyboard.KeyCode.from_char('c'):
self.fetch_image_from_camera() self.fetch_image_from_camera()
async def message_sender(self, websocket): async def message_sender(self, websocket):
@ -342,7 +369,7 @@ class Device:
code = message["content"] code = message["content"]
result = interpreter.computer.run(language, code) result = interpreter.computer.run(language, code)
send_queue.put(result) send_queue.put(result)
if is_win10(): if is_win10():
logger.info("Windows 10 detected") logger.info("Windows 10 detected")
# Workaround for Windows 10 not latching to the websocket server. # Workaround for Windows 10 not latching to the websocket server.

@ -355,7 +355,7 @@ async def listener(mobile: bool):
json.dump(interpreter.messages, file, indent=4) json.dump(interpreter.messages, file, indent=4)
# TODO: is triggering seemingly randomly # TODO: is triggering seemingly randomly
# logger.info("New user message recieved. Breaking.") # logger.info("New user message received. Breaking.")
# break # break
# Also check if there's any new computer messages # Also check if there's any new computer messages
@ -363,7 +363,7 @@ async def listener(mobile: bool):
with open(conversation_history_path, "w") as file: with open(conversation_history_path, "w") as file:
json.dump(interpreter.messages, file, indent=4) json.dump(interpreter.messages, file, indent=4)
logger.info("New computer message recieved. Breaking.") logger.info("New computer message received. Breaking.")
break break
except: except:
traceback.print_exc() traceback.print_exc()

@ -156,7 +156,7 @@ def stt_wav(service_directory, wav_file_path: str):
temp_dir, f"output_stt_{datetime.now().strftime('%Y%m%d%H%M%S%f')}.wav" temp_dir, f"output_stt_{datetime.now().strftime('%Y%m%d%H%M%S%f')}.wav"
) )
ffmpeg.input(wav_file_path).output( ffmpeg.input(wav_file_path).output(
output_path, acodec="pcm_s16le", ac=1, ar="16k" output_path, acodec="pcm_s16le", ac=1, ar="16k", loglevel="panic"
).run() ).run()
try: try:
transcript = get_transcription_file(service_directory, output_path) transcript = get_transcription_file(service_directory, output_path)

@ -5,12 +5,17 @@ load_dotenv() # take environment variables from .env.
import asyncio import asyncio
import subprocess import subprocess
import platform import platform
import os
import shutil
from .logs import setup_logging from .logs import setup_logging
from .logs import logger from .logs import logger
setup_logging() setup_logging()
# dmesg process created at boot time
dmesg_proc = None
def get_kernel_messages(): def get_kernel_messages():
""" """
@ -25,12 +30,37 @@ def get_kernel_messages():
output, _ = process.communicate() output, _ = process.communicate()
return output.decode("utf-8") return output.decode("utf-8")
elif current_platform == "Linux": elif current_platform == "Linux":
with open("/var/log/dmesg", "r") as file: log_path = get_dmesg_log_path()
with open(log_path, 'r') as file:
return file.read() return file.read()
else: else:
logger.info("Unsupported platform.") logger.info("Unsupported platform.")
def get_dmesg_log_path():
"""
Check for the existence of a readable dmesg log file and return its path.
Create an accessible path if not found.
"""
if os.access('/var/log/dmesg', os.F_OK | os.R_OK):
return '/var/log/dmesg'
global dmesg_proc
dmesg_log_path = '/tmp/dmesg'
if dmesg_proc:
return dmesg_log_path
logger.info("Created /tmp/dmesg.")
subprocess.run(['touch', dmesg_log_path])
dmesg_path = shutil.which('dmesg')
if dmesg_path:
logger.info(f"Writing to {dmesg_log_path} from dmesg.")
dmesg_proc = subprocess.Popen([dmesg_path, '--follow'], text=True, stdout=subprocess.PIPE)
subprocess.Popen(['tee', dmesg_log_path], text=True, stdin=dmesg_proc.stdout, stdout=subprocess.DEVNULL)
return dmesg_log_path
def custom_filter(message): def custom_filter(message):
# Check for {TO_INTERPRETER{ message here }TO_INTERPRETER} pattern # Check for {TO_INTERPRETER{ message here }TO_INTERPRETER} pattern
if "{TO_INTERPRETER{" in message and "}TO_INTERPRETER}" in message: if "{TO_INTERPRETER{" in message and "}TO_INTERPRETER}" in message:

@ -7,7 +7,11 @@ def kill_process_tree():
pid = os.getpid() # Get the current process ID pid = os.getpid() # Get the current process ID
try: try:
# Send SIGTERM to the entire process group to ensure all processes are targeted # Send SIGTERM to the entire process group to ensure all processes are targeted
os.killpg(os.getpgid(pid), signal.SIGKILL) try:
os.killpg(os.getpgid(pid), signal.SIGKILL)
# Windows implementation
except AttributeError:
os.kill(pid, signal.SIGTERM)
parent = psutil.Process(pid) parent = psutil.Process(pid)
children = parent.children(recursive=True) children = parent.children(recursive=True)
for child in children: for child in children:

@ -127,6 +127,10 @@ def _run(
# llm_service = "llamafile" # llm_service = "llamafile"
stt_service = "local-whisper" stt_service = "local-whisper"
select_local_model() select_local_model()
system_type = platform.system()
if system_type == "Windows":
server_host = "localhost"
if not server_url: if not server_url:
server_url = f"{server_host}:{server_port}" server_url = f"{server_host}:{server_port}"
@ -134,6 +138,8 @@ def _run(
if not server and not client: if not server and not client:
server = True server = True
client = True client = True
def handle_exit(signum, frame): def handle_exit(signum, frame):
os._exit(0) os._exit(0)

Loading…
Cancel
Save