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,131 @@
1
+ """Built-in tools for GenXAI."""
2
+
3
+ from genxai.tools.registry import ToolRegistry
4
+
5
+ # Import all tools to trigger registration
6
+ # Computation tools
7
+ from genxai.tools.builtin.computation.calculator import CalculatorTool
8
+ from genxai.tools.builtin.computation.code_executor import CodeExecutorTool
9
+ from genxai.tools.builtin.computation.data_validator import DataValidatorTool
10
+ from genxai.tools.builtin.computation.hash_generator import HashGeneratorTool
11
+ from genxai.tools.builtin.computation.regex_matcher import RegexMatcherTool
12
+
13
+ # File tools
14
+ from genxai.tools.builtin.file.file_reader import FileReaderTool
15
+ from genxai.tools.builtin.file.file_writer import FileWriterTool
16
+ from genxai.tools.builtin.file.directory_scanner import DirectoryScannerTool
17
+ from genxai.tools.builtin.file.file_compressor import FileCompressorTool
18
+ from genxai.tools.builtin.file.image_processor import ImageProcessorTool
19
+ from genxai.tools.builtin.file.pdf_parser import PDFParserTool
20
+
21
+ # Web tools
22
+ from genxai.tools.builtin.web.web_scraper import WebScraperTool
23
+ from genxai.tools.builtin.web.api_caller import APICallerTool
24
+ from genxai.tools.builtin.web.http_client import HTTPClientTool
25
+ from genxai.tools.builtin.web.html_parser import HTMLParserTool
26
+ from genxai.tools.builtin.web.url_validator import URLValidatorTool
27
+
28
+ # Database tools
29
+ from genxai.tools.builtin.database.sql_query import SQLQueryTool
30
+ from genxai.tools.builtin.database.mongodb_query import MongoDBQueryTool
31
+ from genxai.tools.builtin.database.redis_cache import RedisCacheTool
32
+ from genxai.tools.builtin.database.vector_search import VectorSearchTool
33
+ from genxai.tools.builtin.database.database_inspector import DatabaseInspectorTool
34
+
35
+ # Communication tools
36
+ from genxai.tools.builtin.communication.email_sender import EmailSenderTool
37
+ from genxai.tools.builtin.communication.slack_notifier import SlackNotifierTool
38
+ from genxai.tools.builtin.communication.sms_sender import SMSSenderTool
39
+ from genxai.tools.builtin.communication.webhook_caller import WebhookCallerTool
40
+ from genxai.tools.builtin.communication.notification_manager import NotificationManagerTool
41
+
42
+ # Data tools
43
+ from genxai.tools.builtin.data.json_processor import JSONProcessorTool
44
+ from genxai.tools.builtin.data.csv_processor import CSVProcessorTool
45
+ from genxai.tools.builtin.data.xml_processor import XMLProcessorTool
46
+ from genxai.tools.builtin.data.text_analyzer import TextAnalyzerTool
47
+ from genxai.tools.builtin.data.data_transformer import DataTransformerTool
48
+
49
+ # Auto-register all tools
50
+ _tools_to_register = [
51
+ # Computation
52
+ CalculatorTool(),
53
+ CodeExecutorTool(),
54
+ DataValidatorTool(),
55
+ HashGeneratorTool(),
56
+ RegexMatcherTool(),
57
+ # File
58
+ FileReaderTool(),
59
+ FileWriterTool(),
60
+ DirectoryScannerTool(),
61
+ FileCompressorTool(),
62
+ ImageProcessorTool(),
63
+ PDFParserTool(),
64
+ # Web
65
+ WebScraperTool(),
66
+ APICallerTool(),
67
+ HTTPClientTool(),
68
+ HTMLParserTool(),
69
+ URLValidatorTool(),
70
+ # Database
71
+ SQLQueryTool(),
72
+ MongoDBQueryTool(),
73
+ RedisCacheTool(),
74
+ VectorSearchTool(),
75
+ DatabaseInspectorTool(),
76
+ # Communication
77
+ EmailSenderTool(),
78
+ SlackNotifierTool(),
79
+ SMSSenderTool(),
80
+ WebhookCallerTool(),
81
+ NotificationManagerTool(),
82
+ # Data
83
+ JSONProcessorTool(),
84
+ CSVProcessorTool(),
85
+ XMLProcessorTool(),
86
+ TextAnalyzerTool(),
87
+ DataTransformerTool(),
88
+ ]
89
+
90
+ # Register all tools
91
+ for tool in _tools_to_register:
92
+ try:
93
+ ToolRegistry.register(tool)
94
+ except Exception as e:
95
+ # Log but don't fail if a tool can't be registered
96
+ import logging
97
+ logging.warning(f"Failed to register tool {tool.metadata.name}: {e}")
98
+
99
+ __all__ = [
100
+ "CalculatorTool",
101
+ "CodeExecutorTool",
102
+ "DataValidatorTool",
103
+ "HashGeneratorTool",
104
+ "RegexMatcherTool",
105
+ "FileReaderTool",
106
+ "FileWriterTool",
107
+ "DirectoryScannerTool",
108
+ "FileCompressorTool",
109
+ "ImageProcessorTool",
110
+ "PDFParserTool",
111
+ "WebScraperTool",
112
+ "APICallerTool",
113
+ "HTTPClientTool",
114
+ "HTMLParserTool",
115
+ "URLValidatorTool",
116
+ "SQLQueryTool",
117
+ "MongoDBQueryTool",
118
+ "RedisCacheTool",
119
+ "VectorSearchTool",
120
+ "DatabaseInspectorTool",
121
+ "EmailSenderTool",
122
+ "SlackNotifierTool",
123
+ "SMSSenderTool",
124
+ "WebhookCallerTool",
125
+ "NotificationManagerTool",
126
+ "JSONProcessorTool",
127
+ "CSVProcessorTool",
128
+ "XMLProcessorTool",
129
+ "TextAnalyzerTool",
130
+ "DataTransformerTool",
131
+ ]
@@ -0,0 +1,15 @@
1
+ """Communication tools for GenXAI."""
2
+
3
+ from genxai.tools.builtin.communication.email_sender import EmailSenderTool
4
+ from genxai.tools.builtin.communication.slack_notifier import SlackNotifierTool
5
+ from genxai.tools.builtin.communication.webhook_caller import WebhookCallerTool
6
+ from genxai.tools.builtin.communication.sms_sender import SMSSenderTool
7
+ from genxai.tools.builtin.communication.notification_manager import NotificationManagerTool
8
+
9
+ __all__ = [
10
+ "EmailSenderTool",
11
+ "SlackNotifierTool",
12
+ "WebhookCallerTool",
13
+ "SMSSenderTool",
14
+ "NotificationManagerTool",
15
+ ]
@@ -0,0 +1,159 @@
1
+ """Email sender tool for sending emails via SMTP."""
2
+
3
+ from typing import Any, Dict, List, Optional
4
+ import logging
5
+
6
+ from genxai.tools.base import Tool, ToolMetadata, ToolParameter, ToolCategory
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ class EmailSenderTool(Tool):
12
+ """Send emails via SMTP with support for HTML and attachments."""
13
+
14
+ def __init__(self) -> None:
15
+ """Initialize email sender tool."""
16
+ metadata = ToolMetadata(
17
+ name="email_sender",
18
+ description="Send emails via SMTP with HTML support and attachments",
19
+ category=ToolCategory.COMMUNICATION,
20
+ tags=["email", "smtp", "communication", "notification", "message"],
21
+ version="1.0.0",
22
+ )
23
+
24
+ parameters = [
25
+ ToolParameter(
26
+ name="to",
27
+ type="string",
28
+ description="Recipient email address",
29
+ required=True,
30
+ ),
31
+ ToolParameter(
32
+ name="subject",
33
+ type="string",
34
+ description="Email subject",
35
+ required=True,
36
+ ),
37
+ ToolParameter(
38
+ name="body",
39
+ type="string",
40
+ description="Email body content",
41
+ required=True,
42
+ ),
43
+ ToolParameter(
44
+ name="from_email",
45
+ type="string",
46
+ description="Sender email address",
47
+ required=True,
48
+ ),
49
+ ToolParameter(
50
+ name="smtp_host",
51
+ type="string",
52
+ description="SMTP server host",
53
+ required=True,
54
+ ),
55
+ ToolParameter(
56
+ name="smtp_port",
57
+ type="number",
58
+ description="SMTP server port",
59
+ required=False,
60
+ default=587,
61
+ ),
62
+ ToolParameter(
63
+ name="username",
64
+ type="string",
65
+ description="SMTP username",
66
+ required=False,
67
+ ),
68
+ ToolParameter(
69
+ name="password",
70
+ type="string",
71
+ description="SMTP password",
72
+ required=False,
73
+ ),
74
+ ToolParameter(
75
+ name="html",
76
+ type="boolean",
77
+ description="Whether body is HTML",
78
+ required=False,
79
+ default=False,
80
+ ),
81
+ ]
82
+
83
+ super().__init__(metadata, parameters)
84
+
85
+ async def _execute(
86
+ self,
87
+ to: str,
88
+ subject: str,
89
+ body: str,
90
+ from_email: str,
91
+ smtp_host: str,
92
+ smtp_port: int = 587,
93
+ username: Optional[str] = None,
94
+ password: Optional[str] = None,
95
+ html: bool = False,
96
+ ) -> Dict[str, Any]:
97
+ """Execute email sending.
98
+
99
+ Args:
100
+ to: Recipient email
101
+ subject: Email subject
102
+ body: Email body
103
+ from_email: Sender email
104
+ smtp_host: SMTP host
105
+ smtp_port: SMTP port
106
+ username: SMTP username
107
+ password: SMTP password
108
+ html: HTML flag
109
+
110
+ Returns:
111
+ Dictionary containing send results
112
+ """
113
+ try:
114
+ import aiosmtplib
115
+ from email.mime.text import MIMEText
116
+ from email.mime.multipart import MIMEMultipart
117
+ except ImportError:
118
+ raise ImportError(
119
+ "aiosmtplib package not installed. Install with: pip install aiosmtplib"
120
+ )
121
+
122
+ result: Dict[str, Any] = {
123
+ "to": to,
124
+ "subject": subject,
125
+ "success": False,
126
+ }
127
+
128
+ try:
129
+ # Create message
130
+ if html:
131
+ message = MIMEMultipart("alternative")
132
+ message.attach(MIMEText(body, "html"))
133
+ else:
134
+ message = MIMEText(body, "plain")
135
+
136
+ message["Subject"] = subject
137
+ message["From"] = from_email
138
+ message["To"] = to
139
+
140
+ # Send email
141
+ await aiosmtplib.send(
142
+ message,
143
+ hostname=smtp_host,
144
+ port=smtp_port,
145
+ username=username,
146
+ password=password,
147
+ start_tls=True if smtp_port == 587 else False,
148
+ )
149
+
150
+ result.update({
151
+ "success": True,
152
+ "message": "Email sent successfully",
153
+ })
154
+
155
+ except Exception as e:
156
+ result["error"] = str(e)
157
+
158
+ logger.info(f"Email send completed: success={result['success']}")
159
+ return result
@@ -0,0 +1,167 @@
1
+ """Notification manager tool for multi-channel notifications."""
2
+
3
+ from typing import Any, Dict, List, Optional
4
+ import logging
5
+
6
+ from genxai.tools.base import Tool, ToolMetadata, ToolParameter, ToolCategory
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ class NotificationManagerTool(Tool):
12
+ """Manage and send notifications across multiple channels."""
13
+
14
+ def __init__(self) -> None:
15
+ """Initialize notification manager tool."""
16
+ metadata = ToolMetadata(
17
+ name="notification_manager",
18
+ description="Send notifications across multiple channels (email, Slack, webhook)",
19
+ category=ToolCategory.COMMUNICATION,
20
+ tags=["notification", "multi-channel", "alert", "messaging", "broadcast"],
21
+ version="1.0.0",
22
+ )
23
+
24
+ parameters = [
25
+ ToolParameter(
26
+ name="message",
27
+ type="string",
28
+ description="Notification message",
29
+ required=True,
30
+ ),
31
+ ToolParameter(
32
+ name="channels",
33
+ type="object",
34
+ description="Channel configurations (email, slack, webhook)",
35
+ required=True,
36
+ ),
37
+ ToolParameter(
38
+ name="priority",
39
+ type="string",
40
+ description="Notification priority",
41
+ required=False,
42
+ default="normal",
43
+ enum=["low", "normal", "high", "urgent"],
44
+ ),
45
+ ToolParameter(
46
+ name="title",
47
+ type="string",
48
+ description="Notification title/subject",
49
+ required=False,
50
+ ),
51
+ ]
52
+
53
+ super().__init__(metadata, parameters)
54
+
55
+ async def _execute(
56
+ self,
57
+ message: str,
58
+ channels: Dict[str, Any],
59
+ priority: str = "normal",
60
+ title: Optional[str] = None,
61
+ ) -> Dict[str, Any]:
62
+ """Execute multi-channel notification.
63
+
64
+ Args:
65
+ message: Notification message
66
+ channels: Channel configurations
67
+ priority: Priority level
68
+ title: Notification title
69
+
70
+ Returns:
71
+ Dictionary containing send results for all channels
72
+ """
73
+ result: Dict[str, Any] = {
74
+ "message": message,
75
+ "priority": priority,
76
+ "channels_attempted": [],
77
+ "channels_succeeded": [],
78
+ "channels_failed": [],
79
+ "success": False,
80
+ }
81
+
82
+ try:
83
+ # Process each channel
84
+ for channel_type, config in channels.items():
85
+ result["channels_attempted"].append(channel_type)
86
+
87
+ try:
88
+ if channel_type == "email":
89
+ await self._send_email(message, title, config)
90
+ result["channels_succeeded"].append(channel_type)
91
+
92
+ elif channel_type == "slack":
93
+ await self._send_slack(message, title, config)
94
+ result["channels_succeeded"].append(channel_type)
95
+
96
+ elif channel_type == "webhook":
97
+ await self._send_webhook(message, title, priority, config)
98
+ result["channels_succeeded"].append(channel_type)
99
+
100
+ else:
101
+ result["channels_failed"].append({
102
+ "channel": channel_type,
103
+ "error": "Unsupported channel type"
104
+ })
105
+
106
+ except Exception as e:
107
+ result["channels_failed"].append({
108
+ "channel": channel_type,
109
+ "error": str(e)
110
+ })
111
+
112
+ result["success"] = len(result["channels_succeeded"]) > 0
113
+
114
+ except Exception as e:
115
+ result["error"] = str(e)
116
+
117
+ logger.info(
118
+ f"Notification sent: {len(result['channels_succeeded'])}/{len(result['channels_attempted'])} channels"
119
+ )
120
+ return result
121
+
122
+ async def _send_email(self, message: str, title: Optional[str], config: Dict[str, Any]) -> None:
123
+ """Send email notification."""
124
+ # Placeholder - would integrate with EmailSenderTool
125
+ logger.info(f"Email notification sent: {title or 'Notification'}")
126
+
127
+ async def _send_slack(self, message: str, title: Optional[str], config: Dict[str, Any]) -> None:
128
+ """Send Slack notification."""
129
+ try:
130
+ import httpx
131
+ except ImportError:
132
+ raise ImportError("httpx required for Slack notifications")
133
+
134
+ webhook_url = config.get("webhook_url")
135
+ if not webhook_url:
136
+ raise ValueError("webhook_url required for Slack channel")
137
+
138
+ payload = {
139
+ "text": f"*{title}*\n{message}" if title else message
140
+ }
141
+
142
+ async with httpx.AsyncClient() as client:
143
+ response = await client.post(webhook_url, json=payload)
144
+ response.raise_for_status()
145
+
146
+ async def _send_webhook(
147
+ self, message: str, title: Optional[str], priority: str, config: Dict[str, Any]
148
+ ) -> None:
149
+ """Send webhook notification."""
150
+ try:
151
+ import httpx
152
+ except ImportError:
153
+ raise ImportError("httpx required for webhook notifications")
154
+
155
+ url = config.get("url")
156
+ if not url:
157
+ raise ValueError("url required for webhook channel")
158
+
159
+ payload = {
160
+ "message": message,
161
+ "title": title,
162
+ "priority": priority,
163
+ }
164
+
165
+ async with httpx.AsyncClient() as client:
166
+ response = await client.post(url, json=payload)
167
+ response.raise_for_status()
@@ -0,0 +1,118 @@
1
+ """Slack notifier tool for sending messages to Slack."""
2
+
3
+ from typing import Any, Dict, Optional
4
+ import logging
5
+
6
+ from genxai.tools.base import Tool, ToolMetadata, ToolParameter, ToolCategory
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ class SlackNotifierTool(Tool):
12
+ """Send notifications to Slack channels via webhook."""
13
+
14
+ def __init__(self) -> None:
15
+ """Initialize Slack notifier tool."""
16
+ metadata = ToolMetadata(
17
+ name="slack_notifier",
18
+ description="Send messages and notifications to Slack channels",
19
+ category=ToolCategory.COMMUNICATION,
20
+ tags=["slack", "notification", "webhook", "messaging", "communication"],
21
+ version="1.0.0",
22
+ )
23
+
24
+ parameters = [
25
+ ToolParameter(
26
+ name="webhook_url",
27
+ type="string",
28
+ description="Slack webhook URL",
29
+ required=True,
30
+ ),
31
+ ToolParameter(
32
+ name="message",
33
+ type="string",
34
+ description="Message text to send",
35
+ required=True,
36
+ ),
37
+ ToolParameter(
38
+ name="username",
39
+ type="string",
40
+ description="Bot username to display",
41
+ required=False,
42
+ ),
43
+ ToolParameter(
44
+ name="icon_emoji",
45
+ type="string",
46
+ description="Emoji icon (e.g., ':robot_face:')",
47
+ required=False,
48
+ ),
49
+ ToolParameter(
50
+ name="channel",
51
+ type="string",
52
+ description="Channel to post to (overrides webhook default)",
53
+ required=False,
54
+ ),
55
+ ]
56
+
57
+ super().__init__(metadata, parameters)
58
+
59
+ async def _execute(
60
+ self,
61
+ webhook_url: str,
62
+ message: str,
63
+ username: Optional[str] = None,
64
+ icon_emoji: Optional[str] = None,
65
+ channel: Optional[str] = None,
66
+ ) -> Dict[str, Any]:
67
+ """Execute Slack notification.
68
+
69
+ Args:
70
+ webhook_url: Slack webhook URL
71
+ message: Message text
72
+ username: Bot username
73
+ icon_emoji: Icon emoji
74
+ channel: Target channel
75
+
76
+ Returns:
77
+ Dictionary containing send results
78
+ """
79
+ try:
80
+ import httpx
81
+ except ImportError:
82
+ raise ImportError(
83
+ "httpx package not installed. Install with: pip install httpx"
84
+ )
85
+
86
+ result: Dict[str, Any] = {
87
+ "message": message,
88
+ "success": False,
89
+ }
90
+
91
+ try:
92
+ # Build payload
93
+ payload: Dict[str, Any] = {"text": message}
94
+
95
+ if username:
96
+ payload["username"] = username
97
+ if icon_emoji:
98
+ payload["icon_emoji"] = icon_emoji
99
+ if channel:
100
+ payload["channel"] = channel
101
+
102
+ # Send to Slack
103
+ async with httpx.AsyncClient() as client:
104
+ response = await client.post(webhook_url, json=payload)
105
+ response.raise_for_status()
106
+
107
+ result.update({
108
+ "success": True,
109
+ "status_code": response.status_code,
110
+ })
111
+
112
+ except httpx.HTTPStatusError as e:
113
+ result["error"] = f"HTTP error: {e.response.status_code}"
114
+ except Exception as e:
115
+ result["error"] = str(e)
116
+
117
+ logger.info(f"Slack notification completed: success={result['success']}")
118
+ return result