basic-open-agent-tools 0.4.0__tar.gz → 0.4.2__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.
- {basic_open_agent_tools-0.4.0/src/basic_open_agent_tools.egg-info → basic_open_agent_tools-0.4.2}/PKG-INFO +1 -1
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/pyproject.toml +1 -1
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/file_system/__init__.py +4 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/file_system/operations.py +95 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2/src/basic_open_agent_tools.egg-info}/PKG-INFO +1 -1
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_transform.py +0 -1
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_file_system_tools.py +82 -1
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/LICENSE +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/README.md +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/setup.cfg +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/setup.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/__init__.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/crypto/__init__.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/data/__init__.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/data/archive_processing.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/data/binary_processing.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/data/config_processing.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/data/csv_tools.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/data/json_tools.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/data/object_serialization.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/data/structures.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/data/transform.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/data/validation.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/exceptions.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/file_system/info.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/file_system/tree.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/file_system/validation.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/helpers.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/network/__init__.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/system/__init__.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/text/__init__.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/text/processing.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/types.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/utilities/__init__.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools.egg-info/SOURCES.txt +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools.egg-info/dependency_links.txt +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools.egg-info/requires.txt +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools.egg-info/top_level.txt +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_archive_processing.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_binary_processing.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_config_processing.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_csv_tools.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_json_tools.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_object_serialization.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_structures.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_validation.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_helpers.py +0 -0
- {basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_text_processing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basic-open-agent-tools
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: An open foundational toolkit providing essential components for building AI agents with minimal dependencies for local (non-HTTP/API) actions.
|
|
5
5
|
Home-page: https://github.com/open-agent-tools/basic-open-agent-tools
|
|
6
6
|
Author: Open Agent Tools
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta:__legacy__"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "basic-open-agent-tools"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.2" # Add targeted file editing functions for safer agent operations
|
|
8
8
|
description = "An open foundational toolkit providing essential components for building AI agents with minimal dependencies for local (non-HTTP/API) actions."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -27,9 +27,11 @@ from .operations import (
|
|
|
27
27
|
create_directory,
|
|
28
28
|
delete_directory,
|
|
29
29
|
delete_file,
|
|
30
|
+
insert_at_line,
|
|
30
31
|
list_directory_contents,
|
|
31
32
|
move_file,
|
|
32
33
|
read_file_to_string,
|
|
34
|
+
replace_in_file,
|
|
33
35
|
write_file_from_string,
|
|
34
36
|
)
|
|
35
37
|
from .tree import (
|
|
@@ -47,6 +49,8 @@ __all__ = [
|
|
|
47
49
|
"read_file_to_string",
|
|
48
50
|
"write_file_from_string",
|
|
49
51
|
"append_to_file",
|
|
52
|
+
"replace_in_file",
|
|
53
|
+
"insert_at_line",
|
|
50
54
|
# Directory operations
|
|
51
55
|
"list_directory_contents",
|
|
52
56
|
"create_directory",
|
|
@@ -233,3 +233,98 @@ def copy_file(source_path: str, destination_path: str) -> bool:
|
|
|
233
233
|
return True
|
|
234
234
|
except OSError as e:
|
|
235
235
|
raise FileSystemError(f"Failed to copy {src_path} to {dst_path}: {e}")
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def replace_in_file(
|
|
239
|
+
file_path: str, old_text: str, new_text: str, count: int = -1
|
|
240
|
+
) -> bool:
|
|
241
|
+
"""Replace occurrences of text within a file without rewriting the entire content.
|
|
242
|
+
|
|
243
|
+
This function performs targeted text replacement, making it safer for agents
|
|
244
|
+
to make small changes without accidentally removing other content.
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
file_path: Path to the file to modify
|
|
248
|
+
old_text: Text to search for and replace
|
|
249
|
+
new_text: Text to replace the old text with
|
|
250
|
+
count: Maximum number of replacements to make (-1 for all occurrences)
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
True if successful (even if no replacements were made)
|
|
254
|
+
|
|
255
|
+
Raises:
|
|
256
|
+
FileSystemError: If file doesn't exist, can't be read, or write fails
|
|
257
|
+
ValueError: If old_text is empty
|
|
258
|
+
"""
|
|
259
|
+
if not old_text:
|
|
260
|
+
raise ValueError("old_text cannot be empty")
|
|
261
|
+
|
|
262
|
+
validate_file_content(new_text, "replace")
|
|
263
|
+
path = validate_path(file_path, "replace")
|
|
264
|
+
|
|
265
|
+
if not path.is_file():
|
|
266
|
+
raise FileSystemError(f"File not found: {path}")
|
|
267
|
+
|
|
268
|
+
try:
|
|
269
|
+
# Read current content
|
|
270
|
+
content = path.read_text(encoding="utf-8")
|
|
271
|
+
|
|
272
|
+
# Perform replacement
|
|
273
|
+
updated_content = content.replace(old_text, new_text, count)
|
|
274
|
+
|
|
275
|
+
# Write back to file
|
|
276
|
+
path.write_text(updated_content, encoding="utf-8")
|
|
277
|
+
return True
|
|
278
|
+
except (OSError, UnicodeDecodeError) as e:
|
|
279
|
+
raise FileSystemError(f"Failed to replace text in file {path}: {e}")
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def insert_at_line(file_path: str, line_number: int, content: str) -> bool:
|
|
283
|
+
"""Insert content at a specific line number in a file.
|
|
284
|
+
|
|
285
|
+
This function allows precise insertion of text at a specific line,
|
|
286
|
+
making it safer for agents to add content without overwriting files.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
file_path: Path to the file to modify
|
|
290
|
+
line_number: Line number to insert at (1-based indexing)
|
|
291
|
+
content: Content to insert (will be added as a new line)
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
True if successful
|
|
295
|
+
|
|
296
|
+
Raises:
|
|
297
|
+
FileSystemError: If file doesn't exist, can't be read, or write fails
|
|
298
|
+
ValueError: If line_number is less than 1
|
|
299
|
+
"""
|
|
300
|
+
if line_number < 1:
|
|
301
|
+
raise ValueError("line_number must be 1 or greater")
|
|
302
|
+
|
|
303
|
+
validate_file_content(content, "insert")
|
|
304
|
+
path = validate_path(file_path, "insert")
|
|
305
|
+
|
|
306
|
+
if not path.is_file():
|
|
307
|
+
raise FileSystemError(f"File not found: {path}")
|
|
308
|
+
|
|
309
|
+
try:
|
|
310
|
+
# Read current lines
|
|
311
|
+
lines = path.read_text(encoding="utf-8").splitlines(keepends=True)
|
|
312
|
+
|
|
313
|
+
# Ensure content ends with newline if it doesn't already
|
|
314
|
+
if content and not content.endswith("\n"):
|
|
315
|
+
content += "\n"
|
|
316
|
+
|
|
317
|
+
# Insert at specified line (convert to 0-based index)
|
|
318
|
+
insert_index = line_number - 1
|
|
319
|
+
|
|
320
|
+
# If line number is beyond file length, append to end
|
|
321
|
+
if insert_index >= len(lines):
|
|
322
|
+
lines.append(content)
|
|
323
|
+
else:
|
|
324
|
+
lines.insert(insert_index, content)
|
|
325
|
+
|
|
326
|
+
# Write back to file
|
|
327
|
+
path.write_text("".join(lines), encoding="utf-8")
|
|
328
|
+
return True
|
|
329
|
+
except (OSError, UnicodeDecodeError) as e:
|
|
330
|
+
raise FileSystemError(f"Failed to insert content in file {path}: {e}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: basic-open-agent-tools
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: An open foundational toolkit providing essential components for building AI agents with minimal dependencies for local (non-HTTP/API) actions.
|
|
5
5
|
Home-page: https://github.com/open-agent-tools/basic-open-agent-tools
|
|
6
6
|
Author: Open Agent Tools
|
{basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_file_system_tools.py
RENAMED
|
@@ -72,15 +72,96 @@ class TestFileSystemModule:
|
|
|
72
72
|
assert "subdir1" in shallow_tree
|
|
73
73
|
assert "nested" not in shallow_tree
|
|
74
74
|
|
|
75
|
+
def test_replace_in_file(self):
|
|
76
|
+
"""Test targeted text replacement in files."""
|
|
77
|
+
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".txt") as f:
|
|
78
|
+
test_file = f.name
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
# Create test file with content
|
|
82
|
+
content = "Hello world!\nThis is a test.\nHello again!"
|
|
83
|
+
file_system.write_file_from_string(test_file, content)
|
|
84
|
+
|
|
85
|
+
# Test replacement
|
|
86
|
+
result = file_system.replace_in_file(test_file, "Hello", "Hi")
|
|
87
|
+
assert result is True
|
|
88
|
+
|
|
89
|
+
# Verify replacement
|
|
90
|
+
updated_content = file_system.read_file_to_string(test_file)
|
|
91
|
+
assert "Hi world!" in updated_content
|
|
92
|
+
assert "Hi again!" in updated_content
|
|
93
|
+
assert "This is a test." in updated_content
|
|
94
|
+
|
|
95
|
+
# Test limited replacement count
|
|
96
|
+
file_system.write_file_from_string(test_file, content)
|
|
97
|
+
result = file_system.replace_in_file(test_file, "Hello", "Hi", count=1)
|
|
98
|
+
assert result is True
|
|
99
|
+
|
|
100
|
+
updated_content = file_system.read_file_to_string(test_file)
|
|
101
|
+
assert updated_content.count("Hi") == 1
|
|
102
|
+
assert updated_content.count("Hello") == 1
|
|
103
|
+
|
|
104
|
+
finally:
|
|
105
|
+
if os.path.exists(test_file):
|
|
106
|
+
os.unlink(test_file)
|
|
107
|
+
|
|
108
|
+
def test_insert_at_line(self):
|
|
109
|
+
"""Test inserting content at specific line numbers."""
|
|
110
|
+
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".txt") as f:
|
|
111
|
+
test_file = f.name
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
# Create test file with multiple lines
|
|
115
|
+
content = "Line 1\nLine 2\nLine 3"
|
|
116
|
+
file_system.write_file_from_string(test_file, content)
|
|
117
|
+
|
|
118
|
+
# Test inserting at beginning
|
|
119
|
+
result = file_system.insert_at_line(test_file, 1, "New Line 1")
|
|
120
|
+
assert result is True
|
|
121
|
+
|
|
122
|
+
updated_content = file_system.read_file_to_string(test_file)
|
|
123
|
+
lines = updated_content.split("\n")
|
|
124
|
+
assert lines[0] == "New Line 1"
|
|
125
|
+
assert lines[1] == "Line 1"
|
|
126
|
+
|
|
127
|
+
# Test inserting in middle
|
|
128
|
+
file_system.write_file_from_string(test_file, content)
|
|
129
|
+
result = file_system.insert_at_line(test_file, 2, "Inserted Line")
|
|
130
|
+
assert result is True
|
|
131
|
+
|
|
132
|
+
updated_content = file_system.read_file_to_string(test_file)
|
|
133
|
+
lines = updated_content.split("\n")
|
|
134
|
+
assert lines[0] == "Line 1"
|
|
135
|
+
assert lines[1] == "Inserted Line"
|
|
136
|
+
assert lines[2] == "Line 2"
|
|
137
|
+
|
|
138
|
+
# Test inserting beyond file length (should append)
|
|
139
|
+
file_system.write_file_from_string(test_file, content)
|
|
140
|
+
result = file_system.insert_at_line(test_file, 10, "Appended Line")
|
|
141
|
+
assert result is True
|
|
142
|
+
|
|
143
|
+
updated_content = file_system.read_file_to_string(test_file)
|
|
144
|
+
assert "Appended Line" in updated_content
|
|
145
|
+
|
|
146
|
+
finally:
|
|
147
|
+
if os.path.exists(test_file):
|
|
148
|
+
os.unlink(test_file)
|
|
149
|
+
|
|
75
150
|
def test_submodule_imports(self):
|
|
76
151
|
"""Test that individual submodules can be imported."""
|
|
77
152
|
from basic_open_agent_tools.file_system.info import file_exists
|
|
78
|
-
from basic_open_agent_tools.file_system.operations import
|
|
153
|
+
from basic_open_agent_tools.file_system.operations import (
|
|
154
|
+
insert_at_line,
|
|
155
|
+
read_file_to_string,
|
|
156
|
+
replace_in_file,
|
|
157
|
+
)
|
|
79
158
|
from basic_open_agent_tools.file_system.tree import list_all_directory_contents
|
|
80
159
|
from basic_open_agent_tools.file_system.validation import validate_path
|
|
81
160
|
|
|
82
161
|
# Just test that imports work
|
|
83
162
|
assert callable(read_file_to_string)
|
|
163
|
+
assert callable(replace_in_file)
|
|
164
|
+
assert callable(insert_at_line)
|
|
84
165
|
assert callable(file_exists)
|
|
85
166
|
assert callable(list_all_directory_contents)
|
|
86
167
|
assert callable(validate_path)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/src/basic_open_agent_tools/types.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_archive_processing.py
RENAMED
|
File without changes
|
{basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_binary_processing.py
RENAMED
|
File without changes
|
{basic_open_agent_tools-0.4.0 → basic_open_agent_tools-0.4.2}/tests/test_data_config_processing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|