openhands 0.0.0__py3-none-any.whl → 1.0.1__py3-none-any.whl
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.
Potentially problematic release.
This version of openhands might be problematic. Click here for more details.
- openhands-1.0.1.dist-info/METADATA +52 -0
- openhands-1.0.1.dist-info/RECORD +31 -0
- {openhands-0.0.0.dist-info → openhands-1.0.1.dist-info}/WHEEL +1 -2
- openhands-1.0.1.dist-info/entry_points.txt +2 -0
- openhands_cli/__init__.py +8 -0
- openhands_cli/agent_chat.py +186 -0
- openhands_cli/argparsers/main_parser.py +56 -0
- openhands_cli/argparsers/serve_parser.py +31 -0
- openhands_cli/gui_launcher.py +220 -0
- openhands_cli/listeners/__init__.py +4 -0
- openhands_cli/listeners/loading_listener.py +63 -0
- openhands_cli/listeners/pause_listener.py +83 -0
- openhands_cli/llm_utils.py +57 -0
- openhands_cli/locations.py +13 -0
- openhands_cli/pt_style.py +30 -0
- openhands_cli/runner.py +178 -0
- openhands_cli/setup.py +116 -0
- openhands_cli/simple_main.py +59 -0
- openhands_cli/tui/__init__.py +5 -0
- openhands_cli/tui/settings/mcp_screen.py +217 -0
- openhands_cli/tui/settings/settings_screen.py +202 -0
- openhands_cli/tui/settings/store.py +93 -0
- openhands_cli/tui/status.py +109 -0
- openhands_cli/tui/tui.py +100 -0
- openhands_cli/tui/utils.py +14 -0
- openhands_cli/user_actions/__init__.py +17 -0
- openhands_cli/user_actions/agent_action.py +95 -0
- openhands_cli/user_actions/exit_session.py +18 -0
- openhands_cli/user_actions/settings_action.py +171 -0
- openhands_cli/user_actions/types.py +18 -0
- openhands_cli/user_actions/utils.py +199 -0
- openhands/__init__.py +0 -1
- openhands/sdk/__init__.py +0 -45
- openhands/sdk/agent/__init__.py +0 -8
- openhands/sdk/agent/agent/__init__.py +0 -6
- openhands/sdk/agent/agent/agent.py +0 -349
- openhands/sdk/agent/base.py +0 -103
- openhands/sdk/context/__init__.py +0 -28
- openhands/sdk/context/agent_context.py +0 -153
- openhands/sdk/context/condenser/__init__.py +0 -5
- openhands/sdk/context/condenser/condenser.py +0 -73
- openhands/sdk/context/condenser/no_op_condenser.py +0 -13
- openhands/sdk/context/manager.py +0 -5
- openhands/sdk/context/microagents/__init__.py +0 -26
- openhands/sdk/context/microagents/exceptions.py +0 -11
- openhands/sdk/context/microagents/microagent.py +0 -345
- openhands/sdk/context/microagents/types.py +0 -70
- openhands/sdk/context/utils/__init__.py +0 -8
- openhands/sdk/context/utils/prompt.py +0 -52
- openhands/sdk/context/view.py +0 -116
- openhands/sdk/conversation/__init__.py +0 -12
- openhands/sdk/conversation/conversation.py +0 -207
- openhands/sdk/conversation/state.py +0 -50
- openhands/sdk/conversation/types.py +0 -6
- openhands/sdk/conversation/visualizer.py +0 -300
- openhands/sdk/event/__init__.py +0 -27
- openhands/sdk/event/base.py +0 -148
- openhands/sdk/event/condenser.py +0 -49
- openhands/sdk/event/llm_convertible.py +0 -265
- openhands/sdk/event/types.py +0 -5
- openhands/sdk/event/user_action.py +0 -12
- openhands/sdk/event/utils.py +0 -30
- openhands/sdk/llm/__init__.py +0 -19
- openhands/sdk/llm/exceptions.py +0 -108
- openhands/sdk/llm/llm.py +0 -867
- openhands/sdk/llm/llm_registry.py +0 -116
- openhands/sdk/llm/message.py +0 -216
- openhands/sdk/llm/metadata.py +0 -34
- openhands/sdk/llm/utils/fn_call_converter.py +0 -1049
- openhands/sdk/llm/utils/metrics.py +0 -311
- openhands/sdk/llm/utils/model_features.py +0 -153
- openhands/sdk/llm/utils/retry_mixin.py +0 -122
- openhands/sdk/llm/utils/telemetry.py +0 -252
- openhands/sdk/logger.py +0 -167
- openhands/sdk/mcp/__init__.py +0 -20
- openhands/sdk/mcp/client.py +0 -113
- openhands/sdk/mcp/definition.py +0 -69
- openhands/sdk/mcp/tool.py +0 -104
- openhands/sdk/mcp/utils.py +0 -59
- openhands/sdk/tests/llm/test_llm.py +0 -447
- openhands/sdk/tests/llm/test_llm_fncall_converter.py +0 -691
- openhands/sdk/tests/llm/test_model_features.py +0 -221
- openhands/sdk/tool/__init__.py +0 -30
- openhands/sdk/tool/builtins/__init__.py +0 -34
- openhands/sdk/tool/builtins/finish.py +0 -57
- openhands/sdk/tool/builtins/think.py +0 -60
- openhands/sdk/tool/schema.py +0 -236
- openhands/sdk/tool/security_prompt.py +0 -5
- openhands/sdk/tool/tool.py +0 -142
- openhands/sdk/utils/__init__.py +0 -14
- openhands/sdk/utils/discriminated_union.py +0 -210
- openhands/sdk/utils/json.py +0 -48
- openhands/sdk/utils/truncate.py +0 -44
- openhands/tools/__init__.py +0 -44
- openhands/tools/execute_bash/__init__.py +0 -30
- openhands/tools/execute_bash/constants.py +0 -31
- openhands/tools/execute_bash/definition.py +0 -166
- openhands/tools/execute_bash/impl.py +0 -38
- openhands/tools/execute_bash/metadata.py +0 -101
- openhands/tools/execute_bash/terminal/__init__.py +0 -22
- openhands/tools/execute_bash/terminal/factory.py +0 -113
- openhands/tools/execute_bash/terminal/interface.py +0 -189
- openhands/tools/execute_bash/terminal/subprocess_terminal.py +0 -412
- openhands/tools/execute_bash/terminal/terminal_session.py +0 -492
- openhands/tools/execute_bash/terminal/tmux_terminal.py +0 -160
- openhands/tools/execute_bash/utils/command.py +0 -150
- openhands/tools/str_replace_editor/__init__.py +0 -17
- openhands/tools/str_replace_editor/definition.py +0 -158
- openhands/tools/str_replace_editor/editor.py +0 -683
- openhands/tools/str_replace_editor/exceptions.py +0 -41
- openhands/tools/str_replace_editor/impl.py +0 -66
- openhands/tools/str_replace_editor/utils/__init__.py +0 -0
- openhands/tools/str_replace_editor/utils/config.py +0 -2
- openhands/tools/str_replace_editor/utils/constants.py +0 -9
- openhands/tools/str_replace_editor/utils/encoding.py +0 -135
- openhands/tools/str_replace_editor/utils/file_cache.py +0 -154
- openhands/tools/str_replace_editor/utils/history.py +0 -122
- openhands/tools/str_replace_editor/utils/shell.py +0 -72
- openhands/tools/task_tracker/__init__.py +0 -16
- openhands/tools/task_tracker/definition.py +0 -336
- openhands/tools/utils/__init__.py +0 -1
- openhands-0.0.0.dist-info/METADATA +0 -3
- openhands-0.0.0.dist-info/RECORD +0 -94
- openhands-0.0.0.dist-info/top_level.txt +0 -1
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
import traceback
|
|
3
|
-
from typing import Any
|
|
4
|
-
|
|
5
|
-
import bashlex
|
|
6
|
-
from bashlex.errors import ParsingError
|
|
7
|
-
|
|
8
|
-
from openhands.sdk.logger import get_logger
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
logger = get_logger(__name__)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def split_bash_commands(commands: str) -> list[str]:
|
|
15
|
-
if not commands.strip():
|
|
16
|
-
return [""]
|
|
17
|
-
try:
|
|
18
|
-
parsed = bashlex.parse(commands)
|
|
19
|
-
except (
|
|
20
|
-
ParsingError,
|
|
21
|
-
NotImplementedError,
|
|
22
|
-
TypeError,
|
|
23
|
-
AttributeError,
|
|
24
|
-
):
|
|
25
|
-
# Added AttributeError to catch 'str' object has no attribute 'kind' error
|
|
26
|
-
# (issue #8369)
|
|
27
|
-
logger.debug(
|
|
28
|
-
f"Failed to parse bash commands\n[input]: {commands}\n[warning]: "
|
|
29
|
-
f"{traceback.format_exc()}\nThe original command will be returned as is."
|
|
30
|
-
)
|
|
31
|
-
# If parsing fails, return the original commands
|
|
32
|
-
return [commands]
|
|
33
|
-
|
|
34
|
-
result: list[str] = []
|
|
35
|
-
last_end = 0
|
|
36
|
-
|
|
37
|
-
for node in parsed:
|
|
38
|
-
start, end = node.pos
|
|
39
|
-
|
|
40
|
-
# Include any text between the last command and this one
|
|
41
|
-
if start > last_end:
|
|
42
|
-
between = commands[last_end:start]
|
|
43
|
-
logger.debug(f"BASH PARSING between: {between}")
|
|
44
|
-
if result:
|
|
45
|
-
result[-1] += between.rstrip()
|
|
46
|
-
elif between.strip():
|
|
47
|
-
# THIS SHOULD NOT HAPPEN
|
|
48
|
-
result.append(between.rstrip())
|
|
49
|
-
|
|
50
|
-
# Extract the command, preserving original formatting
|
|
51
|
-
command = commands[start:end].rstrip()
|
|
52
|
-
logger.debug(f"BASH PARSING command: {command}")
|
|
53
|
-
result.append(command)
|
|
54
|
-
|
|
55
|
-
last_end = end
|
|
56
|
-
|
|
57
|
-
# Add any remaining text after the last command to the last command
|
|
58
|
-
remaining = commands[last_end:].rstrip()
|
|
59
|
-
logger.debug(f"BASH PARSING remaining: {remaining}")
|
|
60
|
-
if last_end < len(commands) and result:
|
|
61
|
-
result[-1] += remaining
|
|
62
|
-
logger.debug(f"BASH PARSING result[-1] += remaining: {result[-1]}")
|
|
63
|
-
elif last_end < len(commands):
|
|
64
|
-
if remaining:
|
|
65
|
-
result.append(remaining)
|
|
66
|
-
logger.debug(f"BASH PARSING result.append(remaining): {result[-1]}")
|
|
67
|
-
return result
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def escape_bash_special_chars(command: str) -> str:
|
|
71
|
-
r"""Escapes characters that have different interpretations in bash vs python.
|
|
72
|
-
Specifically handles escape sequences like \;, \|, \&, etc.
|
|
73
|
-
"""
|
|
74
|
-
if command.strip() == "":
|
|
75
|
-
return ""
|
|
76
|
-
|
|
77
|
-
try:
|
|
78
|
-
parts = []
|
|
79
|
-
last_pos = 0
|
|
80
|
-
|
|
81
|
-
def visit_node(node: Any) -> None:
|
|
82
|
-
nonlocal last_pos
|
|
83
|
-
if (
|
|
84
|
-
node.kind == "redirect"
|
|
85
|
-
and hasattr(node, "heredoc")
|
|
86
|
-
and node.heredoc is not None
|
|
87
|
-
):
|
|
88
|
-
# We're entering a heredoc - preserve everything as-is until we see EOF
|
|
89
|
-
# Store the heredoc end marker (usually 'EOF' but could be different)
|
|
90
|
-
between = command[last_pos : node.pos[0]]
|
|
91
|
-
parts.append(between)
|
|
92
|
-
# Add the heredoc start marker
|
|
93
|
-
parts.append(command[node.pos[0] : node.heredoc.pos[0]])
|
|
94
|
-
# Add the heredoc content as-is
|
|
95
|
-
parts.append(command[node.heredoc.pos[0] : node.heredoc.pos[1]])
|
|
96
|
-
last_pos = node.pos[1]
|
|
97
|
-
return
|
|
98
|
-
|
|
99
|
-
if node.kind == "word":
|
|
100
|
-
# Get the raw text between the last position and current word
|
|
101
|
-
between = command[last_pos : node.pos[0]]
|
|
102
|
-
word_text = command[node.pos[0] : node.pos[1]]
|
|
103
|
-
|
|
104
|
-
# Add the between text, escaping special characters
|
|
105
|
-
between = re.sub(r"\\([;&|><])", r"\\\\\1", between)
|
|
106
|
-
parts.append(between)
|
|
107
|
-
|
|
108
|
-
# Check if word_text is a quoted string or command substitution
|
|
109
|
-
if (
|
|
110
|
-
(word_text.startswith('"') and word_text.endswith('"'))
|
|
111
|
-
or (word_text.startswith("'") and word_text.endswith("'"))
|
|
112
|
-
or (word_text.startswith("$(") and word_text.endswith(")"))
|
|
113
|
-
or (word_text.startswith("`") and word_text.endswith("`"))
|
|
114
|
-
):
|
|
115
|
-
# Preserve quoted strings, command substitutions, and heredoc
|
|
116
|
-
# content as-is
|
|
117
|
-
parts.append(word_text)
|
|
118
|
-
else:
|
|
119
|
-
# Escape special chars in unquoted text
|
|
120
|
-
word_text = re.sub(r"\\([;&|><])", r"\\\\\1", word_text)
|
|
121
|
-
parts.append(word_text)
|
|
122
|
-
|
|
123
|
-
last_pos = node.pos[1]
|
|
124
|
-
return
|
|
125
|
-
|
|
126
|
-
# Visit child nodes
|
|
127
|
-
if hasattr(node, "parts"):
|
|
128
|
-
for part in node.parts:
|
|
129
|
-
visit_node(part)
|
|
130
|
-
|
|
131
|
-
# Process all nodes in the AST
|
|
132
|
-
nodes = list(bashlex.parse(command))
|
|
133
|
-
for node in nodes:
|
|
134
|
-
between = command[last_pos : node.pos[0]]
|
|
135
|
-
between = re.sub(r"\\([;&|><])", r"\\\\\1", between)
|
|
136
|
-
parts.append(between)
|
|
137
|
-
last_pos = node.pos[0]
|
|
138
|
-
visit_node(node)
|
|
139
|
-
|
|
140
|
-
# Handle any remaining text after the last word
|
|
141
|
-
remaining = command[last_pos:]
|
|
142
|
-
parts.append(remaining)
|
|
143
|
-
return "".join(parts)
|
|
144
|
-
except (ParsingError, NotImplementedError, TypeError):
|
|
145
|
-
logger.debug(
|
|
146
|
-
f"Failed to parse bash commands for special characters escape\n[input]: "
|
|
147
|
-
f"{command}\n[warning]: {traceback.format_exc()}\nThe original command "
|
|
148
|
-
f"will be returned as is."
|
|
149
|
-
)
|
|
150
|
-
return command
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
from openhands.tools.str_replace_editor.definition import (
|
|
2
|
-
FileEditorTool,
|
|
3
|
-
StrReplaceEditorAction,
|
|
4
|
-
StrReplaceEditorObservation,
|
|
5
|
-
str_replace_editor_tool,
|
|
6
|
-
)
|
|
7
|
-
from openhands.tools.str_replace_editor.impl import FileEditorExecutor, file_editor
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
__all__ = [
|
|
11
|
-
"str_replace_editor_tool",
|
|
12
|
-
"StrReplaceEditorAction",
|
|
13
|
-
"StrReplaceEditorObservation",
|
|
14
|
-
"file_editor",
|
|
15
|
-
"FileEditorExecutor",
|
|
16
|
-
"FileEditorTool",
|
|
17
|
-
]
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
"""String replace editor tool implementation."""
|
|
2
|
-
|
|
3
|
-
from typing import Literal
|
|
4
|
-
|
|
5
|
-
from pydantic import Field
|
|
6
|
-
|
|
7
|
-
from openhands.sdk.llm import ImageContent, TextContent
|
|
8
|
-
from openhands.sdk.tool import ActionBase, ObservationBase, Tool, ToolAnnotations
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
CommandLiteral = Literal["view", "create", "str_replace", "insert", "undo_edit"]
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class StrReplaceEditorAction(ActionBase):
|
|
15
|
-
"""Schema for string replace editor operations."""
|
|
16
|
-
|
|
17
|
-
command: CommandLiteral = Field(
|
|
18
|
-
description="The commands to run. Allowed options are: `view`, `create`, "
|
|
19
|
-
"`str_replace`, `insert`, `undo_edit`."
|
|
20
|
-
)
|
|
21
|
-
path: str = Field(
|
|
22
|
-
description="Absolute path to file or directory, e.g. `/workspace/file.py` "
|
|
23
|
-
"or `/workspace`."
|
|
24
|
-
)
|
|
25
|
-
file_text: str | None = Field(
|
|
26
|
-
default=None,
|
|
27
|
-
description="Required parameter of `create` command, with the content of "
|
|
28
|
-
"the file to be created.",
|
|
29
|
-
)
|
|
30
|
-
old_str: str | None = Field(
|
|
31
|
-
default=None,
|
|
32
|
-
description="Required parameter of `str_replace` command containing the "
|
|
33
|
-
"string in `path` to replace.",
|
|
34
|
-
)
|
|
35
|
-
new_str: str | None = Field(
|
|
36
|
-
default=None,
|
|
37
|
-
description="Optional parameter of `str_replace` command containing the "
|
|
38
|
-
"new string (if not given, no string will be added). Required parameter "
|
|
39
|
-
"of `insert` command containing the string to insert.",
|
|
40
|
-
)
|
|
41
|
-
insert_line: int | None = Field(
|
|
42
|
-
default=None,
|
|
43
|
-
description="Required parameter of `insert` command. The `new_str` will "
|
|
44
|
-
"be inserted AFTER the line `insert_line` of `path`.",
|
|
45
|
-
)
|
|
46
|
-
view_range: list[int] | None = Field(
|
|
47
|
-
default=None,
|
|
48
|
-
description="Optional parameter of `view` command when `path` points to a "
|
|
49
|
-
"file. If none is given, the full file is shown. If provided, the file "
|
|
50
|
-
"will be shown in the indicated line number range, e.g. [11, 12] will "
|
|
51
|
-
"show lines 11 and 12. Indexing at 1 to start. Setting `[start_line, "
|
|
52
|
-
"-1]` shows all lines from `start_line` to the end of the file.",
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class StrReplaceEditorObservation(ObservationBase):
|
|
57
|
-
"""A ToolResult that can be rendered as a CLI output."""
|
|
58
|
-
|
|
59
|
-
output: str = Field(
|
|
60
|
-
default="", description="The output message from the tool for the LLM to see."
|
|
61
|
-
)
|
|
62
|
-
path: str | None = Field(default=None, description="The file path that was edited.")
|
|
63
|
-
prev_exist: bool = Field(
|
|
64
|
-
default=True,
|
|
65
|
-
description="Indicates if the file previously existed. If not, it was created.",
|
|
66
|
-
)
|
|
67
|
-
old_content: str | None = Field(
|
|
68
|
-
default=None, description="The content of the file before the edit."
|
|
69
|
-
)
|
|
70
|
-
new_content: str | None = Field(
|
|
71
|
-
default=None, description="The content of the file after the edit."
|
|
72
|
-
)
|
|
73
|
-
error: str | None = Field(default=None, description="Error message if any.")
|
|
74
|
-
|
|
75
|
-
@property
|
|
76
|
-
def agent_observation(self) -> list[TextContent | ImageContent]:
|
|
77
|
-
if self.error:
|
|
78
|
-
return [TextContent(text=self.error)]
|
|
79
|
-
return [TextContent(text=self.output)]
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
Command = Literal[
|
|
83
|
-
"view",
|
|
84
|
-
"create",
|
|
85
|
-
"str_replace",
|
|
86
|
-
"insert",
|
|
87
|
-
"undo_edit",
|
|
88
|
-
]
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
TOOL_DESCRIPTION = """Custom editing tool for viewing, creating and editing files in plain-text format
|
|
92
|
-
* State is persistent across command calls and discussions with the user
|
|
93
|
-
* If `path` is a text file, `view` displays the result of applying `cat -n`. If `path` is a directory, `view` lists non-hidden files and directories up to 2 levels deep
|
|
94
|
-
* The following binary file extensions can be viewed in Markdown format: [".xlsx", ".pptx", ".wav", ".mp3", ".m4a", ".flac", ".pdf", ".docx"]. IT DOES NOT HANDLE IMAGES.
|
|
95
|
-
* The `create` command cannot be used if the specified `path` already exists as a file
|
|
96
|
-
* If a `command` generates a long output, it will be truncated and marked with `<response clipped>`
|
|
97
|
-
* The `undo_edit` command will revert the last edit made to the file at `path`
|
|
98
|
-
* This tool can be used for creating and editing files in plain-text format.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
Before using this tool:
|
|
102
|
-
1. Use the view tool to understand the file's contents and context
|
|
103
|
-
2. Verify the directory path is correct (only applicable when creating new files):
|
|
104
|
-
- Use the view tool to verify the parent directory exists and is the correct location
|
|
105
|
-
|
|
106
|
-
When making edits:
|
|
107
|
-
- Ensure the edit results in idiomatic, correct code
|
|
108
|
-
- Do not leave the code in a broken state
|
|
109
|
-
- Always use absolute file paths (starting with /)
|
|
110
|
-
|
|
111
|
-
CRITICAL REQUIREMENTS FOR USING THIS TOOL:
|
|
112
|
-
|
|
113
|
-
1. EXACT MATCHING: The `old_str` parameter must match EXACTLY one or more consecutive lines from the file, including all whitespace and indentation. The tool will fail if `old_str` matches multiple locations or doesn't match exactly with the file content.
|
|
114
|
-
|
|
115
|
-
2. UNIQUENESS: The `old_str` must uniquely identify a single instance in the file:
|
|
116
|
-
- Include sufficient context before and after the change point (3-5 lines recommended)
|
|
117
|
-
- If not unique, the replacement will not be performed
|
|
118
|
-
|
|
119
|
-
3. REPLACEMENT: The `new_str` parameter should contain the edited lines that replace the `old_str`. Both strings must be different.
|
|
120
|
-
|
|
121
|
-
Remember: when making multiple file edits in a row to the same file, you should prefer to send all edits in a single message with multiple calls to this tool, rather than multiple messages with a single call each.
|
|
122
|
-
""" # noqa: E501
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
str_replace_editor_tool = Tool(
|
|
126
|
-
name="str_replace_editor",
|
|
127
|
-
input_schema=StrReplaceEditorAction,
|
|
128
|
-
description=TOOL_DESCRIPTION,
|
|
129
|
-
annotations=ToolAnnotations(
|
|
130
|
-
title="str_replace_editor",
|
|
131
|
-
readOnlyHint=False,
|
|
132
|
-
destructiveHint=True,
|
|
133
|
-
idempotentHint=False,
|
|
134
|
-
openWorldHint=False,
|
|
135
|
-
),
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
class FileEditorTool(Tool[StrReplaceEditorAction, StrReplaceEditorObservation]):
|
|
140
|
-
"""A Tool subclass that automatically initializes a FileEditorExecutor."""
|
|
141
|
-
|
|
142
|
-
def __init__(self):
|
|
143
|
-
"""Initialize FileEditorTool with a FileEditorExecutor."""
|
|
144
|
-
# Import here to avoid circular imports
|
|
145
|
-
from openhands.tools.str_replace_editor.impl import FileEditorExecutor
|
|
146
|
-
|
|
147
|
-
# Initialize the executor
|
|
148
|
-
executor = FileEditorExecutor()
|
|
149
|
-
|
|
150
|
-
# Initialize the parent Tool with the executor
|
|
151
|
-
super().__init__(
|
|
152
|
-
name=str_replace_editor_tool.name,
|
|
153
|
-
description=TOOL_DESCRIPTION,
|
|
154
|
-
input_schema=StrReplaceEditorAction,
|
|
155
|
-
output_schema=StrReplaceEditorObservation,
|
|
156
|
-
annotations=str_replace_editor_tool.annotations,
|
|
157
|
-
executor=executor,
|
|
158
|
-
)
|