toolplane-python-client 0.1.0__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.
- toolplane/__init__.py +106 -0
- toolplane/common/__init__.py +93 -0
- toolplane/common/base_config.py +129 -0
- toolplane/common/base_connection_manager.py +171 -0
- toolplane/common/base_session_manager.py +321 -0
- toolplane/common/base_tool_manager.py +347 -0
- toolplane/common/constants.py +47 -0
- toolplane/common/utils.py +310 -0
- toolplane/core/__init__.py +67 -0
- toolplane/core/config.py +107 -0
- toolplane/core/connection.py +285 -0
- toolplane/core/errors.py +298 -0
- toolplane/core/machine.py +480 -0
- toolplane/core/request.py +775 -0
- toolplane/core/session.py +332 -0
- toolplane/core/session_context.py +514 -0
- toolplane/core/task.py +130 -0
- toolplane/core/tool.py +329 -0
- toolplane/http_core/__init__.py +37 -0
- toolplane/http_core/http_config.py +97 -0
- toolplane/http_core/http_connection.py +409 -0
- toolplane/http_core/http_machine.py +298 -0
- toolplane/http_core/http_request.py +748 -0
- toolplane/http_core/http_session.py +348 -0
- toolplane/http_core/http_session_context.py +491 -0
- toolplane/http_core/http_task.py +101 -0
- toolplane/http_core/http_tool.py +400 -0
- toolplane/interfaces/__init__.py +27 -0
- toolplane/interfaces/client_interface.py +122 -0
- toolplane/interfaces/connection_interface.py +193 -0
- toolplane/interfaces/event_interface.py +290 -0
- toolplane/interfaces/request_interface.py +439 -0
- toolplane/interfaces/session_interface.py +288 -0
- toolplane/interfaces/tool_interface.py +441 -0
- toolplane/proto/__init__.py +0 -0
- toolplane/proto/service_pb2.py +315 -0
- toolplane/proto/service_pb2_grpc.py +2240 -0
- toolplane/provider_cli.py +268 -0
- toolplane/provider_registry.py +77 -0
- toolplane/provider_runtime.py +302 -0
- toolplane/toolkits/__init__.py +0 -0
- toolplane/toolkits/standalone_tools/__init__.py +0 -0
- toolplane/toolkits/standalone_tools/create_directory.py +94 -0
- toolplane/toolkits/standalone_tools/create_file.py +124 -0
- toolplane/toolkits/standalone_tools/file_search.py +229 -0
- toolplane/toolkits/standalone_tools/grep_search.py +372 -0
- toolplane/toolkits/standalone_tools/launcher.py +146 -0
- toolplane/toolkits/standalone_tools/list_dir.py +395 -0
- toolplane/toolkits/standalone_tools/read_file.py +346 -0
- toolplane/toolkits/standalone_tools/replace_string_in_file.py +407 -0
- toolplane/toolkits/standalone_tools/run_tests.py +66 -0
- toolplane/toolkits/standalone_tools/semantic_search.py +485 -0
- toolplane/toolkits/standalone_tools/standalone_toolkit.py +979 -0
- toolplane/toolkits/standalone_tools/test_failure_analysis.py +618 -0
- toolplane/toolkits/standalone_tools/test_standalone_toolkit.py +517 -0
- toolplane/toolkits/swe/__init__.py +35 -0
- toolplane/toolkits/swe/create_directory.py +15 -0
- toolplane/toolkits/swe/create_file.py +15 -0
- toolplane/toolkits/swe/descriptions.py +273 -0
- toolplane/toolkits/swe/execute_bash.py +93 -0
- toolplane/toolkits/swe/file_editor.py +775 -0
- toolplane/toolkits/swe/file_search.py +16 -0
- toolplane/toolkits/swe/finish.py +50 -0
- toolplane/toolkits/swe/grep_search.py +19 -0
- toolplane/toolkits/swe/list_dir.py +407 -0
- toolplane/toolkits/swe/read_file.py +18 -0
- toolplane/toolkits/swe/replace_string_in_file.py +17 -0
- toolplane/toolkits/swe/search.py +260 -0
- toolplane/toolkits/swe/semantic_search.py +20 -0
- toolplane/toolkits/swe/str_replace_editor.py +647 -0
- toolplane/toolkits/swe/submit.py +29 -0
- toolplane/toolkits/swe/swe_toolkit.py +1296 -0
- toolplane/toolplane_client.py +686 -0
- toolplane/toolplane_http_client.py +681 -0
- toolplane/utils/__init__.py +3 -0
- toolplane/utils/schema.py +146 -0
- toolplane_python_client-0.1.0.dist-info/METADATA +543 -0
- toolplane_python_client-0.1.0.dist-info/RECORD +81 -0
- toolplane_python_client-0.1.0.dist-info/WHEEL +5 -0
- toolplane_python_client-0.1.0.dist-info/entry_points.txt +2 -0
- toolplane_python_client-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Description: Search for a term in either a directory or a single file.
|
|
4
|
+
|
|
5
|
+
Behavior:
|
|
6
|
+
* If `--path` points to a directory (default is `.`), we recursively search all non-hidden files and directories.
|
|
7
|
+
* If `--path` points to a file, we run `grep -n` on that file to find line numbers containing the search term.
|
|
8
|
+
* If more than 100 files match (directory search scenario), the tool will stop listing and inform you to narrow your search.
|
|
9
|
+
* If no files are found that match your search term, the tool will inform you of that as well.
|
|
10
|
+
|
|
11
|
+
**Parameters:**
|
|
12
|
+
1. **search_term** (`string`, required): The term to search for in files.
|
|
13
|
+
2. **path** (`string`, optional): The file or directory in which to search. If not provided, defaults to the current directory (i.e., `.`).
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import argparse
|
|
17
|
+
import os
|
|
18
|
+
import subprocess
|
|
19
|
+
import sys
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def search_in_directory(
|
|
23
|
+
search_term: str, directory: str = ".", python_only: bool = False
|
|
24
|
+
):
|
|
25
|
+
"""
|
|
26
|
+
Searches for `search_term` in all non-hidden files under `directory`
|
|
27
|
+
(or only in .py files if `python_only=True`), excluding hidden directories.
|
|
28
|
+
Prints how many matches were found per file.
|
|
29
|
+
"""
|
|
30
|
+
directory = os.path.realpath(directory)
|
|
31
|
+
|
|
32
|
+
if not os.path.isdir(directory):
|
|
33
|
+
print(f"Directory '{directory}' not found or not a directory.")
|
|
34
|
+
sys.exit(1)
|
|
35
|
+
|
|
36
|
+
matches = {}
|
|
37
|
+
num_files_matched = 0
|
|
38
|
+
|
|
39
|
+
for root, dirs, files in os.walk(directory):
|
|
40
|
+
# Exclude hidden directories
|
|
41
|
+
dirs[:] = [d for d in dirs if not d.startswith(".")]
|
|
42
|
+
for file in files:
|
|
43
|
+
# Skip hidden files
|
|
44
|
+
if file.startswith("."):
|
|
45
|
+
continue
|
|
46
|
+
|
|
47
|
+
# If --python_only is set, only search .py files
|
|
48
|
+
if python_only and not file.endswith(".py"):
|
|
49
|
+
continue
|
|
50
|
+
|
|
51
|
+
filepath = os.path.join(root, file)
|
|
52
|
+
try:
|
|
53
|
+
with open(filepath, "r", errors="ignore") as f:
|
|
54
|
+
file_matches = 0
|
|
55
|
+
for line_num, line in enumerate(f, 1):
|
|
56
|
+
if search_term in line:
|
|
57
|
+
file_matches += 1
|
|
58
|
+
if file_matches > 0:
|
|
59
|
+
matches[filepath] = file_matches
|
|
60
|
+
num_files_matched += 1
|
|
61
|
+
except (UnicodeDecodeError, PermissionError):
|
|
62
|
+
# Skip files that can't be read
|
|
63
|
+
continue
|
|
64
|
+
|
|
65
|
+
if not matches:
|
|
66
|
+
print(f'No matches found for "{search_term}" in {directory}')
|
|
67
|
+
sys.exit(0)
|
|
68
|
+
|
|
69
|
+
# Summarize
|
|
70
|
+
num_matches = sum(matches.values())
|
|
71
|
+
if num_files_matched > 100:
|
|
72
|
+
print(
|
|
73
|
+
f'More than {num_files_matched} files matched for "{search_term}" in {directory}. '
|
|
74
|
+
"Please narrow your search."
|
|
75
|
+
)
|
|
76
|
+
sys.exit(0)
|
|
77
|
+
|
|
78
|
+
print(f'Found {num_matches} matches for "{search_term}" in {directory}:')
|
|
79
|
+
|
|
80
|
+
# Print matched files
|
|
81
|
+
for filepath, count in matches.items():
|
|
82
|
+
relative_path = os.path.relpath(filepath, start=os.getcwd())
|
|
83
|
+
if not relative_path.startswith("./"):
|
|
84
|
+
relative_path = "./" + relative_path
|
|
85
|
+
print(f"{relative_path} ({count} matches)")
|
|
86
|
+
|
|
87
|
+
print(f'End of matches for "{search_term}" in {directory}')
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def search_in_directory_old(search_term: str, directory: str = ".", python_only=False):
|
|
91
|
+
"""
|
|
92
|
+
Searches for `search_term` in all non-hidden files under `directory`,
|
|
93
|
+
excluding hidden directories. Prints how many matches were found per file.
|
|
94
|
+
"""
|
|
95
|
+
directory = os.path.realpath(directory)
|
|
96
|
+
|
|
97
|
+
if not os.path.isdir(directory):
|
|
98
|
+
print(f"Directory '{directory}' not found or not a directory.")
|
|
99
|
+
sys.exit(1)
|
|
100
|
+
|
|
101
|
+
matches = {}
|
|
102
|
+
num_files_matched = 0
|
|
103
|
+
|
|
104
|
+
for root, dirs, files in os.walk(directory):
|
|
105
|
+
# Exclude hidden directories
|
|
106
|
+
dirs[:] = [d for d in dirs if not d.startswith(".")]
|
|
107
|
+
for file in files:
|
|
108
|
+
# Skip hidden files
|
|
109
|
+
if file.startswith("."):
|
|
110
|
+
continue
|
|
111
|
+
filepath = os.path.join(root, file)
|
|
112
|
+
try:
|
|
113
|
+
with open(filepath, "r", errors="ignore") as f:
|
|
114
|
+
file_matches = 0
|
|
115
|
+
for line_num, line in enumerate(f, 1):
|
|
116
|
+
if search_term in line:
|
|
117
|
+
file_matches += 1
|
|
118
|
+
if file_matches > 0:
|
|
119
|
+
matches[filepath] = file_matches
|
|
120
|
+
num_files_matched += 1
|
|
121
|
+
except (UnicodeDecodeError, PermissionError):
|
|
122
|
+
# Skip files that can't be read
|
|
123
|
+
continue
|
|
124
|
+
|
|
125
|
+
if not matches:
|
|
126
|
+
print(f'No matches found for "{search_term}" in {directory}')
|
|
127
|
+
sys.exit(0)
|
|
128
|
+
|
|
129
|
+
# Summarize
|
|
130
|
+
num_matches = sum(matches.values())
|
|
131
|
+
if num_files_matched > 100:
|
|
132
|
+
print(
|
|
133
|
+
f'More than {num_files_matched} files matched for "{search_term}" in {directory}. '
|
|
134
|
+
"Please narrow your search."
|
|
135
|
+
)
|
|
136
|
+
sys.exit(0)
|
|
137
|
+
|
|
138
|
+
print(f'Found {num_matches} matches for "{search_term}" in {directory}:')
|
|
139
|
+
|
|
140
|
+
# Print matched files
|
|
141
|
+
for filepath, count in matches.items():
|
|
142
|
+
# Convert absolute path to relative path
|
|
143
|
+
relative_path = os.path.relpath(filepath, start=os.getcwd())
|
|
144
|
+
if not relative_path.startswith("./"):
|
|
145
|
+
relative_path = "./" + relative_path
|
|
146
|
+
print(f"{relative_path} ({count} matches)")
|
|
147
|
+
|
|
148
|
+
print(f'End of matches for "{search_term}" in {directory}')
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def search_in_file(search_term: str, filepath: str):
|
|
152
|
+
"""
|
|
153
|
+
Searches for `search_term` in a single file and prints matching lines with line numbers.
|
|
154
|
+
Uses grep on Unix systems, falls back to pure Python search on Windows.
|
|
155
|
+
"""
|
|
156
|
+
filepath = os.path.realpath(filepath)
|
|
157
|
+
|
|
158
|
+
if not os.path.isfile(filepath):
|
|
159
|
+
print(f"File '{filepath}' not found or is not a file.")
|
|
160
|
+
sys.exit(1)
|
|
161
|
+
|
|
162
|
+
# Try using grep first (Unix systems)
|
|
163
|
+
try:
|
|
164
|
+
try:
|
|
165
|
+
# Try modern parameters if Python 3.7+ (capture_output, text)
|
|
166
|
+
result = subprocess.run(
|
|
167
|
+
["grep", "-n", search_term, filepath], capture_output=True, text=True
|
|
168
|
+
)
|
|
169
|
+
except TypeError:
|
|
170
|
+
# Fallback for Python 3.5/3.6
|
|
171
|
+
result = subprocess.run(
|
|
172
|
+
["grep", "-n", search_term, filepath],
|
|
173
|
+
stdout=subprocess.PIPE,
|
|
174
|
+
stderr=subprocess.PIPE,
|
|
175
|
+
universal_newlines=True,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
if result.returncode == 0:
|
|
179
|
+
# grep found matches
|
|
180
|
+
print(f'Matches for "{search_term}" in {filepath}:')
|
|
181
|
+
print(result.stdout.strip())
|
|
182
|
+
return
|
|
183
|
+
elif result.returncode == 1:
|
|
184
|
+
# grep found no matches
|
|
185
|
+
print(f'No matches found for "{search_term}" in {filepath}')
|
|
186
|
+
return
|
|
187
|
+
else:
|
|
188
|
+
# grep had an error, fall back to Python search
|
|
189
|
+
raise subprocess.CalledProcessError(result.returncode, "grep")
|
|
190
|
+
|
|
191
|
+
except (FileNotFoundError, subprocess.CalledProcessError):
|
|
192
|
+
# grep not available or failed, use Python fallback
|
|
193
|
+
pass
|
|
194
|
+
|
|
195
|
+
# Fallback to pure Python search (cross-platform)
|
|
196
|
+
try:
|
|
197
|
+
matches_found = False
|
|
198
|
+
with open(filepath, "r", errors="ignore") as f:
|
|
199
|
+
for line_num, line in enumerate(f, 1):
|
|
200
|
+
if search_term in line:
|
|
201
|
+
if not matches_found:
|
|
202
|
+
print(f'Matches for "{search_term}" in {filepath}:')
|
|
203
|
+
matches_found = True
|
|
204
|
+
# Format similar to grep output
|
|
205
|
+
print(f"{line_num}:{line.rstrip()}")
|
|
206
|
+
|
|
207
|
+
if not matches_found:
|
|
208
|
+
print(f'No matches found for "{search_term}" in {filepath}')
|
|
209
|
+
|
|
210
|
+
except (UnicodeDecodeError, PermissionError) as e:
|
|
211
|
+
print(f"Error reading file '{filepath}': {e}")
|
|
212
|
+
sys.exit(1)
|
|
213
|
+
# try:
|
|
214
|
+
# # Run grep -n <search_term> <filepath>
|
|
215
|
+
# result = subprocess.run(
|
|
216
|
+
# ["grep", "-n", search_term, filepath], capture_output=True, text=True
|
|
217
|
+
# )
|
|
218
|
+
# if result.returncode != 0:
|
|
219
|
+
# # grep exit code = 1 means no matches
|
|
220
|
+
# print(f'No matches found for "{search_term}" in {filepath}')
|
|
221
|
+
# sys.exit(0)
|
|
222
|
+
# # Print grep output directly
|
|
223
|
+
# print(f'Matches for "{search_term}" in {filepath}:')
|
|
224
|
+
# print(result.stdout.strip())
|
|
225
|
+
# except FileNotFoundError:
|
|
226
|
+
# print(
|
|
227
|
+
# "`grep` is not available on this system. Please install or use another method."
|
|
228
|
+
# )
|
|
229
|
+
# sys.exit(1)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def main():
|
|
233
|
+
parser = argparse.ArgumentParser(
|
|
234
|
+
description="search tool: run subcommands such as `search` for files or directories."
|
|
235
|
+
)
|
|
236
|
+
parser.add_argument(
|
|
237
|
+
"--search_term", help="Term to search for in files.", required=True
|
|
238
|
+
)
|
|
239
|
+
parser.add_argument(
|
|
240
|
+
"--path",
|
|
241
|
+
help="File or directory to search in (defaults to current dir).",
|
|
242
|
+
default=".",
|
|
243
|
+
)
|
|
244
|
+
# NEW ARGUMENT:
|
|
245
|
+
parser.add_argument(
|
|
246
|
+
"--python_only",
|
|
247
|
+
default=True,
|
|
248
|
+
help="If set, only search for matches in .py files when searching a directory.",
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
args = parser.parse_args()
|
|
252
|
+
# Check if path is a file or a directory
|
|
253
|
+
if os.path.isfile(args.path):
|
|
254
|
+
search_in_file(args.search_term, args.path)
|
|
255
|
+
else:
|
|
256
|
+
search_in_directory(args.search_term, args.path, python_only=args.python_only)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
if __name__ == "__main__":
|
|
260
|
+
main()
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Re-exported from toolplane.toolkits.standalone_tools — the single
|
|
2
|
+
maintained copy of this tool. The SWE toolkit composes these safe
|
|
3
|
+
file tools with its own unsafe ones (execute_bash, file_editor).
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from toolplane.toolkits.standalone_tools.semantic_search import ( # noqa: F401
|
|
7
|
+
calculate_similarity,
|
|
8
|
+
extract_functions_and_classes,
|
|
9
|
+
get_searchable_files,
|
|
10
|
+
main,
|
|
11
|
+
preprocess_text,
|
|
12
|
+
search_file,
|
|
13
|
+
semantic_search,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if __name__ == "__main__":
|
|
17
|
+
main()
|
|
18
|
+
|
|
19
|
+
if __name__ == "__main__":
|
|
20
|
+
main()
|