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.
Files changed (81) hide show
  1. toolplane/__init__.py +106 -0
  2. toolplane/common/__init__.py +93 -0
  3. toolplane/common/base_config.py +129 -0
  4. toolplane/common/base_connection_manager.py +171 -0
  5. toolplane/common/base_session_manager.py +321 -0
  6. toolplane/common/base_tool_manager.py +347 -0
  7. toolplane/common/constants.py +47 -0
  8. toolplane/common/utils.py +310 -0
  9. toolplane/core/__init__.py +67 -0
  10. toolplane/core/config.py +107 -0
  11. toolplane/core/connection.py +285 -0
  12. toolplane/core/errors.py +298 -0
  13. toolplane/core/machine.py +480 -0
  14. toolplane/core/request.py +775 -0
  15. toolplane/core/session.py +332 -0
  16. toolplane/core/session_context.py +514 -0
  17. toolplane/core/task.py +130 -0
  18. toolplane/core/tool.py +329 -0
  19. toolplane/http_core/__init__.py +37 -0
  20. toolplane/http_core/http_config.py +97 -0
  21. toolplane/http_core/http_connection.py +409 -0
  22. toolplane/http_core/http_machine.py +298 -0
  23. toolplane/http_core/http_request.py +748 -0
  24. toolplane/http_core/http_session.py +348 -0
  25. toolplane/http_core/http_session_context.py +491 -0
  26. toolplane/http_core/http_task.py +101 -0
  27. toolplane/http_core/http_tool.py +400 -0
  28. toolplane/interfaces/__init__.py +27 -0
  29. toolplane/interfaces/client_interface.py +122 -0
  30. toolplane/interfaces/connection_interface.py +193 -0
  31. toolplane/interfaces/event_interface.py +290 -0
  32. toolplane/interfaces/request_interface.py +439 -0
  33. toolplane/interfaces/session_interface.py +288 -0
  34. toolplane/interfaces/tool_interface.py +441 -0
  35. toolplane/proto/__init__.py +0 -0
  36. toolplane/proto/service_pb2.py +315 -0
  37. toolplane/proto/service_pb2_grpc.py +2240 -0
  38. toolplane/provider_cli.py +268 -0
  39. toolplane/provider_registry.py +77 -0
  40. toolplane/provider_runtime.py +302 -0
  41. toolplane/toolkits/__init__.py +0 -0
  42. toolplane/toolkits/standalone_tools/__init__.py +0 -0
  43. toolplane/toolkits/standalone_tools/create_directory.py +94 -0
  44. toolplane/toolkits/standalone_tools/create_file.py +124 -0
  45. toolplane/toolkits/standalone_tools/file_search.py +229 -0
  46. toolplane/toolkits/standalone_tools/grep_search.py +372 -0
  47. toolplane/toolkits/standalone_tools/launcher.py +146 -0
  48. toolplane/toolkits/standalone_tools/list_dir.py +395 -0
  49. toolplane/toolkits/standalone_tools/read_file.py +346 -0
  50. toolplane/toolkits/standalone_tools/replace_string_in_file.py +407 -0
  51. toolplane/toolkits/standalone_tools/run_tests.py +66 -0
  52. toolplane/toolkits/standalone_tools/semantic_search.py +485 -0
  53. toolplane/toolkits/standalone_tools/standalone_toolkit.py +979 -0
  54. toolplane/toolkits/standalone_tools/test_failure_analysis.py +618 -0
  55. toolplane/toolkits/standalone_tools/test_standalone_toolkit.py +517 -0
  56. toolplane/toolkits/swe/__init__.py +35 -0
  57. toolplane/toolkits/swe/create_directory.py +15 -0
  58. toolplane/toolkits/swe/create_file.py +15 -0
  59. toolplane/toolkits/swe/descriptions.py +273 -0
  60. toolplane/toolkits/swe/execute_bash.py +93 -0
  61. toolplane/toolkits/swe/file_editor.py +775 -0
  62. toolplane/toolkits/swe/file_search.py +16 -0
  63. toolplane/toolkits/swe/finish.py +50 -0
  64. toolplane/toolkits/swe/grep_search.py +19 -0
  65. toolplane/toolkits/swe/list_dir.py +407 -0
  66. toolplane/toolkits/swe/read_file.py +18 -0
  67. toolplane/toolkits/swe/replace_string_in_file.py +17 -0
  68. toolplane/toolkits/swe/search.py +260 -0
  69. toolplane/toolkits/swe/semantic_search.py +20 -0
  70. toolplane/toolkits/swe/str_replace_editor.py +647 -0
  71. toolplane/toolkits/swe/submit.py +29 -0
  72. toolplane/toolkits/swe/swe_toolkit.py +1296 -0
  73. toolplane/toolplane_client.py +686 -0
  74. toolplane/toolplane_http_client.py +681 -0
  75. toolplane/utils/__init__.py +3 -0
  76. toolplane/utils/schema.py +146 -0
  77. toolplane_python_client-0.1.0.dist-info/METADATA +543 -0
  78. toolplane_python_client-0.1.0.dist-info/RECORD +81 -0
  79. toolplane_python_client-0.1.0.dist-info/WHEEL +5 -0
  80. toolplane_python_client-0.1.0.dist-info/entry_points.txt +2 -0
  81. 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()