From a5290cd18ef383dc3e8140444af23709cda34b1c Mon Sep 17 00:00:00 2001 From: killian <63927363+KillianLucas@users.noreply.github.com> Date: Tue, 12 Nov 2024 11:40:52 -0800 Subject: [PATCH] Whitespace error fix and better piping --- interpreter_1/cli.py | 41 +++++++++++++++--------------- interpreter_1/interpreter.py | 49 +++++++++++++++++------------------- interpreter_1/misc/help.py | 8 +++--- interpreter_1/profiles.py | 3 ++- interpreter_1/tools/bash.py | 11 +++++--- 5 files changed, 56 insertions(+), 56 deletions(-) diff --git a/interpreter_1/cli.py b/interpreter_1/cli.py index ef270dc47..e711ca961 100644 --- a/interpreter_1/cli.py +++ b/interpreter_1/cli.py @@ -89,11 +89,6 @@ def _profile_to_arg_params(profile: Profile) -> Dict[str, Dict[str, Any]]: "default": profile.instructions, "help": "Appended to default system message", }, - "input": { - "flags": ["--input"], - "default": profile.input, - "help": "Set initial input message", - }, "max_turns": { "flags": ["--max-turns"], "type": int, @@ -125,6 +120,8 @@ def parse_args(): # Hidden arguments parser.add_argument("--help", "-h", action="store_true", help=argparse.SUPPRESS) + parser.add_argument("--version", action="store_true", help=argparse.SUPPRESS) + parser.add_argument("--input", action="store", help=argparse.SUPPRESS) # Add arguments programmatically from config arg_params = _profile_to_arg_params(profile) @@ -134,7 +131,7 @@ def parse_args(): # If second argument exists and doesn't start with '-', treat as input message if len(sys.argv) > 1 and not sys.argv[1].startswith("-"): - return {**vars(parser.parse_args([])), "input_message": " ".join(sys.argv[1:])} + return {**vars(parser.parse_args([])), "input": "i " + " ".join(sys.argv[1:])} args = vars(parser.parse_args()) @@ -146,16 +143,6 @@ def parse_args(): if key in args and args[key] is None: args[key] = value - if args["help"]: - from .misc.help import help_message - - arguments_string = "" - for action in parser._actions: - if action.help != argparse.SUPPRESS: - arguments_string += f"\n {action.option_strings[0]:<12} {action.help}" - help_message(arguments_string) - sys.exit(0) - return args @@ -172,6 +159,20 @@ def load_interpreter(): if hasattr(interpreter, key) and value is not None: setattr(interpreter, key, value) + if args["help"]: + from .misc.help import help_message + + help_message() + sys.exit(0) + + if args["version"]: + # Print version of currently installed interpreter + # Get this from the package metadata + from importlib.metadata import version + + print("Open Interpreter " + version("open-interpreter")) + sys.exit(0) + # Check if we should start the server if args["serve"]: # Load interpreter immediately for server mode @@ -208,13 +209,11 @@ async def async_load(): spinner.start() load_interpreter() spinner.stop() - if args["input"]: + + if args["input"] is not None: message = args["input"] else: message = sys.stdin.read().strip() - # print("---") - # print(message) - # print("---") interpreter.messages = [{"role": "user", "content": message}] # Run the generator until completion @@ -222,7 +221,7 @@ async def async_load(): pass print() - if sys.stdin.isatty(): + if interpreter.interactive: interpreter.chat() # Continue in interactive mode diff --git a/interpreter_1/interpreter.py b/interpreter_1/interpreter.py index ab25169d2..440535a20 100644 --- a/interpreter_1/interpreter.py +++ b/interpreter_1/interpreter.py @@ -345,7 +345,7 @@ async def async_respond(self): if getattr(self, "auto_run", False): user_approval = "y" else: - if not sys.stdin.isatty(): + if not self.interactive: print( "Error: Non-interactive environment requires auto_run=True to run tools" ) @@ -805,31 +805,28 @@ def chat(self): placeholder = HTML( f"<{placeholder_color}>{placeholder_text}" ) - if self.input: - user_input = self.input - else: - if self._prompt_session is None: - self._prompt_session = PromptSession() - user_input = self._prompt_session.prompt( - "> ", placeholder=placeholder - ).strip() - print() + if self._prompt_session is None: + self._prompt_session = PromptSession() + user_input = self._prompt_session.prompt( + "> ", placeholder=placeholder + ).strip() + print() - # Handle multi-line input - if user_input == '"""': - user_input = "" - print('> """') - while True: - placeholder = HTML( - f'<{placeholder_color}>Use """ again to finish' - ) - line = self._prompt_session.prompt( - "", placeholder=placeholder - ).strip() - if line == '"""': - break - user_input += line + "\n" - print() + # Handle multi-line input + if user_input == '"""': + user_input = "" + print('> """') + while True: + placeholder = HTML( + f'<{placeholder_color}>Use """ again to finish' + ) + line = self._prompt_session.prompt( + "", placeholder=placeholder + ).strip() + if line == '"""': + break + user_input += line + "\n" + print() message_count += 1 # Increment counter after each message @@ -860,7 +857,7 @@ def chat(self): self._spinner.stop() print(traceback.format_exc()) print("\n\n\033[91mAn error has occurred.\033[0m") - if sys.stdin.isatty(): # Only prompt if in interactive mode + if self.interactive: print( "\nOpen Interpreter is self-healing. If you report this error, it will be autonomously repaired." ) diff --git a/interpreter_1/misc/help.py b/interpreter_1/misc/help.py index 3a82c3751..82cca6613 100644 --- a/interpreter_1/misc/help.py +++ b/interpreter_1/misc/help.py @@ -1,12 +1,9 @@ import json -import random -import time from ..ui.tool import ToolRenderer -from .stream_text import stream_text -def help_message(u): +def help_message(): tips = [ "\033[38;5;240mTip: Pipe in prompts using `$ANYTHING | i`\033[0m", "\033[38;5;240mTip: Type `wtf` in your terminal to fix the last error\033[0m", @@ -39,10 +36,11 @@ def help_message(u): {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}--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 {BLUE_COLOR}--system-message{RESET_COLOR} Override default system message {BLUE_COLOR}--instructions{RESET_COLOR} Additional instructions in system message -{BLUE_COLOR}--max-budget{RESET_COLOR} Maximum spend allowed (-1 for unlimited) {BLUE_COLOR}--max-turns{RESET_COLOR} Maximum conversation turns (-1 for unlimited) {BLUE_COLOR}--profile{RESET_COLOR} Load settings from config file diff --git a/interpreter_1/profiles.py b/interpreter_1/profiles.py index 1ddd50024..30fa69c20 100644 --- a/interpreter_1/profiles.py +++ b/interpreter_1/profiles.py @@ -1,6 +1,7 @@ import json import os import platform +import sys from datetime import datetime # System prompt with dynamic values @@ -63,12 +64,12 @@ def __init__(self): self.messages = [] # List of conversation messages self.system_message = SYSTEM_PROMPT # System prompt override self.instructions = "" # Additional model instructions - self.input = None # Input message override # Available tools and settings self.tools = ["interpreter", "editor"] # Enabled tool modules self.auto_run = False # Whether to auto-run tools without confirmation self.tool_calling = True # Whether to allow tool/function calling + self.interactive = sys.stdin.isatty() # Whether to prompt for input # Server settings self.serve = False # Whether to start the server diff --git a/interpreter_1/tools/bash.py b/interpreter_1/tools/bash.py index 853636b6e..31c5ffb04 100644 --- a/interpreter_1/tools/bash.py +++ b/interpreter_1/tools/bash.py @@ -140,7 +140,9 @@ async def watch_for_ctrl_c(): if self._sentinel in full_output: # Remove sentinel and everything after it clean_output = full_output.split(self._sentinel)[0] - # print(clean_output, end="", flush=True) + # If output is empty or only whitespace, return a message + if not clean_output.strip(): + return CLIResult(output="") return CLIResult(output=clean_output) else: print(chunk_str, end="", flush=True) @@ -153,8 +155,11 @@ async def watch_for_ctrl_c(): else: output, error = await self._process.communicate() output_str = output.decode() - print(output_str, end="", flush=True) - return CLIResult(output=output_str + "\n" + error.decode()) + error_str = error.decode() + combined_output = output_str + "\n" + error_str + if not combined_output.strip(): + return CLIResult(output="") + return CLIResult(output=combined_output) except (KeyboardInterrupt, asyncio.CancelledError): self.stop()