openhands-tools 1.56.0__tar.gz → 1.58.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/PKG-INFO +1 -1
  2. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/browser_use/impl.py +14 -4
  3. openhands_tools-1.58.0/openhands/tools/terminal/terminal/process_priority.py +39 -0
  4. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/terminal/subprocess_terminal.py +4 -1
  5. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/terminal/tmux_pane_pool.py +8 -3
  6. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/terminal/tmux_terminal.py +12 -5
  7. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/terminal/windows_terminal.py +10 -4
  8. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands_tools.egg-info/PKG-INFO +1 -1
  9. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands_tools.egg-info/SOURCES.txt +2 -0
  10. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/pyproject.toml +1 -1
  11. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/__init__.py +0 -0
  12. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/apply_patch/__init__.py +0 -0
  13. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/apply_patch/core.py +0 -0
  14. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/apply_patch/definition.py +0 -0
  15. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/ask_oracle/__init__.py +0 -0
  16. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/ask_oracle/definition.py +0 -0
  17. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/ask_oracle/impl.py +0 -0
  18. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/browser_use/__init__.py +0 -0
  19. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/browser_use/definition.py +0 -0
  20. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/browser_use/event_storage.py +0 -0
  21. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/browser_use/logging_fix.py +0 -0
  22. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/browser_use/recording.py +0 -0
  23. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/browser_use/server.py +0 -0
  24. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/child_conversation/__init__.py +0 -0
  25. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/child_conversation/definition.py +0 -0
  26. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/child_conversation/impl.py +0 -0
  27. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/delegate/__init__.py +0 -0
  28. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/delegate/definition.py +0 -0
  29. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/delegate/impl.py +0 -0
  30. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/delegate/visualizer.py +0 -0
  31. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/__init__.py +0 -0
  32. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/definition.py +0 -0
  33. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/editor.py +0 -0
  34. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/exceptions.py +0 -0
  35. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/impl.py +0 -0
  36. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/utils/__init__.py +0 -0
  37. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/utils/config.py +0 -0
  38. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/utils/constants.py +0 -0
  39. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/utils/diff.py +0 -0
  40. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/utils/encoding.py +0 -0
  41. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/utils/file_cache.py +0 -0
  42. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/utils/history.py +0 -0
  43. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/file_editor/utils/shell.py +0 -0
  44. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/__init__.py +0 -0
  45. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/edit/__init__.py +0 -0
  46. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/edit/definition.py +0 -0
  47. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/edit/impl.py +0 -0
  48. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/file_change.py +0 -0
  49. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/list_directory/__init__.py +0 -0
  50. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/list_directory/definition.py +0 -0
  51. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/list_directory/impl.py +0 -0
  52. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/read_file/__init__.py +0 -0
  53. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/read_file/definition.py +0 -0
  54. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/read_file/impl.py +0 -0
  55. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/write_file/__init__.py +0 -0
  56. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/write_file/definition.py +0 -0
  57. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/gemini/write_file/impl.py +0 -0
  58. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/glob/__init__.py +0 -0
  59. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/glob/definition.py +0 -0
  60. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/glob/impl.py +0 -0
  61. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/grep/__init__.py +0 -0
  62. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/grep/definition.py +0 -0
  63. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/grep/impl.py +0 -0
  64. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/planning_file_editor/__init__.py +0 -0
  65. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/planning_file_editor/definition.py +0 -0
  66. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/planning_file_editor/impl.py +0 -0
  67. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/preset/__init__.py +0 -0
  68. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/preset/default.py +0 -0
  69. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/preset/gemini.py +0 -0
  70. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/preset/gpt5.py +0 -0
  71. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/preset/planning.py +0 -0
  72. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/preset/subagents/bash_runner.md +0 -0
  73. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/preset/subagents/code_explorer.md +0 -0
  74. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/preset/subagents/default.md +0 -0
  75. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/preset/subagents/web_researcher.md +0 -0
  76. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/preset/task_outcome.py +0 -0
  77. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/py.typed +0 -0
  78. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/task/__init__.py +0 -0
  79. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/task/definition.py +0 -0
  80. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/task/impl.py +0 -0
  81. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/task/manager.py +0 -0
  82. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/task_tracker/__init__.py +0 -0
  83. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/task_tracker/definition.py +0 -0
  84. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/__init__.py +0 -0
  85. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/constants.py +0 -0
  86. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/definition.py +0 -0
  87. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/descriptions.py +0 -0
  88. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/env.py +0 -0
  89. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/impl.py +0 -0
  90. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/metadata.py +0 -0
  91. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/terminal/__init__.py +0 -0
  92. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/terminal/factory.py +0 -0
  93. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/terminal/interface.py +0 -0
  94. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/terminal/terminal_session.py +0 -0
  95. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/timeout_policy.py +0 -0
  96. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/utils/__init__.py +0 -0
  97. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/utils/command.py +0 -0
  98. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/terminal/utils/escape_filter.py +0 -0
  99. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/tom_consult/__init__.py +0 -0
  100. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/tom_consult/definition.py +0 -0
  101. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/tom_consult/executor.py +0 -0
  102. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/utils/__init__.py +0 -0
  103. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/utils/timeout.py +0 -0
  104. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/workflow/__init__.py +0 -0
  105. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/workflow/definition.py +0 -0
  106. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands/tools/workflow/impl.py +0 -0
  107. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands_tools.egg-info/dependency_links.txt +0 -0
  108. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands_tools.egg-info/requires.txt +0 -0
  109. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/openhands_tools.egg-info/top_level.txt +0 -0
  110. {openhands_tools-1.56.0 → openhands_tools-1.58.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openhands-tools
3
- Version: 1.56.0
3
+ Version: 1.58.0
4
4
  Summary: OpenHands Tools - Runtime tools for AI agents
5
5
  Project-URL: Source, https://github.com/OpenHands/software-agent-sdk
6
6
  Project-URL: Homepage, https://github.com/OpenHands/software-agent-sdk
@@ -147,15 +147,25 @@ def _standard_chromium_paths(platform: str | None = None) -> list[Path]:
147
147
 
148
148
 
149
149
  def _playwright_cache_dirs(platform: str | None = None) -> list[Path]:
150
+ # Playwright installs browsers into $PLAYWRIGHT_BROWSERS_PATH when set.
151
+ # "0" is its special value for browsers inside the installed package,
152
+ # which is not a directory path, so it is ignored here.
153
+ dirs: list[Path] = []
154
+ if (browsers_path := os.environ.get("PLAYWRIGHT_BROWSERS_PATH")) and (
155
+ browsers_path != "0"
156
+ ):
157
+ dirs.append(Path(browsers_path).expanduser())
150
158
  match _current_platform(platform):
151
159
  case "darwin":
152
- return [Path.home() / "Library" / "Caches" / "ms-playwright"]
160
+ dirs.append(Path.home() / "Library" / "Caches" / "ms-playwright")
153
161
  case "win32":
154
162
  if local_app_data := os.environ.get("LOCALAPPDATA"):
155
- return [Path(local_app_data) / "ms-playwright"]
156
- return [Path.home() / "AppData" / "Local" / "ms-playwright"]
163
+ dirs.append(Path(local_app_data) / "ms-playwright")
164
+ else:
165
+ dirs.append(Path.home() / "AppData" / "Local" / "ms-playwright")
157
166
  case _:
158
- return [Path.home() / ".cache" / "ms-playwright"]
167
+ dirs.append(Path.home() / ".cache" / "ms-playwright")
168
+ return dirs
159
169
 
160
170
 
161
171
  def _playwright_chromium_paths(
@@ -0,0 +1,39 @@
1
+ """Lower the CPU priority of agent terminals so they cannot starve the server."""
2
+
3
+ import os
4
+ import platform
5
+ import shutil
6
+ from collections.abc import Mapping
7
+ from typing import Final
8
+
9
+
10
+ TERMINAL_PROCESS_PRIORITY_ENV: Final[str] = "OH_TERMINAL_PROCESS_PRIORITY"
11
+
12
+ # macOS largely ignores nice; the utility QoS clamp is what keeps the server
13
+ # responsive. Avoid the background clamp: it also throttles I/O heavily.
14
+ _TASKPOLICY_PATH: Final[str] = "/usr/sbin/taskpolicy"
15
+ _LINUX_NICE_INCREMENT: Final[str] = "10"
16
+
17
+
18
+ def should_lower_process_priority(env: Mapping[str, str]) -> bool:
19
+ """Return False when the terminal env opts out with ``none``."""
20
+ value = env.get(TERMINAL_PROCESS_PRIORITY_ENV, "")
21
+ return value.strip().lower() != "none"
22
+
23
+
24
+ def process_priority_prefix(env: Mapping[str, str]) -> list[str]:
25
+ """Return an argv prefix that runs the shell at lower CPU priority.
26
+
27
+ This must be an argv prefix rather than a ``preexec_fn``: a macOS QoS class
28
+ set on the calling thread does not survive ``exec``. Both ``taskpolicy``
29
+ and ``nice`` are inherited by every process the shell starts.
30
+ """
31
+ if not should_lower_process_priority(env):
32
+ return []
33
+
34
+ system = platform.system()
35
+ if system == "Darwin" and os.path.exists(_TASKPOLICY_PATH):
36
+ return [_TASKPOLICY_PATH, "-c", "utility"]
37
+ if system == "Linux" and (nice_path := shutil.which("nice")) is not None:
38
+ return [nice_path, "-n", _LINUX_NICE_INCREMENT]
39
+ return []
@@ -35,6 +35,9 @@ from openhands.tools.terminal.env import (
35
35
  from openhands.tools.terminal.metadata import CmdOutputMetadata
36
36
  from openhands.tools.terminal.terminal import TerminalInterface
37
37
  from openhands.tools.terminal.terminal.interface import parse_ctrl_key
38
+ from openhands.tools.terminal.terminal.process_priority import (
39
+ process_priority_prefix,
40
+ )
38
41
 
39
42
 
40
43
  logger = get_logger(__name__)
@@ -151,7 +154,7 @@ class SubprocessTerminal(TerminalInterface):
151
154
  env["PS2"] = ""
152
155
  env["TERM"] = "xterm-256color"
153
156
 
154
- bash_cmd = [resolved_shell_path, "-i"]
157
+ bash_cmd = [*process_priority_prefix(env), resolved_shell_path, "-i"]
155
158
 
156
159
  # Create a PTY; give the slave to the child, keep the master
157
160
  master_fd, slave_fd = pty.openpty()
@@ -6,6 +6,7 @@ tmux session, enabling concurrent command execution across panes.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
+ import shlex
9
10
  import threading
10
11
  import time
11
12
  import uuid
@@ -27,6 +28,9 @@ from openhands.tools.terminal.env import (
27
28
  build_terminal_env,
28
29
  normalize_terminal_env,
29
30
  )
31
+ from openhands.tools.terminal.terminal.process_priority import (
32
+ process_priority_prefix,
33
+ )
30
34
  from openhands.tools.terminal.terminal.tmux_terminal import (
31
35
  TmuxTerminal,
32
36
  _new_owned_session,
@@ -169,13 +173,14 @@ class TmuxPanePool:
169
173
  """Create a new PooledTmuxTerminal within the shared session."""
170
174
  assert self._session is not None
171
175
 
172
- shell_command = "/bin/bash"
176
+ shell_command = ["/bin/bash"]
173
177
  if self.username in ["root", "openhands"]:
174
- shell_command = f"su {self.username} -"
178
+ shell_command = ["su", self.username, "-"]
179
+ priority_prefix = process_priority_prefix(build_terminal_env(self.env))
175
180
 
176
181
  window = self._session.new_window(
177
182
  window_name=f"pane-{len(self._all_panes)}",
178
- window_shell=shell_command,
183
+ window_shell=shlex.join([*priority_prefix, *shell_command]),
179
184
  start_directory=self.work_dir,
180
185
  )
181
186
  active_pane = window.active_pane
@@ -2,6 +2,7 @@
2
2
 
3
3
  import logging
4
4
  import os
5
+ import shlex
5
6
  import sys
6
7
  import time
7
8
  import uuid
@@ -29,6 +30,9 @@ from openhands.tools.terminal.env import (
29
30
  from openhands.tools.terminal.metadata import CmdOutputMetadata
30
31
  from openhands.tools.terminal.terminal import TerminalInterface
31
32
  from openhands.tools.terminal.terminal.interface import parse_ctrl_key
33
+ from openhands.tools.terminal.terminal.process_priority import (
34
+ process_priority_prefix,
35
+ )
32
36
 
33
37
 
34
38
  logger = get_logger(__name__)
@@ -145,7 +149,6 @@ def _new_owned_session(
145
149
  server = libtmux.Server(
146
150
  socket_name=None if fallback else socket_name,
147
151
  socket_path=str(socket_dir / socket_name) if fallback else None,
148
- environment=dict(env),
149
152
  )
150
153
  session = server.new_session(
151
154
  session_name=session_name,
@@ -155,7 +158,11 @@ def _new_owned_session(
155
158
  y=y,
156
159
  )
157
160
  mark_socket_owner(server)
158
- return server, session
161
+ # A tmux server starts with this process's environment rather than *env*,
162
+ # and new windows inherit it, so unset what sanitization removed.
163
+ for key in os.environ.keys() - env.keys():
164
+ server.unset_environment(key)
165
+ return server, session
159
166
 
160
167
 
161
168
  # Map normalized special key names to tmux key names.
@@ -212,12 +219,12 @@ class TmuxTerminal(TerminalInterface):
212
219
  # auto-launch `less` on a TTY don't capture the pane and wedge the session.
213
220
  env.setdefault("GIT_PAGER", "cat")
214
221
  env.setdefault("PAGER", "cat")
215
- _shell_command = "/bin/bash"
222
+ shell_command = ["/bin/bash"]
216
223
  if self.username in ["root", "openhands"]:
217
224
  # This starts a non-login (new) shell for the given user
218
- _shell_command = f"su {self.username} -"
225
+ shell_command = ["su", self.username, "-"]
219
226
 
220
- window_command = _shell_command
227
+ window_command = shlex.join([*process_priority_prefix(env), *shell_command])
221
228
 
222
229
  logger.debug(f"Initializing tmux terminal with command: {window_command}")
223
230
  # Never reuse a socket: tmux numeric IDs restart at zero after server exit.
@@ -26,6 +26,9 @@ from openhands.tools.terminal.terminal.interface import (
26
26
  TerminalInterface,
27
27
  parse_ctrl_key,
28
28
  )
29
+ from openhands.tools.terminal.terminal.process_priority import (
30
+ should_lower_process_priority,
31
+ )
29
32
 
30
33
 
31
34
  logger = get_logger(__name__)
@@ -92,6 +95,10 @@ class WindowsTerminal(TerminalInterface):
92
95
  if self._initialized:
93
96
  return
94
97
 
98
+ env = build_terminal_env(self._env)
99
+ env.setdefault("PYTHONIOENCODING", "utf-8")
100
+ env.setdefault("PYTHONUTF8", "1")
101
+
95
102
  startupinfo = None
96
103
  creationflags = 0
97
104
  if platform.system() == "Windows":
@@ -101,10 +108,9 @@ class WindowsTerminal(TerminalInterface):
101
108
  startupinfo.dwFlags |= getattr(subprocess, "STARTF_USESHOWWINDOW", 0)
102
109
  creationflags = getattr(subprocess, "CREATE_NEW_PROCESS_GROUP", 0)
103
110
  creationflags |= getattr(subprocess, "CREATE_NO_WINDOW", 0)
104
-
105
- env = build_terminal_env(self._env)
106
- env.setdefault("PYTHONIOENCODING", "utf-8")
107
- env.setdefault("PYTHONUTF8", "1")
111
+ # Not PROCESS_MODE_BACKGROUND_BEGIN: it also throttles disk I/O.
112
+ if should_lower_process_priority(env):
113
+ creationflags |= getattr(subprocess, "BELOW_NORMAL_PRIORITY_CLASS", 0)
108
114
 
109
115
  self.process = subprocess.Popen(
110
116
  [self.shell_path, "-NoLogo", "-NoProfile"],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openhands-tools
3
- Version: 1.56.0
3
+ Version: 1.58.0
4
4
  Summary: OpenHands Tools - Runtime tools for AI agents
5
5
  Project-URL: Source, https://github.com/OpenHands/software-agent-sdk
6
6
  Project-URL: Homepage, https://github.com/OpenHands/software-agent-sdk
@@ -84,6 +84,7 @@ pyproject.toml
84
84
  ./openhands/tools/terminal/terminal/__init__.py
85
85
  ./openhands/tools/terminal/terminal/factory.py
86
86
  ./openhands/tools/terminal/terminal/interface.py
87
+ ./openhands/tools/terminal/terminal/process_priority.py
87
88
  ./openhands/tools/terminal/terminal/subprocess_terminal.py
88
89
  ./openhands/tools/terminal/terminal/terminal_session.py
89
90
  ./openhands/tools/terminal/terminal/tmux_pane_pool.py
@@ -185,6 +186,7 @@ openhands/tools/terminal/timeout_policy.py
185
186
  openhands/tools/terminal/terminal/__init__.py
186
187
  openhands/tools/terminal/terminal/factory.py
187
188
  openhands/tools/terminal/terminal/interface.py
189
+ openhands/tools/terminal/terminal/process_priority.py
188
190
  openhands/tools/terminal/terminal/subprocess_terminal.py
189
191
  openhands/tools/terminal/terminal/terminal_session.py
190
192
  openhands/tools/terminal/terminal/tmux_pane_pool.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "openhands-tools"
3
- version = "1.56.0"
3
+ version = "1.58.0"
4
4
  description = "OpenHands Tools - Runtime tools for AI agents"
5
5
 
6
6
  requires-python = ">=3.12"