-
Notifications
You must be signed in to change notification settings - Fork 70
Add Windows terminal backend support #1012
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
SmartManoj
wants to merge
36
commits into
OpenHands:main
Choose a base branch
from
SmartManoj:terminal
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
6789d81
Add Windows terminal backend support
SmartManoj a1f6319
ruff
SmartManoj 4e064b0
Remove platform check and always import fcntl and pty for pyright
SmartManoj baa383e
pyright
SmartManoj 4efe972
Merge branch 'main' into terminal
SmartManoj 7939e98
ruff
SmartManoj a7b35dd
Remove demo script
SmartManoj 0eb8eea
Merge branch 'main' into terminal
SmartManoj 4fefd40
Remove stray character from import statement
SmartManoj d252b38
Update assertions to use obs.text in Windows Terminal tests
SmartManoj a2123bb
Merge branch 'main' into terminal
SmartManoj 83f31c8
Add platform-specific terminal imports to __init__.py
SmartManoj ff46c49
Refactor terminal modules and update imports
SmartManoj d0ca912
Merge branch 'main' into terminal
SmartManoj 78791dd
Add Windows-specific terminal tool description
SmartManoj bd5e3b9
format
SmartManoj d0002c4
Merge branch 'main' into terminal
SmartManoj 69990f1
Add Windows tools test job to CI workflow
SmartManoj b89a96c
Merge branch 'main' into terminal
SmartManoj 486f534
Update tests to use obs.text instead of obs.output
SmartManoj 3b92e5a
Normalize path comparisons in Windows terminal tests
SmartManoj f24948b
Refactor path normalization in Windows terminal tests
SmartManoj e33e91c
Use realpath for path normalization in Windows terminal tests
SmartManoj fddad1c
Remove unnecessary parentheses in path normalization
SmartManoj cbcf45b
Add coverage configuration to pyproject.toml
SmartManoj 9fb0df0
fix integration tests
ryanhoangt 2101caf
lint
ryanhoangt 54a8749
add a few tests
ryanhoangt 3f2dc44
Remove coverage paths configuration from pyproject.toml
SmartManoj c28d605
Merge branch 'main' into terminal
SmartManoj c4869a6
Remove coverage report config from pyproject.toml
SmartManoj c40789b
Merge branch 'main' into terminal
SmartManoj 6c4821c
Load terminal tool descriptions from template files
SmartManoj b2416e0
Merge branch 'main' into terminal
SmartManoj 805630e
Rename terminal description templates to .j2 extension
SmartManoj 2626ec7
Merge branch 'main' into terminal
SmartManoj File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
openhands-tools/openhands/tools/terminal/templates/unix_description.j2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| Execute a bash command in the terminal within a persistent shell session. | ||
|
|
||
|
|
||
| ### Command Execution | ||
| * One command at a time: You can only execute one bash command at a time. If you need to run multiple commands sequentially, use `&&` or `;` to chain them together. | ||
| * Persistent session: Commands execute in a persistent shell session where environment variables, virtual environments, and working directory persist between commands. | ||
| * Soft timeout: Commands have a soft timeout of 10 seconds, once that's reached, you have the option to continue or interrupt the command (see section below for details) | ||
| * Shell options: Do NOT use `set -e`, `set -eu`, or `set -euo pipefail` in shell scripts or commands in this environment. The runtime may not support them and can cause unusable shell sessions. If you want to run multi-line bash commands, write the commands to a file and then run it, instead. | ||
|
|
||
| ### Long-running Commands | ||
| * For commands that may run indefinitely, run them in the background and redirect output to a file, e.g. `python3 app.py > server.log 2>&1 &`. | ||
| * For commands that may run for a long time (e.g. installation or testing commands), or commands that run for a fixed amount of time (e.g. sleep), you should set the "timeout" parameter of your function call to an appropriate value. | ||
| * If a bash command returns exit code `-1`, this means the process hit the soft timeout and is not yet finished. By setting `is_input` to `true`, you can: | ||
| - Send empty `command` to retrieve additional logs | ||
| - Send text (set `command` to the text) to STDIN of the running process | ||
| - Send control commands like `C-c` (Ctrl+C), `C-d` (Ctrl+D), or `C-z` (Ctrl+Z) to interrupt the process | ||
| - If you do C-c, you can re-start the process with a longer "timeout" parameter to let it run to completion | ||
|
|
||
| ### Best Practices | ||
| * Directory verification: Before creating new directories or files, first verify the parent directory exists and is the correct location. | ||
| * Directory management: Try to maintain working directory by using absolute paths and avoiding excessive use of `cd`. | ||
|
|
||
| ### Output Handling | ||
| * Output truncation: If the output exceeds a maximum length, it will be truncated before being returned. | ||
|
|
||
| ### Terminal Reset | ||
| * Terminal reset: If the terminal becomes unresponsive, you can set the "reset" parameter to `true` to create a new terminal session. This will terminate the current session and start fresh. | ||
| * Warning: Resetting the terminal will lose all previously set environment variables, working directory changes, and any running processes. Use this only when the terminal stops responding to commands. | ||
|
|
31 changes: 31 additions & 0 deletions
31
openhands-tools/openhands/tools/terminal/templates/windows_description.j2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| Execute a PowerShell command in the terminal within a persistent shell session. | ||
|
|
||
|
|
||
| ### Command Execution | ||
| * One command at a time: You can only execute one PowerShell command at a time. If you need to run multiple commands sequentially, use `;` to chain them together. | ||
| * Bash compatibility: Basic bash commands like `&&` and `||` are automatically converted to PowerShell `;` separator, though conditional execution semantics are not preserved. | ||
| * Persistent session: Commands execute in a persistent PowerShell session where environment variables, modules, and working directory persist between commands. | ||
| * Soft timeout: Commands have a soft timeout of 10 seconds, once that's reached, you have the option to continue or interrupt the command (see section below for details) | ||
| * PowerShell syntax: Use native PowerShell cmdlets (e.g., `Get-ChildItem`, `Set-Location`) or common aliases (e.g., `ls`, `cd`, `dir`) for best results. | ||
|
|
||
| ### Long-running Commands | ||
| * For commands that may run indefinitely, run them in the background using PowerShell jobs, e.g. `Start-Job -ScriptBlock { python app.py } | Out-File server.log`. | ||
| * For commands that may run for a long time (e.g. installation or testing commands), or commands that run for a fixed amount of time (e.g. Start-Sleep), you should set the "timeout" parameter of your function call to an appropriate value. | ||
| * If a command returns exit code `-1`, this means the process hit the soft timeout and is not yet finished. By setting `is_input` to `true`, you can: | ||
| - Send empty `command` to retrieve additional logs | ||
| - Send text (set `command` to the text) to STDIN of the running process | ||
| - Send control commands like `C-c` (Ctrl+C) to interrupt the process | ||
| - If you do C-c, you can re-start the process with a longer "timeout" parameter to let it run to completion | ||
|
|
||
| ### Best Practices | ||
| * Directory verification: Before creating new directories or files, first verify the parent directory exists and is the correct location (use `Test-Path`). | ||
| * Directory management: Try to maintain working directory by using absolute paths and avoiding excessive use of `cd` or `Set-Location`. | ||
| * Path separators: PowerShell handles both forward slashes `/` and backslashes `\\` in paths, but backslashes are native to Windows. | ||
|
|
||
| ### Output Handling | ||
| * Output truncation: If the output exceeds a maximum length, it will be truncated before being returned. | ||
|
|
||
| ### Terminal Reset | ||
| * Terminal reset: If the terminal becomes unresponsive, you can set the "reset" parameter to `true` to create a new PowerShell session. This will terminate the current session and start fresh. | ||
| * Warning: Resetting the terminal will lose all previously loaded modules, environment variables, working directory changes, and any running processes. Use this only when the terminal stops responding to commands. | ||
|
|
42 changes: 29 additions & 13 deletions
42
openhands-tools/openhands/tools/terminal/terminal/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,24 +1,40 @@ | ||
| import platform | ||
|
|
||
| from openhands.tools.terminal.terminal.factory import create_terminal_session | ||
| from openhands.tools.terminal.terminal.interface import ( | ||
| TerminalInterface, | ||
| TerminalSessionBase, | ||
| ) | ||
| from openhands.tools.terminal.terminal.subprocess_terminal import ( | ||
| SubprocessTerminal, | ||
| ) | ||
| from openhands.tools.terminal.terminal.terminal_session import ( | ||
| TerminalCommandStatus, | ||
| TerminalSession, | ||
| ) | ||
| from openhands.tools.terminal.terminal.tmux_terminal import TmuxTerminal | ||
|
|
||
|
|
||
| __all__ = [ | ||
| "TerminalInterface", | ||
| "TerminalSessionBase", | ||
| "TmuxTerminal", | ||
| "SubprocessTerminal", | ||
| "TerminalSession", | ||
| "TerminalCommandStatus", | ||
| "create_terminal_session", | ||
| ] | ||
| # Conditionally import platform-specific terminals | ||
| if platform.system() == "Windows": | ||
| from openhands.tools.terminal.terminal.windows_terminal import WindowsTerminal | ||
|
|
||
| __all__ = [ | ||
| "TerminalInterface", | ||
| "TerminalSessionBase", | ||
| "WindowsTerminal", | ||
| "TerminalSession", | ||
| "TerminalCommandStatus", | ||
| "create_terminal_session", | ||
| ] | ||
| else: | ||
| from openhands.tools.terminal.terminal.subprocess_terminal import ( | ||
| SubprocessTerminal, | ||
| ) | ||
| from openhands.tools.terminal.terminal.tmux_terminal import TmuxTerminal | ||
|
|
||
| __all__ = [ | ||
| "TerminalInterface", | ||
| "TerminalSessionBase", | ||
| "TmuxTerminal", | ||
| "SubprocessTerminal", | ||
| "TerminalSession", | ||
| "TerminalCommandStatus", | ||
| "create_terminal_session", | ||
| ] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason why we export things conditionally like this? I think it might break several test files like
tests/tools/terminal/test_session_factory.py.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
else, it will raise
ModuleNotFoundError: No module named 'fcntl'https://github.com/OpenHands/OpenHands/issues/11629