diff --git a/openhands/runtime/utils/bash.py b/openhands/runtime/utils/bash.py index 34b2222b5bf9..ec1d2cbfc395 100644 --- a/openhands/runtime/utils/bash.py +++ b/openhands/runtime/utils/bash.py @@ -18,6 +18,10 @@ class BashCommandStatus(Enum): HARD_TIMEOUT = 'hard_timeout' +def _remove_command_prefix(command_output: str, command: str) -> str: + return command_output.lstrip().removeprefix(command.lstrip()).lstrip() + + class BashSession: NO_CHANGE_TIMEOUT_SECONDS = 10.0 POLL_INTERVAL = 0.5 @@ -108,6 +112,7 @@ def _handle_nochange_timeout_command(self, command: str) -> CmdOutputObservation assert len(ps1_matches) == 1, 'Expected exactly one PS1 metadata block' command_output = full_output[ps1_matches[0].end() + 1 :] + command_output = _remove_command_prefix(command_output, command) # remove the previous command output from the new output if any if self.prev_output: _clean_command_output = command_output.removeprefix(self.prev_output) @@ -118,7 +123,7 @@ def _handle_nochange_timeout_command(self, command: str) -> CmdOutputObservation self.prev_output = _clean_command_output command_output += ( - f'\n[The command has no new output after {self.NO_CHANGE_TIMEOUT_SECONDS} seconds. ' + f'\n\n[The command has no new output after {self.NO_CHANGE_TIMEOUT_SECONDS} seconds. ' "You may wait longer to see additional output by sending empty command '', " 'send other commands to interact with the current process, ' 'or send keys to interrupt/kill the command.]' @@ -146,9 +151,9 @@ def _handle_hard_timeout_command( ) self.prev_output = _clean_command_output - command_output = command_output.lstrip().removeprefix(command.lstrip()).lstrip() + command_output = _remove_command_prefix(command_output, command) command_output += ( - f'\n[The command timed out after {timeout} seconds. ' + f'\n\n[The command timed out after {timeout} seconds. ' "You may wait longer to see additional output by sending empty command '', " 'send other commands to interact with the current process, ' 'or send keys to interrupt/kill the command.]' @@ -200,14 +205,6 @@ def execute(self, action: CmdRunAction) -> CmdOutputObservation: if action.command.strip() == '': return self._handle_empty_command() - # Clear screen before executing new command - if self.prev_status not in { - BashCommandStatus.NO_CHANGE_TIMEOUT, - BashCommandStatus.HARD_TIMEOUT, - BashCommandStatus.CONTINUE, - }: - self._clear_screen() - start_time = time.time() last_change_time = start_time last_pane_output = self._get_pane_content()