Rename directories to software and source

pull/93/head
Ty Fiero 10 months ago
parent c8ea1a5554
commit d8e575d386

@ -27,7 +27,7 @@ jobs:
run: sudo apt-get install portaudio19-dev python-all-dev run: sudo apt-get install portaudio19-dev python-all-dev
- name: Install Poetry Package - name: Install Poetry Package
working-directory: 01OS # Set the working directory to "01OS" working-directory: software
run: | run: |
pip install --upgrade pip pip install --upgrade pip
pip install poetry==1.3.2 pip install poetry==1.3.2

@ -21,7 +21,7 @@ jobs:
defaults: defaults:
run: run:
working-directory: 01OS working-directory: software
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}

8
.gitignore vendored

@ -4,9 +4,9 @@ __pycache__/
*.py[cod] *.py[cod]
*$py.class *$py.class
01OS/01OS/server/conversations/user.json software/source/server/conversations/user.json
01OS/01OS/server/tts/local_service/* software/source/server/tts/local_service/*
01OS/01OS/server/stt/local_service/* software/source/server/stt/local_service/*
# C extensions # C extensions
*.so *.so
@ -167,5 +167,5 @@ cython_debug/
# ignore the aifs index files # ignore the aifs index files
_.aifs _.aifs
01OS/output_audio.wav software/output_audio.wav
.DS_Store .DS_Store

@ -1,26 +1,26 @@
repos: repos:
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.2.2" rev: "v0.2.2"
hooks: hooks:
- id: ruff - id: ruff
args: ["--fix"] args: ["--fix"]
- id: ruff-format - id: ruff-format
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0 rev: v4.5.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: end-of-file-fixer - id: end-of-file-fixer
- id: fix-encoding-pragma - id: fix-encoding-pragma
args: [--remove] args: [--remove]
- id: check-yaml - id: check-yaml
- id: debug-statements - id: debug-statements
language_version: python3 language_version: python3
- repo: local - repo: local
hooks: hooks:
- id: pytest - id: pytest
name: pytest name: pytest
entry: pytest 01OS/tests entry: pytest software/tests
language: system language: system
types: [python] types: [python]
pass_filenames: false pass_filenames: false
always_run: true always_run: true

@ -1,7 +0,0 @@
def hello_world():
return "Hello, World!"
# A test function to assert that hello_world() returns the expected string
def test_hello_world():
assert hello_world() == "Hello, World!"

@ -36,7 +36,7 @@ We intend to become the GNU/Linux of this space by staying open, modular, and fr
```shell ```shell
git clone https://github.com/OpenInterpreter/01 # Clone the repository git clone https://github.com/OpenInterpreter/01 # Clone the repository
cd 01/01OS # CD into the source directory cd 01/software # CD into the source directory
``` ```
<!-- > Not working? Read our [setup guide](https://docs.openinterpreter.com/getting-started/setup). --> <!-- > Not working? Read our [setup guide](https://docs.openinterpreter.com/getting-started/setup). -->
@ -146,7 +146,6 @@ The story of devices that came before the 01.
Things we want to steal great ideas from. Things we want to steal great ideas from.
<br> <br>

@ -1,50 +0,0 @@
### SETTINGS
# Copy this file and rename it to ".env" to use it.
# If ALL_LOCAL is False, we'll use OpenAI's services
# else we use whisper.cpp and piper local models
ALL_LOCAL=False
WHISPER_MODEL_NAME="ggml-tiny.en.bin"
WHISPER_MODEL_URL="https://huggingface.co/ggerganov/whisper.cpp/resolve/main/"
TEACH_MODE=False
# Uncomment to set your OpenAI API key
# OPENAI_API_KEY=sk-...
# 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
PIPER_VOICE_URL="https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/lessac/medium/"
PIPER_VOICE_NAME="en_US-lessac-medium.onnx"
# If SERVER_START, this is where we'll serve the server.
# If CLIENT_START, this is where the client expects the server to be.
# SERVER_URL=ws://localhost:10001/
SERVER_URL=ws://0.0.0.0:10001/
SERVER_START=True
CLIENT_START=True
# The port to start the local server on
SERVER_LOCAL_PORT=10001
# Explicitly set the client type (macos, rpi)
CLIENT_TYPE=auto
# Control where various operations happen— can be `client` or `server`.
CODE_RUNNER=server
TTS_RUNNER=server # If client, audio will be sent over websocket.
STT_RUNNER=client # If server, audio will be sent over websocket.
# Image capture settings
CAMERA_ENABLED=False
# Camera device selection (Typically 0 for built-in, 1 for USB)
CAMERA_DEVICE_INDEX=0
# Camera warmup time
# This is a workaround for some cameras that don't immediately
# return a properly exposed picture when they are first turned on
CAMERA_WARMUP_SECONDS=0.4
# Debug level
# LOG_LEVEL=DEBUG
LOG_LEVEL="INFO"

@ -1,255 +0,0 @@
#!/usr/bin/env bash
# Set python to prioritize the module files from the current directory
# If we don't do this, then the python interpreter will not be able to find the modules,
# and will throw an error like "ModuleNotFoundError: No module named '01OS'".
# If we solve the problem by pip installing the official 01OS package, then those
# modules will run instead of the local ones that we are trying to develop with.
export PYTHONPATH="$(pwd):$PYTHONPATH"
### Import Environment Variables from .env
SCRIPT_DIR="$(dirname "$0")"
if [ ! -f "$SCRIPT_DIR/.env" ]; then
echo "No .env file found. Copying from .env.example..."
cp "$SCRIPT_DIR/.env.example" "$SCRIPT_DIR/.env"
fi
set -a; source "$SCRIPT_DIR/.env"; set +a
### COMMAND LINE ARGUMENTS
# Set both SERVER_START and CLIENT_START to False if "--server" or "--client" is passed as an argument
# (This way, --server runs only the server, --client runs only the client.)
if [[ "$@" == *"--server"* ]] || [[ "$@" == *"--client"* ]]; then
export SERVER_START="False"
export CLIENT_START="False"
fi
# Check if "--local" is passed as an argument
if [[ "$@" == *"--local"* ]]; then
# If "--local" is passed, set ALL_LOCAL to True
export ALL_LOCAL="True"
fi
# Check if "--server" is passed as an argument
if [[ "$@" == *"--server"* ]]; then
# If "--server" is passed, set SERVER_START to True
export SERVER_START="True"
fi
# Check if "--teach" is passed as an argument
if [[ "$@" == *"--teach"* ]]; then
# If "--teach" is passed, set TEACH_MODE to True
export TEACH_MODE="True"
fi
# Check if "--client" is passed as an argument
if [[ "$@" == *"--client"* ]]; then
# If "--client" is passed, set CLIENT_START to True
export CLIENT_START="True"
# Extract the client type from the arguments
CLIENT_TYPE=$(echo "$@" | sed -n -e 's/^.*--client //p' | awk '{print $1}')
# If client type is not empty, export it
if [[ ! -z "$CLIENT_TYPE" ]]; then
export CLIENT_TYPE
fi
fi
# Check if "--expose" is passed as an argument
if [[ "$@" == *"--expose"* ]]; then
if [[ "$SERVER_START" != "True" ]]; then
echo "Error: Start script must be started with --serve for tunneling to work."
exit 1
else
export TUNNEL_START="True"
if [[ "$@" == *"--expose-with-bore"* ]]; then
export TUNNEL_METHOD="bore"
elif [[ "$@" == *"--expose-with-localtunnel"* ]]; then
export TUNNEL_METHOD="localtunnel"
elif [[ "$@" == *"--expose-with-ngrok"* ]]; then
export TUNNEL_METHOD="ngrok"
fi
echo "exposing server"
fi
fi
# Check if "--clear-local" is passed as an argument
if [[ "$@" == *"--clear-local"* ]]; then
# If "--clear-local" is passed, clear the contents of the folders in script_dir/01OS/server/{tts and stt}/local_service
echo "Clearing local services..."
rm -rf "$SCRIPT_DIR/01OS/server/tts/local_service"/*
rm -rf "$SCRIPT_DIR/01OS/server/stt/local_service"/*
echo "Exiting after clearing local services..."
exit 0
fi
### SKILLS PATH
OI_SKILLS_PATH="$SCRIPT_DIR/01OS/server/skills"
### SETUP
if [[ "$ALL_LOCAL" == "True" ]]; then
# if using local models, install the models / executables
CWD=$(pwd)
# Whisper setup
STT_PATH="$SCRIPT_DIR/01OS/server/stt"
WHISPER_RUST_PATH="${STT_PATH}/whisper-rust"
cd ${WHISPER_RUST_PATH}
# Check if whisper-rust executable exists before attempting to build
if [[ ! -f "${WHISPER_RUST_PATH}/target/release/whisper-rust" ]]; then
# Check if Rust is installed. Needed to build whisper executable
if ! command -v rustc &> /dev/null; then
echo "Rust is not installed or is not in system PATH. Please install Rust before proceeding."
exit 1
fi
# Build Whisper Rust executable if not found
cargo build --release
else
echo "Whisper Rust executable already exists. Skipping build."
fi
WHISPER_MODEL_PATH="${STT_PATH}/local_service"
if [[ ! -f "${WHISPER_MODEL_PATH}/${WHISPER_MODEL_NAME}" ]]; then
mkdir -p "${WHISPER_MODEL_PATH}"
curl -L "${WHISPER_MODEL_URL}${WHISPER_MODEL_NAME}" -o "${WHISPER_MODEL_PATH}/${WHISPER_MODEL_NAME}"
else
echo "Whisper model already exists. Skipping download."
fi
cd $CWD
## PIPER
PIPER_FOLDER_PATH="$SCRIPT_DIR/01OS/server/tts/local_service"
if [[ ! -d "$PIPER_FOLDER_PATH/piper" ]]; then # Check if the Piper directory exists
mkdir -p "${PIPER_FOLDER_PATH}"
# Determine OS and architecture
OS=$(uname -s)
ARCH=$(uname -m)
if [ "$OS" = "Darwin" ]; then
OS="macos"
if [ "$ARCH" = "arm64" ]; then
ARCH="aarch64"
elif [ "$ARCH" = "x86_64" ]; then
ARCH="x64"
else
echo "Piper: unsupported architecture"
fi
fi
PIPER_ASSETNAME="piper_${OS}_${ARCH}.tar.gz"
PIPER_URL="https://github.com/rhasspy/piper/releases/latest/download/"
# Save the current working directory
CWD=$(pwd)
# Navigate to SCRIPT_DIR/01OS/server/tts/local_service
cd ${PIPER_FOLDER_PATH}
curl -L "${PIPER_URL}${PIPER_ASSETNAME}" -o "${PIPER_ASSETNAME}"
tar -xvzf $PIPER_ASSETNAME
cd piper
curl -OL "${PIPER_VOICE_URL}${PIPER_VOICE_NAME}"
curl -OL "${PIPER_VOICE_URL}${PIPER_VOICE_NAME}.json"
# Additional setup for macOS
if [ "$OS" = "macos" ]; then
if [ "$ARCH" = "x64" ]; then
softwareupdate --install-rosetta --agree-to-license
fi
PIPER_PHONEMIZE_ASSETNAME="piper-phonemize_${OS}_${ARCH}.tar.gz"
PIPER_PHONEMIZE_URL="https://github.com/rhasspy/piper-phonemize/releases/latest/download/"
curl -OL "${PIPER_PHONEMIZE_URL}${PIPER_PHONEMIZE_ASSETNAME}"
tar -xvzf $PIPER_PHONEMIZE_ASSETNAME
PIPER_DIR=`pwd`
install_name_tool -change @rpath/libespeak-ng.1.dylib "${PIPER_DIR}/piper-phonemize/lib/libespeak-ng.1.dylib" "${PIPER_DIR}/piper"
install_name_tool -change @rpath/libonnxruntime.1.14.1.dylib "${PIPER_DIR}/piper-phonemize/lib/libonnxruntime.1.14.1.dylib" "${PIPER_DIR}/piper"
install_name_tool -change @rpath/libpiper_phonemize.1.dylib "${PIPER_DIR}/piper-phonemize/lib/libpiper_phonemize.1.dylib" "${PIPER_DIR}/piper"
fi
echo "Piper setup completed."
# Navigate back to the current working directory
cd $CWD
else
echo "Piper already set up. Skipping download."
fi
fi
### START
start_client() {
echo "Starting client..."
bash $SCRIPT_DIR/01OS/clients/start.sh &
CLIENT_PID=$!
echo "client started as process $CLIENT_PID"
}
# Function to start server
start_server() {
echo "Starting server..."
python -m 01OS.server.server &
SERVER_PID=$!
echo "Server started as process $SERVER_PID"
}
# Function to start tunnel service
start_tunnel() {
echo "Starting tunnel..."
./tunnel.sh &
TUNNEL_PID=$!
echo "Tunnel started as process $TUNNEL_PID"
}
stop_processes() {
if [[ -n $CLIENT_PID ]]; then
echo "Stopping client..."
kill $CLIENT_PID
fi
if [[ -n $SERVER_PID ]]; then
echo "Stopping server..."
kill $SERVER_PID
fi
if [[ -n $TUNNEL_PID ]]; then
echo "Stopping tunnel..."
kill $TUNNEL_PID
fi
}
# Trap SIGINT and SIGTERM to stop processes when the script is terminated
trap stop_processes SIGINT SIGTERM
# SERVER
# Start server if SERVER_START is True
if [[ "$SERVER_START" == "True" ]]; then
start_server
fi
# CLIENT
# Start client if CLIENT_START is True
if [[ "$CLIENT_START" == "True" ]]; then
start_client
fi
# TUNNEL
# Start tunnel if TUNNEL_START is True
if [[ "$TUNNEL_START" == "True" ]]; then
start_tunnel
fi
# Wait for client and server processes to exit
wait $CLIENT_PID
wait $SERVER_PID
wait $TUNNEL_PID
# TTS, STT
# (todo)
# (i think we should start with hosted services)
# LLM
# (disabled, we'll start with hosted services)
# python core/llm/start.py &

@ -1,65 +0,0 @@
#!/usr/bin/env bash
# Get tunnel method from TUNNEL_METHOD environment variable, but default to bore
# Possible options;
# - bore
# - localtunnel
# - ngrok
TUNNEL_METHOD=${TUNNEL_METHOD:-bore}
# Get the SERVER_PORT environment variable, but default to 10001
SERVER_LOCAL_PORT=${SERVER_LOCAL_PORT:-10001}
echo "Using $TUNNEL_METHOD to expose port $SERVER_LOCAL_PORT on localhost..."
# If the TUNNEL_METHOD is bore, then we need to check if the bore-cli is installed
if [[ "$TUNNEL_METHOD" == "bore" ]]; then
if ! command -v bore &> /dev/null; then
echo "The bore-cli command is not available. Please run 'cargo install bore-cli'."
echo "For more information, see https://github.com/ekzhang/bore"
exit 1
else
bore local $SERVER_LOCAL_PORT --to bore.pub | while IFS= read -r line; do
if [[ "$line" == *"listening at bore.pub:"* ]]; then
remote_port=$(echo "$line" | grep -o 'bore.pub:[0-9]*' | cut -d':' -f2)
echo "Please set your client env variable for SERVER_URL=ws://bore.pub:$remote_port"
break
fi
done
fi
elif [[ "$TUNNEL_METHOD" == "localtunnel" ]]; then
if ! command -v lt &> /dev/null; then
echo "The 'lt' command is not available."
echo "Please ensure you have Node.js installed, then run 'npm install -g localtunnel'."
echo "For more information, see https://github.com/localtunnel/localtunnel"
exit 1
else
npx localtunnel --port $SERVER_LOCAL_PORT | while IFS= read -r line; do
if [[ "$line" == *"your url is: https://"* ]]; then
remote_url=$(echo "$line" | grep -o 'https://[a-zA-Z0-9.-]*' | sed 's|https://||')
echo "Please set your client env variable for SERVER_URL=wss://$remote_url"
break
fi
done
fi
elif [[ "$TUNNEL_METHOD" == "ngrok" ]]; then
if ! command -v ngrok &> /dev/null; then
echo "The ngrok command is not available."
echo "Please install ngrok using the instructions at https://ngrok.com/docs/getting-started/"
exit 1
else
ngrok http $SERVER_LOCAL_PORT --log stdout | while IFS= read -r line; do
if [[ "$line" == *"started tunnel"* ]]; then
remote_url=$(echo "$line" | grep -o 'https://[a-zA-Z0-9.-]*' | sed 's|https://||')
echo "Please set your client env variable for SERVER_URL=wss://$remote_url"
break
fi
done
fi
fi

@ -30,9 +30,9 @@ sudo apt-get install portaudio19-dev ffmpeg cmake
### Install and run the 01 CLI ### Install and run the 01 CLI
```bash ```bash
# Clone the repo and navigate into the 01OS directory # Clone the repo and navigate into the software directory
git clone https://github.com/OpenInterpreter/01.git git clone https://github.com/OpenInterpreter/01.git
cd 01OS cd software
# Install dependencies and run 01 # Install dependencies and run 01
poetry install poetry install

@ -40,10 +40,10 @@ git clone https://github.com/OpenInterpreter/01.git
In order to run 01 on your computer, use [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer) In order to run 01 on your computer, use [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer)
Navigate to the project's 01OS directory: Navigate to the project's software directory:
```bash ```bash
cd 01OS cd software
``` ```
Install your project along with its dependencies in a virtual environment managed by Poetry. Install your project along with its dependencies in a virtual environment managed by Poetry.

@ -16,7 +16,7 @@ Open Interpreter is highly configurable and only requires updating a single file
```bash ```bash
# Edit i.py # Edit i.py
01OS/01OS/server/i.py software/source/server/i.py
``` ```
Properties such as `model`, `context_window`, and many more can be updated here. Properties such as `model`, `context_window`, and many more can be updated here.

@ -1,7 +1,7 @@
[tool.poetry] [tool.poetry]
name = "01OS" name = "01OS"
packages = [ packages = [
{include = "01OS"}, {include = "source"},
] ]
include = ["start.py"] include = ["start.py"]
version = "0.0.13" version = "0.0.13"

@ -0,0 +1,9 @@
; Config for Pytest Runner.
; suppress Deprecation Warning and User Warning to not spam the interface, but check periodically
[pytest]
python_files = tests.py test_*.py
filterwarnings =
ignore::UserWarning
ignore::DeprecationWarning
log_cli = true
log_cli_level = INFO

@ -0,0 +1,19 @@
import os
import sys
import pytest
from source.server.i import configure_interpreter
from unittest.mock import Mock
from interpreter import OpenInterpreter
from fastapi.testclient import TestClient
from .server import app
@pytest.fixture
def client():
return TestClient(app)
@pytest.fixture
def mock_interpreter():
interpreter = configure_interpreter(OpenInterpreter())
return interpreter

@ -408,7 +408,8 @@ async def main(server_host, server_port, llm_service, model, llm_supports_vision
"temperature": temperature "temperature": temperature
}) })
module = import_module(f'.server.services.{service}.{service_dict[service]}.{service}', package='01OS') module = import_module(f'.server.services.{service}.{service_dict[service]}.{service}', package='source')
ServiceClass = getattr(module, service.capitalize()) ServiceClass = getattr(module, service.capitalize())
service_instance = ServiceClass(config) service_instance = ServiceClass(config)
globals()[service] = getattr(service_instance, service) globals()[service] = getattr(service_instance, service)

@ -0,0 +1,41 @@
# test_main.py
import subprocess
import uuid
import pytest
from source.server.i import configure_interpreter
from unittest.mock import Mock
from fastapi.testclient import TestClient
@pytest.mark.asyncio
def test_ping(client):
response = client.get("/ping")
assert response.status_code == 200
assert response.text == "pong"
def test_interpreter_chat(mock_interpreter):
# Set up a sample conversation
messages = [
{"role": "user", "type": "message", "content": "Hello."},
{"role": "assistant", "type": "message", "content": "Hi there!"},
# Add more messages as needed
]
# Configure the mock interpreter with the sample conversation
mock_interpreter.messages = messages
# Simulate additional user input
user_input = {"role": "user", "type": "message", "content": "How are you?"}
mock_interpreter.chat([user_input])
# Ensure the interpreter processed the user input
assert len(mock_interpreter.messages) == len(messages)
assert mock_interpreter.messages[-1]["role"] == "assistant"
assert "don't have feelings" in mock_interpreter.messages[-1]["content"]
def test_interpreter_configuration(mock_interpreter):
# Test interpreter configuration
interpreter = configure_interpreter(mock_interpreter)
assert interpreter is not None

@ -5,7 +5,9 @@ import concurrent.futures
import threading import threading
import os import os
import importlib import importlib
create_tunnel = importlib.import_module(".server.tunnel", package="01OS").create_tunnel from source.server.tunnel import create_tunnel
from source.server.server import main
import signal import signal
app = typer.Typer() app = typer.Typer()
@ -105,7 +107,6 @@ def _run(
signal.signal(signal.SIGINT, handle_exit) signal.signal(signal.SIGINT, handle_exit)
if server: if server:
main = importlib.import_module(".server.server", package="01OS").main
loop = asyncio.new_event_loop() loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop) asyncio.set_event_loop(loop)
server_thread = threading.Thread(target=loop.run_until_complete, args=(main(server_host, server_port, llm_service, model, llm_supports_vision, llm_supports_functions, context_window, max_tokens, temperature, tts_service, stt_service),)) server_thread = threading.Thread(target=loop.run_until_complete, args=(main(server_host, server_port, llm_service, model, llm_supports_vision, llm_supports_functions, context_window, max_tokens, temperature, tts_service, stt_service),))
@ -130,7 +131,7 @@ def _run(
except FileNotFoundError: except FileNotFoundError:
client_type = "linux" client_type = "linux"
module = importlib.import_module(f".clients.{client_type}.device", package='01OS') module = importlib.import_module(f".clients.{client_type}.device", package='source')
client_thread = threading.Thread(target=module.main, args=[server_url]) client_thread = threading.Thread(target=module.main, args=[server_url])
client_thread.start() client_thread.start()
Loading…
Cancel
Save