genxai-framework 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 (156) hide show
  1. cli/__init__.py +3 -0
  2. cli/commands/__init__.py +6 -0
  3. cli/commands/approval.py +85 -0
  4. cli/commands/audit.py +127 -0
  5. cli/commands/metrics.py +25 -0
  6. cli/commands/tool.py +389 -0
  7. cli/main.py +32 -0
  8. genxai/__init__.py +81 -0
  9. genxai/api/__init__.py +5 -0
  10. genxai/api/app.py +21 -0
  11. genxai/config/__init__.py +5 -0
  12. genxai/config/settings.py +37 -0
  13. genxai/connectors/__init__.py +19 -0
  14. genxai/connectors/base.py +122 -0
  15. genxai/connectors/kafka.py +92 -0
  16. genxai/connectors/postgres_cdc.py +95 -0
  17. genxai/connectors/registry.py +44 -0
  18. genxai/connectors/sqs.py +94 -0
  19. genxai/connectors/webhook.py +73 -0
  20. genxai/core/__init__.py +37 -0
  21. genxai/core/agent/__init__.py +32 -0
  22. genxai/core/agent/base.py +206 -0
  23. genxai/core/agent/config_io.py +59 -0
  24. genxai/core/agent/registry.py +98 -0
  25. genxai/core/agent/runtime.py +970 -0
  26. genxai/core/communication/__init__.py +6 -0
  27. genxai/core/communication/collaboration.py +44 -0
  28. genxai/core/communication/message_bus.py +192 -0
  29. genxai/core/communication/protocols.py +35 -0
  30. genxai/core/execution/__init__.py +22 -0
  31. genxai/core/execution/metadata.py +181 -0
  32. genxai/core/execution/queue.py +201 -0
  33. genxai/core/graph/__init__.py +30 -0
  34. genxai/core/graph/checkpoints.py +77 -0
  35. genxai/core/graph/edges.py +131 -0
  36. genxai/core/graph/engine.py +813 -0
  37. genxai/core/graph/executor.py +516 -0
  38. genxai/core/graph/nodes.py +161 -0
  39. genxai/core/graph/trigger_runner.py +40 -0
  40. genxai/core/memory/__init__.py +19 -0
  41. genxai/core/memory/base.py +72 -0
  42. genxai/core/memory/embedding.py +327 -0
  43. genxai/core/memory/episodic.py +448 -0
  44. genxai/core/memory/long_term.py +467 -0
  45. genxai/core/memory/manager.py +543 -0
  46. genxai/core/memory/persistence.py +297 -0
  47. genxai/core/memory/procedural.py +461 -0
  48. genxai/core/memory/semantic.py +526 -0
  49. genxai/core/memory/shared.py +62 -0
  50. genxai/core/memory/short_term.py +303 -0
  51. genxai/core/memory/vector_store.py +508 -0
  52. genxai/core/memory/working.py +211 -0
  53. genxai/core/state/__init__.py +6 -0
  54. genxai/core/state/manager.py +293 -0
  55. genxai/core/state/schema.py +115 -0
  56. genxai/llm/__init__.py +14 -0
  57. genxai/llm/base.py +150 -0
  58. genxai/llm/factory.py +329 -0
  59. genxai/llm/providers/__init__.py +1 -0
  60. genxai/llm/providers/anthropic.py +249 -0
  61. genxai/llm/providers/cohere.py +274 -0
  62. genxai/llm/providers/google.py +334 -0
  63. genxai/llm/providers/ollama.py +147 -0
  64. genxai/llm/providers/openai.py +257 -0
  65. genxai/llm/routing.py +83 -0
  66. genxai/observability/__init__.py +6 -0
  67. genxai/observability/logging.py +327 -0
  68. genxai/observability/metrics.py +494 -0
  69. genxai/observability/tracing.py +372 -0
  70. genxai/performance/__init__.py +39 -0
  71. genxai/performance/cache.py +256 -0
  72. genxai/performance/pooling.py +289 -0
  73. genxai/security/audit.py +304 -0
  74. genxai/security/auth.py +315 -0
  75. genxai/security/cost_control.py +528 -0
  76. genxai/security/default_policies.py +44 -0
  77. genxai/security/jwt.py +142 -0
  78. genxai/security/oauth.py +226 -0
  79. genxai/security/pii.py +366 -0
  80. genxai/security/policy_engine.py +82 -0
  81. genxai/security/rate_limit.py +341 -0
  82. genxai/security/rbac.py +247 -0
  83. genxai/security/validation.py +218 -0
  84. genxai/tools/__init__.py +21 -0
  85. genxai/tools/base.py +383 -0
  86. genxai/tools/builtin/__init__.py +131 -0
  87. genxai/tools/builtin/communication/__init__.py +15 -0
  88. genxai/tools/builtin/communication/email_sender.py +159 -0
  89. genxai/tools/builtin/communication/notification_manager.py +167 -0
  90. genxai/tools/builtin/communication/slack_notifier.py +118 -0
  91. genxai/tools/builtin/communication/sms_sender.py +118 -0
  92. genxai/tools/builtin/communication/webhook_caller.py +136 -0
  93. genxai/tools/builtin/computation/__init__.py +15 -0
  94. genxai/tools/builtin/computation/calculator.py +101 -0
  95. genxai/tools/builtin/computation/code_executor.py +183 -0
  96. genxai/tools/builtin/computation/data_validator.py +259 -0
  97. genxai/tools/builtin/computation/hash_generator.py +129 -0
  98. genxai/tools/builtin/computation/regex_matcher.py +201 -0
  99. genxai/tools/builtin/data/__init__.py +15 -0
  100. genxai/tools/builtin/data/csv_processor.py +213 -0
  101. genxai/tools/builtin/data/data_transformer.py +299 -0
  102. genxai/tools/builtin/data/json_processor.py +233 -0
  103. genxai/tools/builtin/data/text_analyzer.py +288 -0
  104. genxai/tools/builtin/data/xml_processor.py +175 -0
  105. genxai/tools/builtin/database/__init__.py +15 -0
  106. genxai/tools/builtin/database/database_inspector.py +157 -0
  107. genxai/tools/builtin/database/mongodb_query.py +196 -0
  108. genxai/tools/builtin/database/redis_cache.py +167 -0
  109. genxai/tools/builtin/database/sql_query.py +145 -0
  110. genxai/tools/builtin/database/vector_search.py +163 -0
  111. genxai/tools/builtin/file/__init__.py +17 -0
  112. genxai/tools/builtin/file/directory_scanner.py +214 -0
  113. genxai/tools/builtin/file/file_compressor.py +237 -0
  114. genxai/tools/builtin/file/file_reader.py +102 -0
  115. genxai/tools/builtin/file/file_writer.py +122 -0
  116. genxai/tools/builtin/file/image_processor.py +186 -0
  117. genxai/tools/builtin/file/pdf_parser.py +144 -0
  118. genxai/tools/builtin/test/__init__.py +15 -0
  119. genxai/tools/builtin/test/async_simulator.py +62 -0
  120. genxai/tools/builtin/test/data_transformer.py +99 -0
  121. genxai/tools/builtin/test/error_generator.py +82 -0
  122. genxai/tools/builtin/test/simple_math.py +94 -0
  123. genxai/tools/builtin/test/string_processor.py +72 -0
  124. genxai/tools/builtin/web/__init__.py +15 -0
  125. genxai/tools/builtin/web/api_caller.py +161 -0
  126. genxai/tools/builtin/web/html_parser.py +330 -0
  127. genxai/tools/builtin/web/http_client.py +187 -0
  128. genxai/tools/builtin/web/url_validator.py +162 -0
  129. genxai/tools/builtin/web/web_scraper.py +170 -0
  130. genxai/tools/custom/my_test_tool_2.py +9 -0
  131. genxai/tools/dynamic.py +105 -0
  132. genxai/tools/mcp_server.py +167 -0
  133. genxai/tools/persistence/__init__.py +6 -0
  134. genxai/tools/persistence/models.py +55 -0
  135. genxai/tools/persistence/service.py +322 -0
  136. genxai/tools/registry.py +227 -0
  137. genxai/tools/security/__init__.py +11 -0
  138. genxai/tools/security/limits.py +214 -0
  139. genxai/tools/security/policy.py +20 -0
  140. genxai/tools/security/sandbox.py +248 -0
  141. genxai/tools/templates.py +435 -0
  142. genxai/triggers/__init__.py +19 -0
  143. genxai/triggers/base.py +104 -0
  144. genxai/triggers/file_watcher.py +75 -0
  145. genxai/triggers/queue.py +68 -0
  146. genxai/triggers/registry.py +82 -0
  147. genxai/triggers/schedule.py +66 -0
  148. genxai/triggers/webhook.py +68 -0
  149. genxai/utils/__init__.py +1 -0
  150. genxai/utils/tokens.py +295 -0
  151. genxai_framework-0.1.0.dist-info/METADATA +495 -0
  152. genxai_framework-0.1.0.dist-info/RECORD +156 -0
  153. genxai_framework-0.1.0.dist-info/WHEEL +5 -0
  154. genxai_framework-0.1.0.dist-info/entry_points.txt +2 -0
  155. genxai_framework-0.1.0.dist-info/licenses/LICENSE +21 -0
  156. genxai_framework-0.1.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,259 @@
1
+ """Data validator tool for validating data against schemas and rules."""
2
+
3
+ from typing import Any, Dict, List, Optional
4
+ import logging
5
+ import re
6
+
7
+ from genxai.tools.base import Tool, ToolMetadata, ToolParameter, ToolCategory
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ class DataValidatorTool(Tool):
13
+ """Validate data against schemas, patterns, and custom rules."""
14
+
15
+ def __init__(self) -> None:
16
+ """Initialize data validator tool."""
17
+ metadata = ToolMetadata(
18
+ name="data_validator",
19
+ description="Validate data types, formats, ranges, and patterns",
20
+ category=ToolCategory.COMPUTATION,
21
+ tags=["validation", "schema", "data", "rules", "constraints"],
22
+ version="1.0.0",
23
+ )
24
+
25
+ parameters = [
26
+ ToolParameter(
27
+ name="data",
28
+ type="string",
29
+ description="Data to validate",
30
+ required=True,
31
+ ),
32
+ ToolParameter(
33
+ name="validation_type",
34
+ type="string",
35
+ description="Type of validation to perform",
36
+ required=True,
37
+ enum=[
38
+ "email",
39
+ "url",
40
+ "phone",
41
+ "ip",
42
+ "date",
43
+ "number",
44
+ "json",
45
+ "custom_regex",
46
+ ],
47
+ ),
48
+ ToolParameter(
49
+ name="custom_pattern",
50
+ type="string",
51
+ description="Custom regex pattern (for custom_regex type)",
52
+ required=False,
53
+ ),
54
+ ToolParameter(
55
+ name="min_value",
56
+ type="number",
57
+ description="Minimum value (for number validation)",
58
+ required=False,
59
+ ),
60
+ ToolParameter(
61
+ name="max_value",
62
+ type="number",
63
+ description="Maximum value (for number validation)",
64
+ required=False,
65
+ ),
66
+ ]
67
+
68
+ super().__init__(metadata, parameters)
69
+
70
+ async def _execute(
71
+ self,
72
+ data: str,
73
+ validation_type: str,
74
+ custom_pattern: Optional[str] = None,
75
+ min_value: Optional[float] = None,
76
+ max_value: Optional[float] = None,
77
+ ) -> Dict[str, Any]:
78
+ """Execute data validation.
79
+
80
+ Args:
81
+ data: Data to validate
82
+ validation_type: Type of validation
83
+ custom_pattern: Custom regex pattern
84
+ min_value: Minimum value
85
+ max_value: Maximum value
86
+
87
+ Returns:
88
+ Dictionary containing validation results
89
+ """
90
+ result: Dict[str, Any] = {
91
+ "validation_type": validation_type,
92
+ "data": data,
93
+ "valid": False,
94
+ }
95
+
96
+ try:
97
+ if validation_type == "email":
98
+ result.update(self._validate_email(data))
99
+
100
+ elif validation_type == "url":
101
+ result.update(self._validate_url(data))
102
+
103
+ elif validation_type == "phone":
104
+ result.update(self._validate_phone(data))
105
+
106
+ elif validation_type == "ip":
107
+ result.update(self._validate_ip(data))
108
+
109
+ elif validation_type == "date":
110
+ result.update(self._validate_date(data))
111
+
112
+ elif validation_type == "number":
113
+ result.update(self._validate_number(data, min_value, max_value))
114
+
115
+ elif validation_type == "custom_regex":
116
+ if not custom_pattern:
117
+ raise ValueError("custom_pattern required for custom_regex validation")
118
+ result.update(self._validate_custom_regex(data, custom_pattern))
119
+
120
+ elif validation_type == "json":
121
+ result.update(self._validate_json(data))
122
+
123
+ except Exception as e:
124
+ result["error"] = str(e)
125
+
126
+ logger.info(
127
+ f"Data validation ({validation_type}) completed: valid={result.get('valid', False)}"
128
+ )
129
+ return result
130
+
131
+ def _validate_json(self, data: str) -> Dict[str, Any]:
132
+ """Validate JSON."""
133
+ import json
134
+
135
+ try:
136
+ parsed = json.loads(data)
137
+ return {
138
+ "valid": True,
139
+ "format": "json",
140
+ "parsed_type": type(parsed).__name__,
141
+ }
142
+ except Exception as e:
143
+ return {
144
+ "valid": False,
145
+ "format": "json",
146
+ "error": f"Invalid JSON: {e}",
147
+ }
148
+
149
+ def _validate_email(self, data: str) -> Dict[str, Any]:
150
+ """Validate email address."""
151
+ pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
152
+ match = re.match(pattern, data)
153
+ return {
154
+ "valid": bool(match),
155
+ "format": "email",
156
+ }
157
+
158
+ def _validate_url(self, data: str) -> Dict[str, Any]:
159
+ """Validate URL."""
160
+ pattern = r'^https?://[^\s/$.?#].[^\s]*$'
161
+ match = re.match(pattern, data, re.IGNORECASE)
162
+ return {
163
+ "valid": bool(match),
164
+ "format": "url",
165
+ }
166
+
167
+ def _validate_phone(self, data: str) -> Dict[str, Any]:
168
+ """Validate phone number."""
169
+ # Remove common separators
170
+ cleaned = re.sub(r'[\s\-\(\)\.]', '', data)
171
+ # Check if it's all digits and reasonable length
172
+ valid = cleaned.isdigit() and 10 <= len(cleaned) <= 15
173
+ return {
174
+ "valid": valid,
175
+ "format": "phone",
176
+ "cleaned": cleaned if valid else None,
177
+ }
178
+
179
+ def _validate_ip(self, data: str) -> Dict[str, Any]:
180
+ """Validate IP address (IPv4)."""
181
+ pattern = r'^(\d{1,3}\.){3}\d{1,3}$'
182
+ if not re.match(pattern, data):
183
+ return {"valid": False, "format": "ipv4"}
184
+
185
+ # Check each octet is 0-255
186
+ octets = data.split('.')
187
+ valid = all(0 <= int(octet) <= 255 for octet in octets)
188
+
189
+ return {
190
+ "valid": valid,
191
+ "format": "ipv4",
192
+ "octets": octets if valid else None,
193
+ }
194
+
195
+ def _validate_date(self, data: str) -> Dict[str, Any]:
196
+ """Validate date format."""
197
+ # Common date patterns
198
+ patterns = [
199
+ (r'^\d{4}-\d{2}-\d{2}$', 'YYYY-MM-DD'),
200
+ (r'^\d{2}/\d{2}/\d{4}$', 'MM/DD/YYYY'),
201
+ (r'^\d{2}-\d{2}-\d{4}$', 'DD-MM-YYYY'),
202
+ ]
203
+
204
+ for pattern, format_name in patterns:
205
+ if re.match(pattern, data):
206
+ return {
207
+ "valid": True,
208
+ "format": format_name,
209
+ }
210
+
211
+ return {
212
+ "valid": False,
213
+ "format": "unknown",
214
+ }
215
+
216
+ def _validate_number(
217
+ self, data: str, min_value: Optional[float], max_value: Optional[float]
218
+ ) -> Dict[str, Any]:
219
+ """Validate number and range."""
220
+ try:
221
+ number = float(data)
222
+
223
+ # Check range
224
+ in_range = True
225
+ if min_value is not None and number < min_value:
226
+ in_range = False
227
+ if max_value is not None and number > max_value:
228
+ in_range = False
229
+
230
+ return {
231
+ "valid": in_range,
232
+ "format": "number",
233
+ "value": number,
234
+ "in_range": in_range,
235
+ "is_integer": number.is_integer(),
236
+ }
237
+ except ValueError:
238
+ return {
239
+ "valid": False,
240
+ "format": "number",
241
+ "error": "Not a valid number",
242
+ }
243
+
244
+ def _validate_custom_regex(self, data: str, pattern: str) -> Dict[str, Any]:
245
+ """Validate against custom regex pattern."""
246
+ try:
247
+ match = re.match(pattern, data)
248
+ return {
249
+ "valid": bool(match),
250
+ "format": "custom_regex",
251
+ "pattern": pattern,
252
+ "matched": match.group(0) if match else None,
253
+ }
254
+ except re.error as e:
255
+ return {
256
+ "valid": False,
257
+ "format": "custom_regex",
258
+ "error": f"Invalid regex pattern: {str(e)}",
259
+ }
@@ -0,0 +1,129 @@
1
+ """Hash generator tool for creating cryptographic hashes."""
2
+
3
+ from typing import Any, Dict
4
+ import logging
5
+ import hashlib
6
+ import hmac
7
+ import base64
8
+
9
+ from genxai.tools.base import Tool, ToolMetadata, ToolParameter, ToolCategory
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class HashGeneratorTool(Tool):
15
+ """Generate cryptographic hashes and HMACs."""
16
+
17
+ def __init__(self) -> None:
18
+ """Initialize hash generator tool."""
19
+ metadata = ToolMetadata(
20
+ name="hash_generator",
21
+ description="Generate cryptographic hashes (MD5, SHA1, SHA256, SHA512) and HMACs",
22
+ category=ToolCategory.COMPUTATION,
23
+ tags=["hash", "crypto", "md5", "sha", "hmac", "checksum"],
24
+ version="1.0.0",
25
+ )
26
+
27
+ parameters = [
28
+ ToolParameter(
29
+ name="data",
30
+ type="string",
31
+ description="Data to hash",
32
+ required=True,
33
+ ),
34
+ ToolParameter(
35
+ name="algorithm",
36
+ type="string",
37
+ description="Hash algorithm",
38
+ required=True,
39
+ enum=["md5", "sha1", "sha256", "sha512", "sha3_256", "sha3_512", "blake2b", "blake2s"],
40
+ ),
41
+ ToolParameter(
42
+ name="encoding",
43
+ type="string",
44
+ description="Input data encoding",
45
+ required=False,
46
+ default="utf-8",
47
+ enum=["utf-8", "ascii", "latin-1"],
48
+ ),
49
+ ToolParameter(
50
+ name="output_format",
51
+ type="string",
52
+ description="Output format",
53
+ required=False,
54
+ default="hex",
55
+ enum=["hex", "base64"],
56
+ ),
57
+ ToolParameter(
58
+ name="hmac_key",
59
+ type="string",
60
+ description="HMAC key (if provided, generates HMAC instead of hash)",
61
+ required=False,
62
+ ),
63
+ ]
64
+
65
+ super().__init__(metadata, parameters)
66
+
67
+ async def _execute(
68
+ self,
69
+ data: str,
70
+ algorithm: str,
71
+ encoding: str = "utf-8",
72
+ output_format: str = "hex",
73
+ hmac_key: str = None,
74
+ ) -> Dict[str, Any]:
75
+ """Execute hash generation.
76
+
77
+ Args:
78
+ data: Data to hash
79
+ algorithm: Hash algorithm
80
+ encoding: Input encoding
81
+ output_format: Output format
82
+ hmac_key: HMAC key (optional)
83
+
84
+ Returns:
85
+ Dictionary containing hash results
86
+ """
87
+ result: Dict[str, Any] = {
88
+ "algorithm": algorithm,
89
+ "output_format": output_format,
90
+ "success": False,
91
+ }
92
+
93
+ try:
94
+ # Encode data
95
+ data_bytes = data.encode(encoding)
96
+
97
+ # Generate hash or HMAC
98
+ if hmac_key:
99
+ # Generate HMAC
100
+ key_bytes = hmac_key.encode(encoding)
101
+ hash_obj = hmac.new(key_bytes, data_bytes, algorithm)
102
+ result["type"] = "hmac"
103
+ else:
104
+ # Generate regular hash
105
+ hash_obj = hashlib.new(algorithm, data_bytes)
106
+ result["type"] = "hash"
107
+
108
+ # Format output
109
+ if output_format == "hex":
110
+ hash_value = hash_obj.hexdigest()
111
+ elif output_format == "base64":
112
+ hash_value = base64.b64encode(hash_obj.digest()).decode("ascii")
113
+ else:
114
+ hash_value = hash_obj.hexdigest()
115
+
116
+ result.update({
117
+ "hash": hash_value,
118
+ "length": len(hash_value),
119
+ "input_length": len(data),
120
+ "success": True,
121
+ })
122
+
123
+ except ValueError as e:
124
+ result["error"] = f"Invalid algorithm: {str(e)}"
125
+ except Exception as e:
126
+ result["error"] = str(e)
127
+
128
+ logger.info(f"Hash generation ({algorithm}) completed: success={result['success']}")
129
+ return result
@@ -0,0 +1,201 @@
1
+ """Regex matcher tool for pattern matching and extraction."""
2
+
3
+ from typing import Any, Dict, List, Optional
4
+ import logging
5
+ import re
6
+
7
+ from genxai.tools.base import Tool, ToolMetadata, ToolParameter, ToolCategory
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ class RegexMatcherTool(Tool):
13
+ """Match, search, and extract patterns using regular expressions."""
14
+
15
+ def __init__(self) -> None:
16
+ """Initialize regex matcher tool."""
17
+ metadata = ToolMetadata(
18
+ name="regex_matcher",
19
+ description="Match, search, and extract patterns using regular expressions",
20
+ category=ToolCategory.COMPUTATION,
21
+ tags=["regex", "pattern", "matching", "extraction", "search"],
22
+ version="1.0.0",
23
+ )
24
+
25
+ parameters = [
26
+ ToolParameter(
27
+ name="text",
28
+ type="string",
29
+ description="Text to search in",
30
+ required=True,
31
+ ),
32
+ ToolParameter(
33
+ name="pattern",
34
+ type="string",
35
+ description="Regular expression pattern",
36
+ required=True,
37
+ ),
38
+ ToolParameter(
39
+ name="operation",
40
+ type="string",
41
+ description="Operation to perform",
42
+ required=False,
43
+ default="findall",
44
+ enum=["match", "search", "findall", "finditer", "sub", "split"],
45
+ ),
46
+ ToolParameter(
47
+ name="replacement",
48
+ type="string",
49
+ description="Replacement string (for sub operation)",
50
+ required=False,
51
+ ),
52
+ ToolParameter(
53
+ name="flags",
54
+ type="string",
55
+ description="Regex flags (comma-separated: IGNORECASE,MULTILINE,DOTALL)",
56
+ required=False,
57
+ ),
58
+ ]
59
+
60
+ super().__init__(metadata, parameters)
61
+
62
+ async def _execute(
63
+ self,
64
+ text: str,
65
+ pattern: str,
66
+ operation: str = "findall",
67
+ replacement: Optional[str] = None,
68
+ flags: Optional[str] = None,
69
+ ) -> Dict[str, Any]:
70
+ """Execute regex operation.
71
+
72
+ Args:
73
+ text: Text to search
74
+ pattern: Regex pattern
75
+ operation: Operation to perform
76
+ replacement: Replacement string
77
+ flags: Regex flags
78
+
79
+ Returns:
80
+ Dictionary containing operation results
81
+ """
82
+ result: Dict[str, Any] = {
83
+ "operation": operation,
84
+ "pattern": pattern,
85
+ "success": False,
86
+ }
87
+
88
+ try:
89
+ # Parse flags
90
+ regex_flags = self._parse_flags(flags)
91
+
92
+ # Compile pattern
93
+ compiled_pattern = re.compile(pattern, regex_flags)
94
+
95
+ if operation == "match":
96
+ match = compiled_pattern.match(text)
97
+ if match:
98
+ result.update({
99
+ "matched": True,
100
+ "match": match.group(0),
101
+ "groups": match.groups(),
102
+ "groupdict": match.groupdict(),
103
+ "span": match.span(),
104
+ })
105
+ else:
106
+ result["matched"] = False
107
+
108
+ elif operation == "search":
109
+ match = compiled_pattern.search(text)
110
+ if match:
111
+ result.update({
112
+ "found": True,
113
+ "match": match.group(0),
114
+ "groups": match.groups(),
115
+ "groupdict": match.groupdict(),
116
+ "span": match.span(),
117
+ })
118
+ else:
119
+ result["found"] = False
120
+
121
+ elif operation == "findall":
122
+ matches = compiled_pattern.findall(text)
123
+ result.update({
124
+ "matches": matches,
125
+ "count": len(matches),
126
+ })
127
+
128
+ elif operation == "finditer":
129
+ matches = []
130
+ for match in compiled_pattern.finditer(text):
131
+ matches.append({
132
+ "match": match.group(0),
133
+ "groups": match.groups(),
134
+ "groupdict": match.groupdict(),
135
+ "span": match.span(),
136
+ })
137
+ result.update({
138
+ "matches": matches,
139
+ "count": len(matches),
140
+ })
141
+
142
+ elif operation == "sub":
143
+ if replacement is None:
144
+ raise ValueError("replacement parameter required for sub operation")
145
+
146
+ new_text = compiled_pattern.sub(replacement, text)
147
+ result.update({
148
+ "original_text": text,
149
+ "new_text": new_text,
150
+ "replacements_made": text != new_text,
151
+ })
152
+
153
+ elif operation == "split":
154
+ parts = compiled_pattern.split(text)
155
+ result.update({
156
+ "parts": parts,
157
+ "count": len(parts),
158
+ })
159
+
160
+ result["success"] = True
161
+
162
+ except re.error as e:
163
+ result["error"] = f"Invalid regex pattern: {str(e)}"
164
+ except Exception as e:
165
+ result["error"] = str(e)
166
+
167
+ logger.info(f"Regex {operation} completed: success={result['success']}")
168
+ return result
169
+
170
+ def _parse_flags(self, flags: Optional[str]) -> int:
171
+ """Parse regex flags from string.
172
+
173
+ Args:
174
+ flags: Comma-separated flag names
175
+
176
+ Returns:
177
+ Combined regex flags
178
+ """
179
+ if not flags:
180
+ return 0
181
+
182
+ flag_map = {
183
+ "IGNORECASE": re.IGNORECASE,
184
+ "I": re.IGNORECASE,
185
+ "MULTILINE": re.MULTILINE,
186
+ "M": re.MULTILINE,
187
+ "DOTALL": re.DOTALL,
188
+ "S": re.DOTALL,
189
+ "VERBOSE": re.VERBOSE,
190
+ "X": re.VERBOSE,
191
+ "ASCII": re.ASCII,
192
+ "A": re.ASCII,
193
+ }
194
+
195
+ combined_flags = 0
196
+ for flag_name in flags.upper().split(","):
197
+ flag_name = flag_name.strip()
198
+ if flag_name in flag_map:
199
+ combined_flags |= flag_map[flag_name]
200
+
201
+ return combined_flags
@@ -0,0 +1,15 @@
1
+ """Data processing tools for GenXAI."""
2
+
3
+ from genxai.tools.builtin.data.json_processor import JSONProcessorTool
4
+ from genxai.tools.builtin.data.csv_processor import CSVProcessorTool
5
+ from genxai.tools.builtin.data.xml_processor import XMLProcessorTool
6
+ from genxai.tools.builtin.data.data_transformer import DataTransformerTool
7
+ from genxai.tools.builtin.data.text_analyzer import TextAnalyzerTool
8
+
9
+ __all__ = [
10
+ "JSONProcessorTool",
11
+ "CSVProcessorTool",
12
+ "XMLProcessorTool",
13
+ "DataTransformerTool",
14
+ "TextAnalyzerTool",
15
+ ]