empathy-framework 3.7.0__py3-none-any.whl → 3.8.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.
- coach_wizards/code_reviewer_README.md +60 -0
- coach_wizards/code_reviewer_wizard.py +180 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/METADATA +148 -11
- empathy_framework-3.8.0.dist-info/RECORD +333 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/top_level.txt +5 -1
- empathy_healthcare_plugin/monitors/__init__.py +9 -0
- empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
- empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
- empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
- empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
- empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
- empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
- empathy_llm_toolkit/agent_factory/__init__.py +53 -0
- empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
- empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
- empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
- empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
- empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
- empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
- empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
- empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
- empathy_llm_toolkit/agent_factory/base.py +305 -0
- empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
- empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
- empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
- empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
- empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
- empathy_llm_toolkit/agent_factory/decorators.py +286 -0
- empathy_llm_toolkit/agent_factory/factory.py +558 -0
- empathy_llm_toolkit/agent_factory/framework.py +192 -0
- empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
- empathy_llm_toolkit/agent_factory/resilient.py +320 -0
- empathy_llm_toolkit/cli/__init__.py +8 -0
- empathy_llm_toolkit/cli/sync_claude.py +487 -0
- empathy_llm_toolkit/code_health.py +150 -3
- empathy_llm_toolkit/config/__init__.py +29 -0
- empathy_llm_toolkit/config/unified.py +295 -0
- empathy_llm_toolkit/routing/__init__.py +32 -0
- empathy_llm_toolkit/routing/model_router.py +362 -0
- empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
- empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
- empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
- empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
- empathy_llm_toolkit/security/README.md +262 -0
- empathy_llm_toolkit/security/__init__.py +62 -0
- empathy_llm_toolkit/security/audit_logger.py +929 -0
- empathy_llm_toolkit/security/audit_logger_example.py +152 -0
- empathy_llm_toolkit/security/pii_scrubber.py +640 -0
- empathy_llm_toolkit/security/secrets_detector.py +678 -0
- empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
- empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
- empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
- empathy_llm_toolkit/wizards/__init__.py +38 -0
- empathy_llm_toolkit/wizards/base_wizard.py +364 -0
- empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
- empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
- empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
- empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
- empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
- empathy_os/__init__.py +52 -52
- empathy_os/adaptive/__init__.py +13 -0
- empathy_os/adaptive/task_complexity.py +127 -0
- empathy_os/cache/__init__.py +117 -0
- empathy_os/cache/base.py +166 -0
- empathy_os/cache/dependency_manager.py +253 -0
- empathy_os/cache/hash_only.py +248 -0
- empathy_os/cache/hybrid.py +390 -0
- empathy_os/cache/storage.py +282 -0
- empathy_os/cli.py +118 -8
- empathy_os/cli_unified.py +121 -1
- empathy_os/config/__init__.py +63 -0
- empathy_os/config/xml_config.py +239 -0
- empathy_os/config.py +2 -1
- empathy_os/dashboard/__init__.py +15 -0
- empathy_os/dashboard/server.py +743 -0
- empathy_os/memory/__init__.py +195 -0
- empathy_os/memory/claude_memory.py +466 -0
- empathy_os/memory/config.py +224 -0
- empathy_os/memory/control_panel.py +1298 -0
- empathy_os/memory/edges.py +179 -0
- empathy_os/memory/graph.py +567 -0
- empathy_os/memory/long_term.py +1194 -0
- empathy_os/memory/nodes.py +179 -0
- empathy_os/memory/redis_bootstrap.py +540 -0
- empathy_os/memory/security/__init__.py +31 -0
- empathy_os/memory/security/audit_logger.py +930 -0
- empathy_os/memory/security/pii_scrubber.py +640 -0
- empathy_os/memory/security/secrets_detector.py +678 -0
- empathy_os/memory/short_term.py +2119 -0
- empathy_os/memory/storage/__init__.py +15 -0
- empathy_os/memory/summary_index.py +583 -0
- empathy_os/memory/unified.py +619 -0
- empathy_os/metrics/__init__.py +12 -0
- empathy_os/metrics/prompt_metrics.py +190 -0
- empathy_os/models/__init__.py +136 -0
- empathy_os/models/__main__.py +13 -0
- empathy_os/models/cli.py +655 -0
- empathy_os/models/empathy_executor.py +354 -0
- empathy_os/models/executor.py +252 -0
- empathy_os/models/fallback.py +671 -0
- empathy_os/models/provider_config.py +563 -0
- empathy_os/models/registry.py +382 -0
- empathy_os/models/tasks.py +302 -0
- empathy_os/models/telemetry.py +548 -0
- empathy_os/models/token_estimator.py +378 -0
- empathy_os/models/validation.py +274 -0
- empathy_os/monitoring/__init__.py +52 -0
- empathy_os/monitoring/alerts.py +23 -0
- empathy_os/monitoring/alerts_cli.py +268 -0
- empathy_os/monitoring/multi_backend.py +271 -0
- empathy_os/monitoring/otel_backend.py +363 -0
- empathy_os/optimization/__init__.py +19 -0
- empathy_os/optimization/context_optimizer.py +272 -0
- empathy_os/plugins/__init__.py +28 -0
- empathy_os/plugins/base.py +361 -0
- empathy_os/plugins/registry.py +268 -0
- empathy_os/project_index/__init__.py +30 -0
- empathy_os/project_index/cli.py +335 -0
- empathy_os/project_index/crew_integration.py +430 -0
- empathy_os/project_index/index.py +425 -0
- empathy_os/project_index/models.py +501 -0
- empathy_os/project_index/reports.py +473 -0
- empathy_os/project_index/scanner.py +538 -0
- empathy_os/prompts/__init__.py +61 -0
- empathy_os/prompts/config.py +77 -0
- empathy_os/prompts/context.py +177 -0
- empathy_os/prompts/parser.py +285 -0
- empathy_os/prompts/registry.py +313 -0
- empathy_os/prompts/templates.py +208 -0
- empathy_os/resilience/__init__.py +56 -0
- empathy_os/resilience/circuit_breaker.py +256 -0
- empathy_os/resilience/fallback.py +179 -0
- empathy_os/resilience/health.py +300 -0
- empathy_os/resilience/retry.py +209 -0
- empathy_os/resilience/timeout.py +135 -0
- empathy_os/routing/__init__.py +43 -0
- empathy_os/routing/chain_executor.py +433 -0
- empathy_os/routing/classifier.py +217 -0
- empathy_os/routing/smart_router.py +234 -0
- empathy_os/routing/wizard_registry.py +307 -0
- empathy_os/trust/__init__.py +28 -0
- empathy_os/trust/circuit_breaker.py +579 -0
- empathy_os/validation/__init__.py +19 -0
- empathy_os/validation/xml_validator.py +281 -0
- empathy_os/wizard_factory_cli.py +170 -0
- empathy_os/workflows/__init__.py +360 -0
- empathy_os/workflows/base.py +1660 -0
- empathy_os/workflows/bug_predict.py +962 -0
- empathy_os/workflows/code_review.py +960 -0
- empathy_os/workflows/code_review_adapters.py +310 -0
- empathy_os/workflows/code_review_pipeline.py +720 -0
- empathy_os/workflows/config.py +600 -0
- empathy_os/workflows/dependency_check.py +648 -0
- empathy_os/workflows/document_gen.py +1069 -0
- empathy_os/workflows/documentation_orchestrator.py +1205 -0
- empathy_os/workflows/health_check.py +679 -0
- empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
- empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
- empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
- empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
- empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
- empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
- empathy_os/workflows/manage_documentation.py +804 -0
- empathy_os/workflows/new_sample_workflow1.py +146 -0
- empathy_os/workflows/new_sample_workflow1_README.md +150 -0
- empathy_os/workflows/perf_audit.py +687 -0
- empathy_os/workflows/pr_review.py +748 -0
- empathy_os/workflows/progress.py +445 -0
- empathy_os/workflows/progress_server.py +322 -0
- empathy_os/workflows/refactor_plan.py +693 -0
- empathy_os/workflows/release_prep.py +808 -0
- empathy_os/workflows/research_synthesis.py +404 -0
- empathy_os/workflows/secure_release.py +585 -0
- empathy_os/workflows/security_adapters.py +297 -0
- empathy_os/workflows/security_audit.py +1046 -0
- empathy_os/workflows/step_config.py +234 -0
- empathy_os/workflows/test5.py +125 -0
- empathy_os/workflows/test5_README.md +158 -0
- empathy_os/workflows/test_gen.py +1855 -0
- empathy_os/workflows/test_lifecycle.py +526 -0
- empathy_os/workflows/test_maintenance.py +626 -0
- empathy_os/workflows/test_maintenance_cli.py +590 -0
- empathy_os/workflows/test_maintenance_crew.py +821 -0
- empathy_os/workflows/xml_enhanced_crew.py +285 -0
- empathy_software_plugin/cli/__init__.py +120 -0
- empathy_software_plugin/cli/inspect.py +362 -0
- empathy_software_plugin/cli.py +3 -1
- empathy_software_plugin/wizards/__init__.py +42 -0
- empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
- empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
- empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
- empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
- empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
- empathy_software_plugin/wizards/base_wizard.py +288 -0
- empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
- empathy_software_plugin/wizards/code_review_wizard.py +606 -0
- empathy_software_plugin/wizards/debugging/__init__.py +50 -0
- empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
- empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
- empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
- empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
- empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
- empathy_software_plugin/wizards/debugging/verification.py +369 -0
- empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
- empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
- empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
- empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
- empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
- empathy_software_plugin/wizards/performance/__init__.py +9 -0
- empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
- empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
- empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
- empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
- empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
- empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
- empathy_software_plugin/wizards/security/__init__.py +32 -0
- empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
- empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
- empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
- empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
- empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
- empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
- empathy_software_plugin/wizards/testing/__init__.py +27 -0
- empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
- empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
- empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
- empathy_software_plugin/wizards/testing_wizard.py +274 -0
- hot_reload/README.md +473 -0
- hot_reload/__init__.py +62 -0
- hot_reload/config.py +84 -0
- hot_reload/integration.py +228 -0
- hot_reload/reloader.py +298 -0
- hot_reload/watcher.py +179 -0
- hot_reload/websocket.py +176 -0
- scaffolding/README.md +589 -0
- scaffolding/__init__.py +35 -0
- scaffolding/__main__.py +14 -0
- scaffolding/cli.py +240 -0
- test_generator/__init__.py +38 -0
- test_generator/__main__.py +14 -0
- test_generator/cli.py +226 -0
- test_generator/generator.py +325 -0
- test_generator/risk_analyzer.py +216 -0
- workflow_patterns/__init__.py +33 -0
- workflow_patterns/behavior.py +249 -0
- workflow_patterns/core.py +76 -0
- workflow_patterns/output.py +99 -0
- workflow_patterns/registry.py +255 -0
- workflow_patterns/structural.py +288 -0
- workflow_scaffolding/__init__.py +11 -0
- workflow_scaffolding/__main__.py +12 -0
- workflow_scaffolding/cli.py +206 -0
- workflow_scaffolding/generator.py +265 -0
- agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
- agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
- agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
- agents/compliance_anticipation_agent.py +0 -1422
- agents/compliance_db.py +0 -339
- agents/epic_integration_wizard.py +0 -530
- agents/notifications.py +0 -291
- agents/trust_building_behaviors.py +0 -872
- empathy_framework-3.7.0.dist-info/RECORD +0 -105
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/WHEEL +0 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/entry_points.txt +0 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/licenses/LICENSE +0 -0
- /empathy_os/{monitoring.py → agent_monitoring.py} +0 -0
agents/notifications.py
DELETED
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
"""Notification system for compliance alerts.
|
|
2
|
-
|
|
3
|
-
Supports multiple channels: Email (SMTP), Slack webhooks, SMS (Twilio).
|
|
4
|
-
Graceful fallback when notification delivery fails.
|
|
5
|
-
|
|
6
|
-
Copyright 2025 Smart-AI-Memory
|
|
7
|
-
Licensed under Fair Source License 0.9
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
import logging
|
|
11
|
-
import os
|
|
12
|
-
import smtplib
|
|
13
|
-
from dataclasses import dataclass
|
|
14
|
-
from email.mime.multipart import MIMEMultipart
|
|
15
|
-
from email.mime.text import MIMEText
|
|
16
|
-
from typing import Any
|
|
17
|
-
|
|
18
|
-
import requests
|
|
19
|
-
|
|
20
|
-
logger = logging.getLogger(__name__)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@dataclass
|
|
24
|
-
class NotificationConfig:
|
|
25
|
-
"""Configuration for notification channels."""
|
|
26
|
-
|
|
27
|
-
# Email (SMTP)
|
|
28
|
-
smtp_host: str | None = None
|
|
29
|
-
smtp_port: int = 587
|
|
30
|
-
smtp_user: str | None = None
|
|
31
|
-
smtp_password: str | None = None
|
|
32
|
-
smtp_from: str | None = None
|
|
33
|
-
|
|
34
|
-
# Slack
|
|
35
|
-
slack_webhook_url: str | None = None
|
|
36
|
-
|
|
37
|
-
# Twilio SMS
|
|
38
|
-
twilio_account_sid: str | None = None
|
|
39
|
-
twilio_auth_token: str | None = None
|
|
40
|
-
twilio_from_number: str | None = None
|
|
41
|
-
|
|
42
|
-
@classmethod
|
|
43
|
-
def from_env(cls) -> "NotificationConfig":
|
|
44
|
-
"""Load configuration from environment variables."""
|
|
45
|
-
return cls(
|
|
46
|
-
# Email
|
|
47
|
-
smtp_host=os.getenv("SMTP_HOST"),
|
|
48
|
-
smtp_port=int(os.getenv("SMTP_PORT", "587")),
|
|
49
|
-
smtp_user=os.getenv("SMTP_USER"),
|
|
50
|
-
smtp_password=os.getenv("SMTP_PASSWORD"),
|
|
51
|
-
smtp_from=os.getenv("SMTP_FROM"),
|
|
52
|
-
# Slack
|
|
53
|
-
slack_webhook_url=os.getenv("SLACK_WEBHOOK_URL"),
|
|
54
|
-
# Twilio
|
|
55
|
-
twilio_account_sid=os.getenv("TWILIO_ACCOUNT_SID"),
|
|
56
|
-
twilio_auth_token=os.getenv("TWILIO_AUTH_TOKEN"),
|
|
57
|
-
twilio_from_number=os.getenv("TWILIO_FROM_NUMBER"),
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
class NotificationService:
|
|
62
|
-
"""Multi-channel notification service with graceful fallback."""
|
|
63
|
-
|
|
64
|
-
def __init__(self, config: NotificationConfig | None = None):
|
|
65
|
-
"""Initialize notification service.
|
|
66
|
-
|
|
67
|
-
Args:
|
|
68
|
-
config: Notification configuration (loads from env if None)
|
|
69
|
-
"""
|
|
70
|
-
self.config = config or NotificationConfig.from_env()
|
|
71
|
-
|
|
72
|
-
def send_email(
|
|
73
|
-
self,
|
|
74
|
-
to: list[str],
|
|
75
|
-
subject: str,
|
|
76
|
-
body: str,
|
|
77
|
-
html_body: str | None = None,
|
|
78
|
-
) -> bool:
|
|
79
|
-
"""Send email notification via SMTP.
|
|
80
|
-
|
|
81
|
-
Args:
|
|
82
|
-
to: List of recipient email addresses
|
|
83
|
-
subject: Email subject
|
|
84
|
-
body: Plain text body
|
|
85
|
-
html_body: Optional HTML body
|
|
86
|
-
|
|
87
|
-
Returns:
|
|
88
|
-
True if sent successfully, False otherwise
|
|
89
|
-
"""
|
|
90
|
-
if not self.config.smtp_host:
|
|
91
|
-
logger.warning("SMTP not configured, skipping email notification")
|
|
92
|
-
return False
|
|
93
|
-
|
|
94
|
-
try:
|
|
95
|
-
# Create message
|
|
96
|
-
msg = MIMEMultipart("alternative")
|
|
97
|
-
msg["Subject"] = subject
|
|
98
|
-
msg["From"] = self.config.smtp_from or "noreply@smartaimemory.com"
|
|
99
|
-
msg["To"] = ", ".join(to)
|
|
100
|
-
|
|
101
|
-
# Attach plain text and HTML
|
|
102
|
-
msg.attach(MIMEText(body, "plain"))
|
|
103
|
-
if html_body:
|
|
104
|
-
msg.attach(MIMEText(html_body, "html"))
|
|
105
|
-
|
|
106
|
-
# Send via SMTP
|
|
107
|
-
with smtplib.SMTP(self.config.smtp_host, self.config.smtp_port) as server:
|
|
108
|
-
server.starttls()
|
|
109
|
-
if self.config.smtp_user and self.config.smtp_password:
|
|
110
|
-
server.login(self.config.smtp_user, self.config.smtp_password)
|
|
111
|
-
server.send_message(msg)
|
|
112
|
-
|
|
113
|
-
logger.info(f"Email sent to {len(to)} recipients: {subject}")
|
|
114
|
-
return True
|
|
115
|
-
|
|
116
|
-
except Exception as e:
|
|
117
|
-
logger.error(f"Failed to send email: {e}")
|
|
118
|
-
return False
|
|
119
|
-
|
|
120
|
-
def send_slack(
|
|
121
|
-
self,
|
|
122
|
-
message: str,
|
|
123
|
-
channel: str | None = None,
|
|
124
|
-
blocks: list[dict[str, Any]] | None = None,
|
|
125
|
-
) -> bool:
|
|
126
|
-
"""Send Slack notification via webhook.
|
|
127
|
-
|
|
128
|
-
Args:
|
|
129
|
-
message: Message text (fallback for blocks)
|
|
130
|
-
channel: Optional channel override
|
|
131
|
-
blocks: Optional Slack blocks for rich formatting
|
|
132
|
-
|
|
133
|
-
Returns:
|
|
134
|
-
True if sent successfully, False otherwise
|
|
135
|
-
"""
|
|
136
|
-
if not self.config.slack_webhook_url:
|
|
137
|
-
logger.warning("Slack webhook not configured, skipping notification")
|
|
138
|
-
return False
|
|
139
|
-
|
|
140
|
-
try:
|
|
141
|
-
payload: dict[str, Any] = {"text": message}
|
|
142
|
-
|
|
143
|
-
if channel:
|
|
144
|
-
payload["channel"] = channel
|
|
145
|
-
|
|
146
|
-
if blocks:
|
|
147
|
-
payload["blocks"] = blocks
|
|
148
|
-
|
|
149
|
-
response = requests.post(
|
|
150
|
-
self.config.slack_webhook_url,
|
|
151
|
-
json=payload,
|
|
152
|
-
headers={"Content-Type": "application/json"},
|
|
153
|
-
timeout=10,
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
if response.status_code == 200:
|
|
157
|
-
logger.info(f"Slack notification sent: {message[:50]}...")
|
|
158
|
-
return True
|
|
159
|
-
else:
|
|
160
|
-
logger.error(f"Slack webhook failed: {response.status_code} {response.text}")
|
|
161
|
-
return False
|
|
162
|
-
|
|
163
|
-
except Exception as e:
|
|
164
|
-
logger.error(f"Failed to send Slack notification: {e}")
|
|
165
|
-
return False
|
|
166
|
-
|
|
167
|
-
def send_sms(self, to: str, message: str) -> bool:
|
|
168
|
-
"""Send SMS notification via Twilio.
|
|
169
|
-
|
|
170
|
-
Args:
|
|
171
|
-
to: Phone number (E.164 format: +1234567890)
|
|
172
|
-
message: SMS message text (max 160 chars recommended)
|
|
173
|
-
|
|
174
|
-
Returns:
|
|
175
|
-
True if sent successfully, False otherwise
|
|
176
|
-
"""
|
|
177
|
-
if not all([self.config.twilio_account_sid, self.config.twilio_auth_token]):
|
|
178
|
-
logger.warning("Twilio not configured, skipping SMS notification")
|
|
179
|
-
return False
|
|
180
|
-
|
|
181
|
-
try:
|
|
182
|
-
# Import Twilio client (optional dependency)
|
|
183
|
-
from twilio.rest import Client
|
|
184
|
-
|
|
185
|
-
client = Client(self.config.twilio_account_sid, self.config.twilio_auth_token)
|
|
186
|
-
|
|
187
|
-
client.messages.create(
|
|
188
|
-
to=to,
|
|
189
|
-
from_=self.config.twilio_from_number,
|
|
190
|
-
body=message,
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
logger.info(f"SMS sent to {to}")
|
|
194
|
-
return True
|
|
195
|
-
|
|
196
|
-
except ImportError:
|
|
197
|
-
logger.error("Twilio SDK not installed. Install with: pip install twilio")
|
|
198
|
-
return False
|
|
199
|
-
except Exception as e:
|
|
200
|
-
logger.error(f"Failed to send SMS: {e}")
|
|
201
|
-
return False
|
|
202
|
-
|
|
203
|
-
def send_compliance_alert(
|
|
204
|
-
self,
|
|
205
|
-
severity: str,
|
|
206
|
-
title: str,
|
|
207
|
-
description: str,
|
|
208
|
-
recipients: dict[str, list[str]], # {'email': [...], 'phone': [...]}
|
|
209
|
-
) -> dict[str, bool]:
|
|
210
|
-
"""Send multi-channel compliance alert.
|
|
211
|
-
|
|
212
|
-
Args:
|
|
213
|
-
severity: Alert severity ('critical', 'high', 'medium', 'low')
|
|
214
|
-
title: Alert title
|
|
215
|
-
description: Alert description
|
|
216
|
-
recipients: Dict with 'email' and 'phone' lists
|
|
217
|
-
|
|
218
|
-
Returns:
|
|
219
|
-
Dict with channel success status: {'email': True, 'slack': True, 'sms': False}
|
|
220
|
-
"""
|
|
221
|
-
results = {}
|
|
222
|
-
|
|
223
|
-
# Email alert
|
|
224
|
-
if recipients.get("email"):
|
|
225
|
-
email_subject = f"[{severity.upper()}] Compliance Alert: {title}"
|
|
226
|
-
email_body = f"""
|
|
227
|
-
Compliance Alert
|
|
228
|
-
================
|
|
229
|
-
|
|
230
|
-
Severity: {severity.upper()}
|
|
231
|
-
Title: {title}
|
|
232
|
-
|
|
233
|
-
Description:
|
|
234
|
-
{description}
|
|
235
|
-
|
|
236
|
-
---
|
|
237
|
-
Generated by Empathy Framework Compliance Monitor
|
|
238
|
-
""".strip()
|
|
239
|
-
|
|
240
|
-
results["email"] = self.send_email(
|
|
241
|
-
to=recipients["email"],
|
|
242
|
-
subject=email_subject,
|
|
243
|
-
body=email_body,
|
|
244
|
-
)
|
|
245
|
-
|
|
246
|
-
# Slack alert
|
|
247
|
-
slack_emoji = {
|
|
248
|
-
"critical": ":rotating_light:",
|
|
249
|
-
"high": ":warning:",
|
|
250
|
-
"medium": ":grey_exclamation:",
|
|
251
|
-
"low": ":information_source:",
|
|
252
|
-
}.get(severity, ":bell:")
|
|
253
|
-
|
|
254
|
-
slack_message = f"{slack_emoji} *[{severity.upper()}] {title}*\n\n{description}"
|
|
255
|
-
|
|
256
|
-
slack_blocks = [
|
|
257
|
-
{
|
|
258
|
-
"type": "header",
|
|
259
|
-
"text": {
|
|
260
|
-
"type": "plain_text",
|
|
261
|
-
"text": f"{slack_emoji} Compliance Alert",
|
|
262
|
-
},
|
|
263
|
-
},
|
|
264
|
-
{
|
|
265
|
-
"type": "section",
|
|
266
|
-
"fields": [
|
|
267
|
-
{"type": "mrkdwn", "text": f"*Severity:*\n{severity.upper()}"},
|
|
268
|
-
{"type": "mrkdwn", "text": f"*Title:*\n{title}"},
|
|
269
|
-
],
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
"type": "section",
|
|
273
|
-
"text": {"type": "mrkdwn", "text": f"*Description:*\n{description}"},
|
|
274
|
-
},
|
|
275
|
-
]
|
|
276
|
-
|
|
277
|
-
results["slack"] = self.send_slack(slack_message, blocks=slack_blocks)
|
|
278
|
-
|
|
279
|
-
# SMS alert (only for critical/high)
|
|
280
|
-
if severity in ["critical", "high"] and recipients.get("phone"):
|
|
281
|
-
sms_message = f"[{severity.upper()}] {title}: {description[:100]}"
|
|
282
|
-
|
|
283
|
-
# Send to all phone numbers
|
|
284
|
-
sms_results = []
|
|
285
|
-
for phone in recipients["phone"]:
|
|
286
|
-
sms_results.append(self.send_sms(phone, sms_message))
|
|
287
|
-
|
|
288
|
-
results["sms"] = any(sms_results) # Success if any SMS sent
|
|
289
|
-
|
|
290
|
-
logger.info(f"Compliance alert sent: {results}")
|
|
291
|
-
return results
|