Skip to content

Commit 55db632

Browse files
committed
Better profiles, commands, system message, ioctl fixes
1 parent bee3f3c commit 55db632

File tree

8 files changed

+224
-29
lines changed

8 files changed

+224
-29
lines changed
File renamed without changes.

interpreter_1/README.md

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,2 @@
1-
- server
2-
- tools [interpreter,editor,gui]
3-
- allowed_commands
4-
- allowed_paths
5-
- system_message
6-
- custom_instructions
7-
- model
8-
- api_base
9-
- api_key
10-
- api_version
11-
- provider
12-
- max_budget
13-
- max_turns
14-
- profile ~/.openinterpreter
15-
- auto_run
16-
- tool_calling
17-
18-
i --model ollama/llama3.2 --no-tool-calling --custom-instructions "
19-
You can execute code by enclosing it in markdown code blocks."
1+
curl openinterpreter.com/cli | bash
2+
interpreter

interpreter_1/cli.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ def _profile_to_arg_params(profile: Profile) -> Dict[str, Dict[str, Any]]:
7979
"dest": "tool_calling",
8080
"help": "Disable tool calling (enabled by default)",
8181
},
82+
"interactive": {
83+
"flags": ["--interactive"],
84+
"action": "store_true",
85+
"default": profile.interactive,
86+
"help": "Enable interactive mode (enabled by default)",
87+
},
88+
"no_interactive": {
89+
"flags": ["--no-interactive"],
90+
"action": "store_false",
91+
"default": profile.interactive,
92+
"dest": "interactive",
93+
"help": "Disable interactive mode",
94+
},
8295
# Behavior configuration
8396
"system_message": {
8497
"flags": ["--system-message"],
@@ -239,8 +252,8 @@ async def async_load():
239252
pass
240253
print()
241254

242-
if interpreter.interactive:
243-
interpreter.chat() # Continue in interactive mode
255+
# if interpreter.interactive:
256+
# interpreter.chat() # Continue in interactive mode
244257

245258

246259
if __name__ == "__main__":

interpreter_1/interpreter.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -693,9 +693,17 @@ def chat(self):
693693
)
694694
if self._prompt_session is None:
695695
self._prompt_session = PromptSession()
696-
user_input = self._prompt_session.prompt(
697-
"> ", placeholder=placeholder
698-
).strip()
696+
697+
try:
698+
# Prompt toolkit requires terminal size to work properly
699+
# If this fails, prompt toolkit will look weird, so we fall back to standard input
700+
os.get_terminal_size()
701+
user_input = self._prompt_session.prompt(
702+
"> ",
703+
placeholder=placeholder,
704+
).strip()
705+
except:
706+
user_input = input("> ").strip()
699707
print()
700708

701709
# Handle multi-line input

interpreter_1/misc/help.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def help_message():
3535
{BLUE_COLOR}--allowed-commands{RESET_COLOR} Commands the model can execute
3636
{BLUE_COLOR}--allowed-paths{RESET_COLOR} Paths the model can access
3737
{BLUE_COLOR}--no-tool-calling{RESET_COLOR} Disable tool usage (enabled by default)
38+
{BLUE_COLOR}--no-stream{RESET_COLOR} Disable streaming (enabled by default)
3839
{BLUE_COLOR}--auto-run{RESET_COLOR}, {BLUE_COLOR}-y{RESET_COLOR} Auto-run suggested commands
3940
{BLUE_COLOR}--interactive{RESET_COLOR} Enable interactive mode (enabled if sys.stdin.isatty())
4041
{BLUE_COLOR}--no-interactive{RESET_COLOR} Disable interactive mode

interpreter_1/misc/welcome.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77

88

99
def welcome_message(args):
10-
terminal_width = os.get_terminal_size().columns
10+
try:
11+
terminal_width = os.get_terminal_size().columns
12+
except:
13+
terminal_width = 80
1114
print()
1215
renderer = MarkdownRenderer()
1316

scripts/install.sh

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#!/usr/bin/env bash
2+
3+
# Exit on error
4+
set -e
5+
6+
# Function to check if a command exists
7+
command_exists() {
8+
command -v "$1" >/dev/null 2>&1
9+
}
10+
11+
# Function to print error messages
12+
error() {
13+
echo "Error: $1" >&2
14+
exit 1
15+
}
16+
17+
# Function to print status messages
18+
info() {
19+
echo "$1"
20+
}
21+
22+
# Function for cleanup on failure
23+
cleanup() {
24+
info "Cleaning up after installation failure..."
25+
if [ -d "$VENV_DIR" ]; then
26+
rm -rf "$VENV_DIR"
27+
fi
28+
}
29+
30+
# Set trap for cleanup on script failure
31+
trap cleanup ERR
32+
33+
# Install uv if it's not already installed
34+
if ! command_exists uv; then
35+
info "Installing uv package manager..."
36+
if [[ "$OSTYPE" == "darwin"* ]] || [[ "$OSTYPE" == "linux-gnu"* ]]; then
37+
if command_exists curl; then
38+
curl -LsSf https://astral.sh/uv/install.sh | sh
39+
elif command_exists wget; then
40+
wget -qO- https://astral.sh/uv/install.sh | sh
41+
else
42+
error "Neither curl nor wget found. Please install either curl or wget first."
43+
fi
44+
elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
45+
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
46+
else
47+
error "Unsupported operating system"
48+
fi
49+
fi
50+
51+
# Function to check Python version compatibility
52+
check_python_version() {
53+
local version=$1
54+
if [[ $version =~ ^3\.(9|1[0-9])(\.[0-9]+)?$ ]]; then
55+
return 0
56+
fi
57+
return 1
58+
}
59+
60+
# Find existing compatible Python version or install one
61+
info "Checking for compatible Python (>=3.9,<4)..."
62+
existing_python=""
63+
while IFS= read -r version; do
64+
if check_python_version "$version"; then
65+
existing_python=$version
66+
break
67+
fi
68+
done < <(uv python list 2>/dev/null || true)
69+
70+
if [ -z "$existing_python" ]; then
71+
info "Installing Python 3.11..."
72+
uv python install 3.11 || error "Failed to install Python"
73+
existing_python="3.11"
74+
fi
75+
76+
info "Using Python $existing_python"
77+
78+
# Function to get user data directory
79+
get_user_data_dir() {
80+
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
81+
echo "$USERPROFILE/.openinterpreter"
82+
elif [[ -n "${XDG_DATA_HOME}" ]]; then
83+
echo "${XDG_DATA_HOME}/openinterpreter"
84+
else
85+
echo "$HOME/.openinterpreter"
86+
fi
87+
}
88+
89+
# Define installation directories
90+
INSTALL_DIR="$(get_user_data_dir)"
91+
VENV_DIR="$INSTALL_DIR/venv"
92+
93+
# Define bin directory for executables
94+
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
95+
BIN_DIR="$INSTALL_DIR/bin"
96+
ACTIVATE_SCRIPT="$VENV_DIR/Scripts/activate"
97+
WRAPPER_SCRIPT="$BIN_DIR/open-interpreter.cmd"
98+
else
99+
BIN_DIR="$HOME/.local/bin"
100+
ACTIVATE_SCRIPT="$VENV_DIR/bin/activate"
101+
WRAPPER_SCRIPT="$BIN_DIR/open-interpreter"
102+
fi
103+
104+
# Create installation directories
105+
info "Creating installation directories..."
106+
mkdir -p "$INSTALL_DIR" "$BIN_DIR" || error "Failed to create installation directories"
107+
108+
# Create a virtual environment with the selected Python version
109+
info "Creating virtual environment..."
110+
uv venv --python "$existing_python" "$VENV_DIR" || error "Failed to create virtual environment"
111+
112+
# Create platform-specific wrapper script
113+
info "Creating wrapper script..."
114+
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
115+
# Windows CMD wrapper
116+
cat > "$WRAPPER_SCRIPT" << EOF
117+
@echo off
118+
call "$ACTIVATE_SCRIPT"
119+
python -m interpreter %*
120+
EOF
121+
122+
# Also create a PowerShell wrapper
123+
WRAPPER_PS1="$BIN_DIR/open-interpreter.ps1"
124+
cat > "$WRAPPER_PS1" << EOF
125+
& "$ACTIVATE_SCRIPT"
126+
python -m interpreter @args
127+
EOF
128+
129+
# Add to User PATH if not already present
130+
powershell -Command "[Environment]::SetEnvironmentVariable('Path', [Environment]::GetEnvironmentVariable('Path', 'User') + ';$BIN_DIR', 'User')"
131+
info "Added $BIN_DIR to User PATH"
132+
else
133+
# Unix-like systems (Linux/macOS)
134+
cat > "$WRAPPER_SCRIPT" << EOF
135+
#!/bin/bash
136+
source "$ACTIVATE_SCRIPT"
137+
python -m interpreter "\$@"
138+
EOF
139+
chmod +x "$WRAPPER_SCRIPT" || error "Failed to make wrapper script executable"
140+
fi
141+
142+
# Platform-specific final instructions
143+
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then
144+
info "Installation complete! You can now use 'open-interpreter' from a new terminal window."
145+
elif [[ "$OSTYPE" == "darwin"* ]]; then
146+
info "Installation complete! You can now use the 'open-interpreter' command."
147+
info "Make sure $BIN_DIR is in your PATH by adding this to your ~/.zshrc or ~/.bash_profile:"
148+
info " export PATH=\"\$PATH:$BIN_DIR\""
149+
else
150+
info "Installation complete! You can now use the 'open-interpreter' command."
151+
info "Make sure $BIN_DIR is in your PATH."
152+
fi

scripts/setup.py

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,60 @@ def get_shell_script(shell_type):
4444
# Function to capture terminal interaction
4545
function capture_output() {
4646
local cmd=$1
47+
# Redirect with more thorough ANSI and cursor control stripping
48+
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))
49+
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))
50+
4751
echo "user: $cmd" >> ~/.shell_history_with_output
4852
echo "computer:" >> ~/.shell_history_with_output
49-
eval "$cmd" >> ~/.shell_history_with_output 2>&1
53+
54+
# Trim history file if it exceeds 20K characters
55+
if [ $(wc -c < ~/.shell_history_with_output) -gt 20000 ]; then
56+
# Keep only the last 15K characters to prevent frequent trimming
57+
tail -c 15000 ~/.shell_history_with_output > ~/.shell_history_with_output.tmp
58+
mv ~/.shell_history_with_output.tmp ~/.shell_history_with_output
59+
fi
60+
}
61+
62+
# After the command completes, reset the output redirection
63+
function reset_output() {
64+
exec 1>&1
65+
exec 2>&2
5066
}
5167
5268
# Command not found handler that pipes context to interpreter
5369
command_not_found_handler() {
54-
cat ~/.shell_history_with_output | interpreter
70+
local cmd=$1
71+
# echo "user: $cmd" >> ~/.shell_history_with_output
72+
# echo "computer:" >> ~/.shell_history_with_output
73+
74+
# Capture output in temp file, display unstripped version, then process and append stripped version
75+
output_file=$(mktemp)
76+
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 | \
77+
tee "$output_file"
78+
cat "$output_file" | sed -r \
79+
-e "s/\x1B\[([0-9]{1,3}(;[0-9]{1,3})*)?[mGKHF]//g" \
80+
-e "s/\x1B\[[0-9;]*[A-Za-z]//g" \
81+
-e "s/\]633;[^]]*\]//g" \
82+
-e "s/^[[:space:]\.]*//;s/[[:space:]\.]*$//" \
83+
-e "s/─{3,}//g" \
84+
>> ~/.shell_history_with_output
85+
rm "$output_file"
5586
return 0
5687
}
5788
5889
# Hook into preexec"""
5990

6091
if shell_type == "zsh":
61-
return base_script + '\npreexec() {\n capture_output "$1"\n}\n'
92+
return (
93+
base_script
94+
+ '\npreexec() {\n capture_output "$1"\n}\n\npostexec() {\n reset_output\n}\n'
95+
)
6296
elif shell_type == "bash":
6397
return (
6498
base_script
6599
+ '\ntrap \'capture_output "$(HISTTIMEFORMAT= history 1 | sed "s/^[ ]*[0-9]*[ ]*//")" \' DEBUG\n'
100+
+ "trap 'reset_output' RETURN\n"
66101
)
67102
return None
68103

@@ -130,7 +165,7 @@ def main():
130165
except Exception as e:
131166
print(f"Error writing to {config_path}: {e}")
132167
print(
133-
"Please visit docs.openinterpreter.com/shell for manual installation instructions."
168+
"Please visit docs.openinterpreter.com for manual installation instructions."
134169
)
135170

136171

0 commit comments

Comments
 (0)