Skip to content

Commit bee3f3c

Browse files
committed
Better profiles, commands, system message
1 parent a5290cd commit bee3f3c

File tree

7 files changed

+356
-253
lines changed

7 files changed

+356
-253
lines changed

interpreter_1/cli.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import argparse
22
import asyncio
3+
import os
34
import sys
45
from concurrent.futures import ThreadPoolExecutor
56
from typing import Any, Dict
@@ -114,14 +115,19 @@ def parse_args():
114115
# Create profile with defaults
115116
profile = Profile()
116117
# Load from default location if it exists
117-
profile.load(Profile.DEFAULT_PROFILE_PATH)
118+
default_profile_path = os.path.expanduser(Profile.DEFAULT_PROFILE_PATH)
119+
if os.path.exists(default_profile_path):
120+
profile.load(Profile.DEFAULT_PROFILE_PATH)
118121

119122
parser = argparse.ArgumentParser(add_help=False)
120123

121124
# Hidden arguments
122125
parser.add_argument("--help", "-h", action="store_true", help=argparse.SUPPRESS)
123126
parser.add_argument("--version", action="store_true", help=argparse.SUPPRESS)
124127
parser.add_argument("--input", action="store", help=argparse.SUPPRESS)
128+
parser.add_argument(
129+
"--profiles", action="store_true", help="Open profiles directory"
130+
)
125131

126132
# Add arguments programmatically from config
127133
arg_params = _profile_to_arg_params(profile)
@@ -135,6 +141,18 @@ def parse_args():
135141

136142
args = vars(parser.parse_args())
137143

144+
# Handle profiles flag
145+
if args["profiles"]:
146+
profile_dir = os.path.expanduser(Profile.DEFAULT_PROFILE_FOLDER)
147+
if sys.platform == "win32":
148+
os.startfile(profile_dir)
149+
else:
150+
import subprocess
151+
152+
opener = "open" if sys.platform == "darwin" else "xdg-open"
153+
subprocess.run([opener, profile_dir])
154+
sys.exit(0)
155+
138156
# If a different profile is specified, load it
139157
if args["profile"] != profile.profile_path:
140158
profile.load(args["profile"])

interpreter_1/commands.py

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import os
2+
import platform
3+
from typing import Any, Dict, Tuple, Type
4+
5+
from .profiles import Profile
6+
7+
SETTINGS: Dict[str, Tuple[Type, str]] = {
8+
"model": (str, "Model (e.g. claude-3-5-sonnet-20241022)"),
9+
"provider": (str, "Provider (e.g. anthropic, openai)"),
10+
"system_message": (str, "System message"),
11+
"tools": (list, "Enabled tools (comma-separated: interpreter,editor,gui)"),
12+
"auto_run": (bool, "Auto-run tools without confirmation"),
13+
"tool_calling": (bool, "Enable/disable tool calling"),
14+
"api_base": (str, "Custom API endpoint"),
15+
"api_key": (str, "API key"),
16+
"api_version": (str, "API version"),
17+
"temperature": (float, "Sampling temperature (0-1)"),
18+
"max_turns": (int, "Maximum conversation turns (-1 for unlimited)"),
19+
}
20+
21+
22+
def parse_value(value_str: str, type_hint: type) -> Any:
23+
"""Convert string value to appropriate type"""
24+
if type_hint == bool:
25+
return value_str.lower() in ("true", "yes", "1", "on")
26+
if type_hint == list:
27+
return value_str.split(",")
28+
if type_hint == float:
29+
return float(value_str)
30+
if type_hint == int:
31+
return int(value_str)
32+
return value_str
33+
34+
35+
def print_help() -> None:
36+
"""Print help message for available commands"""
37+
print("Available Commands:")
38+
print(" /help Show this help message")
39+
print("\nProfile Management:")
40+
print(" /profile show Show current profile location")
41+
print(
42+
" /profile save [path] Save settings to profile (default: ~/.openinterpreter)"
43+
)
44+
print(" /profile load <path> Load settings from profile")
45+
print(" /profile reset Reset settings to defaults")
46+
print("\nSettings:")
47+
for name, (type_hint, help_text) in SETTINGS.items():
48+
if type_hint == bool:
49+
print(f" /set {name} <true/false> {help_text}")
50+
else:
51+
print(f" /set {name} <value> {help_text}")
52+
print()
53+
54+
55+
class CommandHandler:
56+
def __init__(self, interpreter):
57+
self.interpreter = interpreter
58+
59+
def handle_command(self, cmd: str, parts: list[str]) -> bool:
60+
"""Handle / commands for controlling interpreter settings"""
61+
62+
# Handle /help
63+
if cmd == "/help":
64+
print_help()
65+
return True
66+
67+
# Handle /profile commands
68+
if cmd == "/profile":
69+
return self._handle_profile_command(parts)
70+
71+
# Handle /set commands
72+
if cmd == "/set":
73+
return self._handle_set_command(parts)
74+
75+
# Not a recognized command
76+
return False
77+
78+
def _handle_profile_command(self, parts: list[str]) -> bool:
79+
if len(parts) < 2:
80+
print(
81+
"Error: Missing profile command. Use /help to see available commands."
82+
)
83+
return True
84+
85+
subcmd = parts[1].lower()
86+
path = parts[2] if len(parts) > 2 else None
87+
88+
if subcmd == "show":
89+
return self._handle_profile_show()
90+
elif subcmd == "save":
91+
return self._handle_profile_save(path)
92+
elif subcmd == "load":
93+
return self._handle_profile_load(path)
94+
elif subcmd == "reset":
95+
return self._handle_profile_reset()
96+
else:
97+
print(f"Unknown profile command: {subcmd}")
98+
print("Use /help to see available commands")
99+
return True
100+
101+
def _handle_profile_show(self) -> bool:
102+
path = os.path.expanduser(self.interpreter._profile.profile_path)
103+
if not os.path.exists(path):
104+
print(f"Profile does not exist yet. Current path would be: {path}")
105+
print("Use /profile save to create it")
106+
return True
107+
108+
if platform.system() == "Darwin": # macOS
109+
os.system(f"open -R '{path}'")
110+
elif platform.system() == "Windows":
111+
os.system(f"explorer /select,{path}")
112+
else:
113+
print(f"Current profile path: {path}")
114+
return True
115+
116+
def _handle_profile_save(self, path: str | None) -> bool:
117+
try:
118+
self.interpreter.save_profile(path)
119+
except Exception as e:
120+
print(f"Error saving profile: {str(e)}")
121+
return True
122+
123+
def _handle_profile_load(self, path: str | None) -> bool:
124+
if not path:
125+
print("Error: Missing path for profile load")
126+
return True
127+
try:
128+
self.interpreter.load_profile(path)
129+
print(f"Settings loaded from: {path}")
130+
except Exception as e:
131+
print(f"Error loading profile: {str(e)}")
132+
return True
133+
134+
def _handle_profile_reset(self) -> bool:
135+
# Create new profile with defaults
136+
self.interpreter._profile = Profile()
137+
# Update interpreter attributes
138+
for key, value in self.interpreter._profile.to_dict().items():
139+
if key != "profile":
140+
setattr(self.interpreter, key, value)
141+
142+
print("Settings reset to defaults. To save this profile, use /profile save")
143+
return True
144+
145+
def _handle_set_command(self, parts: list[str]) -> bool:
146+
if len(parts) < 2:
147+
print("Error: Missing parameter name")
148+
return True
149+
150+
param = parts[1].lower()
151+
152+
if param not in SETTINGS:
153+
print(f"Unknown parameter: {param}")
154+
return True
155+
156+
if len(parts) < 3:
157+
print(f"Error: Missing value for {param}")
158+
return True
159+
160+
value_str = parts[2]
161+
type_hint, _ = SETTINGS[param]
162+
try:
163+
value = parse_value(value_str, type_hint)
164+
setattr(self.interpreter, param, value)
165+
print(f"Set {param} = {value}")
166+
except (ValueError, TypeError) as e:
167+
print(f"Error setting {param}: {str(e)}")
168+
return True

0 commit comments

Comments
 (0)