basic-open-agent-tools 0.7.2__tar.gz → 0.7.3__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 (41) hide show
  1. {basic_open_agent_tools-0.7.2/src/basic_open_agent_tools.egg-info → basic_open_agent_tools-0.7.3}/PKG-INFO +1 -1
  2. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/pyproject.toml +1 -1
  3. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/__init__.py +1 -1
  4. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/data/config_processing.py +18 -47
  5. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/data/json_tools.py +7 -7
  6. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/data/validation.py +10 -10
  7. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/file_system/operations.py +1 -1
  8. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3/src/basic_open_agent_tools.egg-info}/PKG-INFO +1 -1
  9. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/tests/test_data_config_processing.py +4 -5
  10. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/tests/test_data_json_tools.py +7 -7
  11. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/LICENSE +0 -0
  12. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/README.md +0 -0
  13. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/setup.cfg +0 -0
  14. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/setup.py +0 -0
  15. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/crypto/__init__.py +0 -0
  16. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/data/__init__.py +0 -0
  17. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/data/csv_tools.py +0 -0
  18. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/data/transform.py +0 -0
  19. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/exceptions.py +0 -0
  20. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/file_system/__init__.py +0 -0
  21. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/file_system/info.py +0 -0
  22. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/file_system/tree.py +0 -0
  23. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/file_system/validation.py +0 -0
  24. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/helpers.py +0 -0
  25. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/network/__init__.py +0 -0
  26. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/system/__init__.py +0 -0
  27. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/text/__init__.py +0 -0
  28. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/text/processing.py +0 -0
  29. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/types.py +0 -0
  30. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools/utilities/__init__.py +0 -0
  31. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools.egg-info/SOURCES.txt +0 -0
  32. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools.egg-info/dependency_links.txt +0 -0
  33. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools.egg-info/requires.txt +0 -0
  34. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/src/basic_open_agent_tools.egg-info/top_level.txt +0 -0
  35. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/tests/test_data_csv_tools.py +0 -0
  36. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/tests/test_data_transform.py +0 -0
  37. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/tests/test_data_validation.py +0 -0
  38. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/tests/test_file_system_tools.py +0 -0
  39. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/tests/test_helpers.py +0 -0
  40. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/tests/test_read_only_tools.py +0 -0
  41. {basic_open_agent_tools-0.7.2 → basic_open_agent_tools-0.7.3}/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.7.2
3
+ Version: 0.7.3
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.7.2" # Remove structures, archives, and object serialization for agent compatibility
7
+ version = "0.7.3" # Remove Any types from function parameters for Google ADK compatibility
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"
@@ -6,7 +6,7 @@ with minimal dependencies for local (non-HTTP/API) actions.
6
6
 
7
7
  from typing import List
8
8
 
9
- __version__ = "0.7.2"
9
+ __version__ = "0.7.3"
10
10
 
11
11
  # Modular structure
12
12
  from . import data, exceptions, file_system, text, types
@@ -2,7 +2,7 @@
2
2
 
3
3
  import configparser
4
4
  import json
5
- from typing import Any, Dict, Optional
5
+ from typing import List, Union
6
6
 
7
7
  from ..exceptions import DataError
8
8
 
@@ -102,7 +102,7 @@ def read_toml_file(file_path: str) -> dict:
102
102
 
103
103
  try:
104
104
  with open(file_path, "rb") as f:
105
- result: Dict[Any, Any] = tomli.load(f)
105
+ result: dict = tomli.load(f)
106
106
  return result
107
107
  except FileNotFoundError:
108
108
  raise FileNotFoundError(f"TOML file not found: {file_path}")
@@ -262,12 +262,12 @@ def validate_config_schema(config_data: dict, schema: dict) -> list:
262
262
  return errors
263
263
 
264
264
 
265
- def merge_config_files(*config_paths: Any, format_type: Optional[str] = None) -> dict:
265
+ def merge_config_files(config_paths: Union[str, List[str]], format_type: str) -> dict:
266
266
  """Merge multiple configuration files into a single dictionary.
267
267
 
268
268
  Args:
269
- *config_paths: Paths to configuration files (either as separate arguments or a list)
270
- format_type: Format of the files ("yaml", "toml", "ini", or None for auto-detect)
269
+ config_paths: Paths to configuration files (either a single path or list of paths)
270
+ format_type: Format of the files ("yaml", "toml", "ini", or "json")
271
271
 
272
272
  Returns:
273
273
  Merged configuration dictionary
@@ -277,58 +277,29 @@ def merge_config_files(*config_paths: Any, format_type: Optional[str] = None) ->
277
277
  DataError: If files cannot be read or merged
278
278
 
279
279
  Example:
280
- >>> merge_config_files("base.yaml", "override.yaml", format_type="yaml")
281
- {"database": {"host": "override-host", "port": 5432}}
282
- >>> merge_config_files(["base.yaml", "override.yaml"], format_type="yaml")
280
+ >>> merge_config_files(["base.yaml", "override.yaml"], "yaml")
283
281
  {"database": {"host": "override-host", "port": 5432}}
282
+ >>> merge_config_files("single.yaml", "yaml")
283
+ {"database": {"host": "localhost", "port": 5432}}
284
284
  """
285
- # Handle both list input and variable arguments
286
- paths = []
287
- if len(config_paths) == 1 and isinstance(config_paths[0], list):
288
- paths = config_paths[0]
285
+ # Handle both single string and list input
286
+ if isinstance(config_paths, str):
287
+ paths = [config_paths]
289
288
  else:
290
- paths = list(config_paths)
289
+ paths = config_paths
291
290
 
292
291
  if not paths:
293
292
  raise ValueError("No configuration files provided")
294
293
 
295
- # Check if all files have the same format if format_type is not specified
296
- if format_type is None and len(paths) > 1:
297
- detected_formats = set()
298
- for path in paths:
299
- if path.endswith((".yml", ".yaml")):
300
- detected_formats.add("yaml")
301
- elif path.endswith(".toml"):
302
- detected_formats.add("toml")
303
- elif path.endswith(".ini"):
304
- detected_formats.add("ini")
305
- elif path.endswith(".json"):
306
- detected_formats.add("json")
307
- else:
308
- raise DataError(f"Cannot determine format for file: {path}")
309
-
310
- if len(detected_formats) > 1:
311
- raise DataError(
312
- f"Cannot merge files with different formats: {detected_formats}"
313
- )
294
+ # Validate format_type
295
+ valid_formats = ["yaml", "toml", "ini", "json"]
296
+ if format_type not in valid_formats:
297
+ raise ValueError(f"format_type must be one of {valid_formats}")
314
298
 
315
- merged_config: Dict[str, Any] = {}
299
+ merged_config: dict = {}
316
300
 
317
301
  for config_path in paths:
318
- # Auto-detect format if not specified
319
- if format_type is None:
320
- if config_path.endswith((".yml", ".yaml")):
321
- file_format = "yaml"
322
- elif config_path.endswith(".toml"):
323
- file_format = "toml"
324
- elif config_path.endswith(".ini"):
325
- file_format = "ini"
326
- elif config_path.endswith(".json"):
327
- file_format = "json"
328
- else:
329
- raise DataError(f"Cannot determine format for file: {config_path}")
330
- else:
331
- file_format = format_type
302
+ file_format = format_type
332
303
 
333
304
  # Read the file
334
305
  if file_format == "yaml":
@@ -2,12 +2,12 @@
2
2
 
3
3
  import gzip
4
4
  import json
5
- from typing import Any
5
+ from typing import Union, cast
6
6
 
7
7
  from ..exceptions import SerializationError
8
8
 
9
9
 
10
- def safe_json_serialize(data: dict, indent: int = 0) -> str:
10
+ def safe_json_serialize(data: Union[dict, list, str, int, float, bool], indent: int) -> str:
11
11
  """Safely serialize data to JSON string with error handling.
12
12
 
13
13
  Args:
@@ -38,7 +38,7 @@ def safe_json_serialize(data: dict, indent: int = 0) -> str:
38
38
  raise SerializationError(f"Failed to serialize data to JSON: {e}")
39
39
 
40
40
 
41
- def safe_json_deserialize(json_str: str) -> Any:
41
+ def safe_json_deserialize(json_str: str) -> Union[dict, list, str, int, float, bool, None]:
42
42
  """Safely deserialize JSON string to Python object with error handling.
43
43
 
44
44
  Args:
@@ -61,7 +61,7 @@ def safe_json_deserialize(json_str: str) -> Any:
61
61
  raise TypeError("Input must be a string")
62
62
 
63
63
  try:
64
- return json.loads(json_str)
64
+ return cast(Union[dict, list, str, int, float, bool, None], json.loads(json_str))
65
65
  except (json.JSONDecodeError, ValueError) as e:
66
66
  raise SerializationError(f"Failed to deserialize JSON string: {e}")
67
67
 
@@ -91,7 +91,7 @@ def validate_json_string(json_str: str) -> bool:
91
91
  return False
92
92
 
93
93
 
94
- def compress_json_data(data: Any) -> bytes:
94
+ def compress_json_data(data: Union[dict, list, str, int, float, bool]) -> bytes:
95
95
  """Compress JSON data for storage or transmission.
96
96
 
97
97
  Args:
@@ -110,13 +110,13 @@ def compress_json_data(data: Any) -> bytes:
110
110
  True
111
111
  """
112
112
  try:
113
- json_str = safe_json_serialize(data)
113
+ json_str = safe_json_serialize(data, 0)
114
114
  return gzip.compress(json_str.encode("utf-8"))
115
115
  except Exception as e:
116
116
  raise SerializationError(f"Failed to compress JSON data: {e}")
117
117
 
118
118
 
119
- def decompress_json_data(compressed_data: bytes) -> Any:
119
+ def decompress_json_data(compressed_data: bytes) -> Union[dict, list, str, int, float, bool, None]:
120
120
  """Decompress and deserialize JSON data.
121
121
 
122
122
  Args:
@@ -1,11 +1,11 @@
1
1
  """Data validation utilities for AI agents."""
2
2
 
3
- from typing import Any, Dict, List, Optional, Union
3
+ from typing import Dict, List, Optional, Union
4
4
 
5
5
  from ..exceptions import ValidationError
6
6
 
7
7
 
8
- def validate_schema_simple(data: Any, schema: Dict[str, Any]) -> bool:
8
+ def validate_schema_simple(data: Union[dict, list, str, int, float, bool], schema: dict) -> bool:
9
9
  """Validate data against a JSON Schema-style schema.
10
10
 
11
11
  Args:
@@ -34,7 +34,7 @@ def validate_schema_simple(data: Any, schema: Dict[str, Any]) -> bool:
34
34
  raise
35
35
 
36
36
 
37
- def _validate_against_schema(data: Any, schema: Dict[str, Any]) -> None:
37
+ def _validate_against_schema(data: Union[dict, list, str, int, float, bool], schema: dict) -> None:
38
38
  """Internal helper to validate data against schema."""
39
39
  schema_type = schema.get("type")
40
40
 
@@ -88,7 +88,7 @@ def _validate_against_schema(data: Any, schema: Dict[str, Any]) -> None:
88
88
  raise ValidationError(f"Expected null, got {type(data).__name__}")
89
89
 
90
90
 
91
- def check_required_fields(data: Dict[str, Any], required: List[str]) -> bool:
91
+ def check_required_fields(data: dict, required: List[str]) -> bool:
92
92
  """Check if all required fields are present in data.
93
93
 
94
94
  Args:
@@ -122,7 +122,7 @@ def check_required_fields(data: Dict[str, Any], required: List[str]) -> bool:
122
122
  return True
123
123
 
124
124
 
125
- def validate_data_types_simple(data: Dict[str, Any], type_map: Dict[str, str]) -> bool:
125
+ def validate_data_types_simple(data: dict, type_map: Dict[str, str]) -> bool:
126
126
  """Check that field types match expectations.
127
127
 
128
128
  Args:
@@ -219,8 +219,8 @@ def validate_range_simple(
219
219
 
220
220
 
221
221
  def create_validation_report(
222
- data: Dict[str, Any], rules: Dict[str, Any]
223
- ) -> Dict[str, Any]:
222
+ data: dict, rules: dict
223
+ ) -> dict:
224
224
  """Create comprehensive validation report for data.
225
225
 
226
226
  Args:
@@ -303,7 +303,7 @@ def create_validation_report(
303
303
  }
304
304
 
305
305
 
306
- def check_required_fields_simple(data: Dict[str, Any], required: List[str]) -> bool:
306
+ def check_required_fields_simple(data: dict, required: List[str]) -> bool:
307
307
  """Check if all required fields are present in data.
308
308
 
309
309
  This is an alias for check_required_fields for LLM agent compatibility.
@@ -327,8 +327,8 @@ def check_required_fields_simple(data: Dict[str, Any], required: List[str]) -> b
327
327
 
328
328
 
329
329
  def create_validation_report_simple(
330
- data: Dict[str, Any], rules: Dict[str, Any]
331
- ) -> Dict[str, Any]:
330
+ data: dict, rules: dict
331
+ ) -> dict:
332
332
  """Create simplified validation report for data.
333
333
 
334
334
  This is an alias for create_validation_report for LLM agent compatibility.
@@ -150,7 +150,7 @@ def delete_file(file_path: str) -> bool:
150
150
  raise FileSystemError(f"Failed to delete file {path}: {e}")
151
151
 
152
152
 
153
- def delete_directory(directory_path: str, recursive: bool = False) -> bool:
153
+ def delete_directory(directory_path: str, recursive: bool) -> bool:
154
154
  """Delete a directory.
155
155
 
156
156
  Args:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-open-agent-tools
3
- Version: 0.7.2
3
+ Version: 0.7.3
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
@@ -12,7 +12,6 @@ from basic_open_agent_tools.data.config_processing import (
12
12
  validate_config_schema,
13
13
  write_ini_file,
14
14
  )
15
- from basic_open_agent_tools.exceptions import DataError
16
15
 
17
16
  # Import optional dependencies if available
18
17
  try:
@@ -229,7 +228,7 @@ class TestMergeConfigFiles:
229
228
  write_ini_file(config2, temp2_path)
230
229
 
231
230
  # Merge configs
232
- merged = merge_config_files(temp1_path, temp2_path)
231
+ merged = merge_config_files([temp1_path, temp2_path], "ini")
233
232
 
234
233
  # Verify
235
234
  assert merged["server"]["host"] == "localhost"
@@ -247,7 +246,7 @@ class TestMergeConfigFiles:
247
246
  def test_merge_config_files_no_paths(self):
248
247
  """Test merging with no config paths."""
249
248
  with pytest.raises(ValueError):
250
- merge_config_files()
249
+ merge_config_files([], "ini")
251
250
 
252
251
  def test_merge_config_files_mixed_formats(self):
253
252
  """Test merging files with different formats."""
@@ -263,8 +262,8 @@ class TestMergeConfigFiles:
263
262
  write_ini_file(config, temp1_path)
264
263
 
265
264
  # Try to merge different formats
266
- with pytest.raises(DataError):
267
- merge_config_files(temp1_path, temp2_path)
265
+ with pytest.raises(ValueError): # Now raises ValueError for invalid format
266
+ merge_config_files([temp1_path, temp2_path], "invalid_format")
268
267
 
269
268
  finally:
270
269
  # Clean up
@@ -18,13 +18,13 @@ class TestSafeJsonSerialize:
18
18
  def test_serialize_dict(self):
19
19
  """Test serializing a dictionary."""
20
20
  data = {"name": "test", "value": 42}
21
- result = safe_json_serialize(data)
21
+ result = safe_json_serialize(data, 0)
22
22
  assert result == '{"name": "test", "value": 42}'
23
23
 
24
24
  def test_serialize_list(self):
25
25
  """Test serializing a list."""
26
26
  data = [1, 2, 3]
27
- result = safe_json_serialize(data)
27
+ result = safe_json_serialize(data, 0)
28
28
  assert result == "[1, 2, 3]"
29
29
 
30
30
  def test_serialize_with_indent(self):
@@ -37,12 +37,12 @@ class TestSafeJsonSerialize:
37
37
  def test_serialize_unicode(self):
38
38
  """Test serializing Unicode characters."""
39
39
  data = {"message": "Hello 世界"}
40
- result = safe_json_serialize(data)
40
+ result = safe_json_serialize(data, 0)
41
41
  assert "世界" in result
42
42
 
43
43
  def test_serialize_none(self):
44
44
  """Test serializing None."""
45
- result = safe_json_serialize(None)
45
+ result = safe_json_serialize(None, 0)
46
46
  assert result == "null"
47
47
 
48
48
  def test_serialize_invalid_indent_type(self):
@@ -59,7 +59,7 @@ class TestSafeJsonSerialize:
59
59
  with pytest.raises(
60
60
  SerializationError, match="Failed to serialize data to JSON"
61
61
  ):
62
- safe_json_serialize({"obj": CustomClass()})
62
+ safe_json_serialize({"obj": CustomClass()}, 0)
63
63
 
64
64
 
65
65
  class TestSafeJsonDeserialize:
@@ -147,7 +147,7 @@ class TestCompressJsonData:
147
147
  """Test compressing larger data for better compression."""
148
148
  data = {"repeated": "data" * 100, "numbers": list(range(100))}
149
149
  compressed = compress_json_data(data)
150
- original_json = safe_json_serialize(data)
150
+ original_json = safe_json_serialize(data, 0)
151
151
 
152
152
  # Compressed should be smaller than original for repetitive data
153
153
  assert len(compressed) < len(original_json.encode("utf-8"))
@@ -226,7 +226,7 @@ class TestRoundTripSerialization:
226
226
  ]
227
227
 
228
228
  for original in test_cases:
229
- serialized = safe_json_serialize(original)
229
+ serialized = safe_json_serialize(original, 0)
230
230
  deserialized = safe_json_deserialize(serialized)
231
231
  assert deserialized == original
232
232