Skip to content

Commit

Permalink
Better profiles, commands, system message, ioctl fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
KillianLucas committed Nov 14, 2024
1 parent bee3f3c commit 55db632
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 29 deletions.
File renamed without changes.
21 changes: 2 additions & 19 deletions interpreter_1/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,2 @@
- server
- tools [interpreter,editor,gui]
- allowed_commands
- allowed_paths
- system_message
- custom_instructions
- model
- api_base
- api_key
- api_version
- provider
- max_budget
- max_turns
- profile ~/.openinterpreter
- auto_run
- tool_calling

i --model ollama/llama3.2 --no-tool-calling --custom-instructions "
You can execute code by enclosing it in markdown code blocks."
curl openinterpreter.com/cli | bash
interpreter
17 changes: 15 additions & 2 deletions interpreter_1/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ def _profile_to_arg_params(profile: Profile) -> Dict[str, Dict[str, Any]]:
"dest": "tool_calling",
"help": "Disable tool calling (enabled by default)",
},
"interactive": {
"flags": ["--interactive"],
"action": "store_true",
"default": profile.interactive,
"help": "Enable interactive mode (enabled by default)",
},
"no_interactive": {
"flags": ["--no-interactive"],
"action": "store_false",
"default": profile.interactive,
"dest": "interactive",
"help": "Disable interactive mode",
},
# Behavior configuration
"system_message": {
"flags": ["--system-message"],
Expand Down Expand Up @@ -239,8 +252,8 @@ async def async_load():
pass
print()

if interpreter.interactive:
interpreter.chat() # Continue in interactive mode
# if interpreter.interactive:
# interpreter.chat() # Continue in interactive mode


if __name__ == "__main__":
Expand Down
14 changes: 11 additions & 3 deletions interpreter_1/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,9 +693,17 @@ def chat(self):
)
if self._prompt_session is None:
self._prompt_session = PromptSession()
user_input = self._prompt_session.prompt(
"> ", placeholder=placeholder
).strip()

try:
# Prompt toolkit requires terminal size to work properly
# If this fails, prompt toolkit will look weird, so we fall back to standard input
os.get_terminal_size()
user_input = self._prompt_session.prompt(
"> ",
placeholder=placeholder,
).strip()
except:
user_input = input("> ").strip()
print()

# Handle multi-line input
Expand Down
1 change: 1 addition & 0 deletions interpreter_1/misc/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def help_message():
{BLUE_COLOR}--allowed-commands{RESET_COLOR} Commands the model can execute
{BLUE_COLOR}--allowed-paths{RESET_COLOR} Paths the model can access
{BLUE_COLOR}--no-tool-calling{RESET_COLOR} Disable tool usage (enabled by default)
{BLUE_COLOR}--no-stream{RESET_COLOR} Disable streaming (enabled by default)
{BLUE_COLOR}--auto-run{RESET_COLOR}, {BLUE_COLOR}-y{RESET_COLOR} Auto-run suggested commands
{BLUE_COLOR}--interactive{RESET_COLOR} Enable interactive mode (enabled if sys.stdin.isatty())
{BLUE_COLOR}--no-interactive{RESET_COLOR} Disable interactive mode
Expand Down
5 changes: 4 additions & 1 deletion interpreter_1/misc/welcome.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@


def welcome_message(args):
terminal_width = os.get_terminal_size().columns
try:
terminal_width = os.get_terminal_size().columns
except:
terminal_width = 80
print()
renderer = MarkdownRenderer()

Expand Down
152 changes: 152 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#!/usr/bin/env bash

# Exit on error
set -e

# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}

# Function to print error messages
error() {
echo "Error: $1" >&2
exit 1
}

# Function to print status messages
info() {
echo "$1"
}

# Function for cleanup on failure
cleanup() {
info "Cleaning up after installation failure..."
if [ -d "$VENV_DIR" ]; then
rm -rf "$VENV_DIR"
fi
}

# Set trap for cleanup on script failure
trap cleanup ERR

# Install uv if it's not already installed
if ! command_exists uv; then
info "Installing uv package manager..."
if [[ "$OSTYPE" == "darwin"* ]] || [[ "$OSTYPE" == "linux-gnu"* ]]; then
if command_exists curl; then
curl -LsSf https://astral.sh/uv/install.sh | sh
elif command_exists wget; then
wget -qO- https://astral.sh/uv/install.sh | sh
else
error "Neither curl nor wget found. Please install either curl or wget first."
fi
elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
else
error "Unsupported operating system"
fi
fi

# Function to check Python version compatibility
check_python_version() {
local version=$1
if [[ $version =~ ^3\.(9|1[0-9])(\.[0-9]+)?$ ]]; then
return 0
fi
return 1
}

# Find existing compatible Python version or install one
info "Checking for compatible Python (>=3.9,<4)..."
existing_python=""
while IFS= read -r version; do
if check_python_version "$version"; then
existing_python=$version
break
fi
done < <(uv python list 2>/dev/null || true)

if [ -z "$existing_python" ]; then
info "Installing Python 3.11..."
uv python install 3.11 || error "Failed to install Python"
existing_python="3.11"
fi

info "Using Python $existing_python"

# Function to get user data directory
get_user_data_dir() {
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
echo "$USERPROFILE/.openinterpreter"
elif [[ -n "${XDG_DATA_HOME}" ]]; then
echo "${XDG_DATA_HOME}/openinterpreter"
else
echo "$HOME/.openinterpreter"
fi
}

# Define installation directories
INSTALL_DIR="$(get_user_data_dir)"
VENV_DIR="$INSTALL_DIR/venv"

# Define bin directory for executables
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
BIN_DIR="$INSTALL_DIR/bin"
ACTIVATE_SCRIPT="$VENV_DIR/Scripts/activate"
WRAPPER_SCRIPT="$BIN_DIR/open-interpreter.cmd"
else
BIN_DIR="$HOME/.local/bin"
ACTIVATE_SCRIPT="$VENV_DIR/bin/activate"
WRAPPER_SCRIPT="$BIN_DIR/open-interpreter"
fi

# Create installation directories
info "Creating installation directories..."
mkdir -p "$INSTALL_DIR" "$BIN_DIR" || error "Failed to create installation directories"

# Create a virtual environment with the selected Python version
info "Creating virtual environment..."
uv venv --python "$existing_python" "$VENV_DIR" || error "Failed to create virtual environment"

# Create platform-specific wrapper script
info "Creating wrapper script..."
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
# Windows CMD wrapper
cat > "$WRAPPER_SCRIPT" << EOF
@echo off
call "$ACTIVATE_SCRIPT"
python -m interpreter %*
EOF

# Also create a PowerShell wrapper
WRAPPER_PS1="$BIN_DIR/open-interpreter.ps1"
cat > "$WRAPPER_PS1" << EOF
& "$ACTIVATE_SCRIPT"
python -m interpreter @args
EOF

# Add to User PATH if not already present
powershell -Command "[Environment]::SetEnvironmentVariable('Path', [Environment]::GetEnvironmentVariable('Path', 'User') + ';$BIN_DIR', 'User')"
info "Added $BIN_DIR to User PATH"
else
# Unix-like systems (Linux/macOS)
cat > "$WRAPPER_SCRIPT" << EOF
#!/bin/bash
source "$ACTIVATE_SCRIPT"
python -m interpreter "\$@"
EOF
chmod +x "$WRAPPER_SCRIPT" || error "Failed to make wrapper script executable"
fi

# Platform-specific final instructions
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
info "Installation complete! You can now use 'open-interpreter' from a new terminal window."
elif [[ "$OSTYPE" == "darwin"* ]]; then
info "Installation complete! You can now use the 'open-interpreter' command."
info "Make sure $BIN_DIR is in your PATH by adding this to your ~/.zshrc or ~/.bash_profile:"
info " export PATH=\"\$PATH:$BIN_DIR\""
else
info "Installation complete! You can now use the 'open-interpreter' command."
info "Make sure $BIN_DIR is in your PATH."
fi
43 changes: 39 additions & 4 deletions scripts/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,60 @@ def get_shell_script(shell_type):
# Function to capture terminal interaction
function capture_output() {
local cmd=$1
# Redirect with more thorough ANSI and cursor control stripping
exec 1> >(tee >(sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,3})*)?[mGKHF]//g; s/\x1B\[[0-9;]*[A-Za-z]//g; s/\r//g" >> ~/.shell_history_with_output))
exec 2> >(tee >(sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,3})*)?[mGKHF]//g; s/\x1B\[[0-9;]*[A-Za-z]//g; s/\r//g" >> ~/.shell_history_with_output))
echo "user: $cmd" >> ~/.shell_history_with_output
echo "computer:" >> ~/.shell_history_with_output
eval "$cmd" >> ~/.shell_history_with_output 2>&1
# Trim history file if it exceeds 20K characters
if [ $(wc -c < ~/.shell_history_with_output) -gt 20000 ]; then
# Keep only the last 15K characters to prevent frequent trimming
tail -c 15000 ~/.shell_history_with_output > ~/.shell_history_with_output.tmp
mv ~/.shell_history_with_output.tmp ~/.shell_history_with_output
fi
}
# After the command completes, reset the output redirection
function reset_output() {
exec 1>&1
exec 2>&2
}
# Command not found handler that pipes context to interpreter
command_not_found_handler() {
cat ~/.shell_history_with_output | interpreter
local cmd=$1
# echo "user: $cmd" >> ~/.shell_history_with_output
# echo "computer:" >> ~/.shell_history_with_output
# Capture output in temp file, display unstripped version, then process and append stripped version
output_file=$(mktemp)
interpreter --input "$(cat ~/.shell_history_with_output)" --instructions "You are in FAST mode. Be ultra-concise. Determine what the user is trying to do (most recently) and help them." 2>&1 | \
tee "$output_file"
cat "$output_file" | sed -r \
-e "s/\x1B\[([0-9]{1,3}(;[0-9]{1,3})*)?[mGKHF]//g" \
-e "s/\x1B\[[0-9;]*[A-Za-z]//g" \
-e "s/\]633;[^]]*\]//g" \
-e "s/^[[:space:]\.]*//;s/[[:space:]\.]*$//" \
-e "s/─{3,}//g" \
>> ~/.shell_history_with_output
rm "$output_file"
return 0
}
# Hook into preexec"""

if shell_type == "zsh":
return base_script + '\npreexec() {\n capture_output "$1"\n}\n'
return (
base_script
+ '\npreexec() {\n capture_output "$1"\n}\n\npostexec() {\n reset_output\n}\n'
)
elif shell_type == "bash":
return (
base_script
+ '\ntrap \'capture_output "$(HISTTIMEFORMAT= history 1 | sed "s/^[ ]*[0-9]*[ ]*//")" \' DEBUG\n'
+ "trap 'reset_output' RETURN\n"
)
return None

Expand Down Expand Up @@ -130,7 +165,7 @@ def main():
except Exception as e:
print(f"Error writing to {config_path}: {e}")
print(
"Please visit docs.openinterpreter.com/shell for manual installation instructions."
"Please visit docs.openinterpreter.com for manual installation instructions."
)


Expand Down

0 comments on commit 55db632

Please sign in to comment.