cx_ai_agent_v1 / agents /compliance.py
muzakkirhussain011's picture
Add application files (text files only)
8bab08d
# file: agents/compliance.py
from pathlib import Path
from app.schema import Prospect
from app.config import (
COMPANY_FOOTER_PATH, ENABLE_CAN_SPAM,
ENABLE_PECR, ENABLE_CASL
)
class Compliance:
"""Enforces email compliance and policies"""
def __init__(self, mcp_registry):
self.mcp = mcp_registry
self.store = mcp_registry.get_store_client()
# Load footer
footer_path = Path(COMPANY_FOOTER_PATH)
if footer_path.exists():
self.footer = footer_path.read_text()
else:
self.footer = "\n\n---\nLucidya Inc.\n123 Market St, San Francisco, CA 94105\nUnsubscribe: https://lucidya.example.com/unsubscribe"
async def run(self, prospect: Prospect) -> Prospect:
"""Check compliance and enforce policies"""
if not prospect.email_draft:
prospect.status = "blocked"
prospect.dropped_reason = "No email draft to check"
await self.store.save_prospect(prospect)
return prospect
policy_failures = []
# Check suppression
for contact in prospect.contacts:
if await self.store.check_suppression("email", contact.email):
policy_failures.append(f"Email suppressed: {contact.email}")
domain = contact.email.split("@")[1]
if await self.store.check_suppression("domain", domain):
policy_failures.append(f"Domain suppressed: {domain}")
if await self.store.check_suppression("company", prospect.company.id):
policy_failures.append(f"Company suppressed: {prospect.company.name}")
# Check content requirements
body = prospect.email_draft.get("body", "")
# CAN-SPAM requirements
if ENABLE_CAN_SPAM:
if "unsubscribe" not in body.lower() and "unsubscribe" not in self.footer.lower():
policy_failures.append("CAN-SPAM: Missing unsubscribe mechanism")
if not any(addr in self.footer for addr in ["St", "Ave", "Rd", "Blvd"]):
policy_failures.append("CAN-SPAM: Missing physical postal address")
# PECR requirements (UK)
if ENABLE_PECR:
# Check for soft opt-in or existing relationship
# In production, would check CRM for prior relationship
if "existing customer" not in body.lower():
# For demo, we'll be lenient
pass
# CASL requirements (Canada)
if ENABLE_CASL:
if "consent" not in body.lower() and prospect.company.domain.endswith(".ca"):
policy_failures.append("CASL: May need express consent for Canadian recipients")
# Check for unverifiable claims
forbidden_phrases = [
"guaranteed", "100%", "no risk", "best in the world",
"revolutionary", "breakthrough"
]
for phrase in forbidden_phrases:
if phrase in body.lower():
policy_failures.append(f"Unverifiable claim: '{phrase}'")
# Append footer to email
if not policy_failures:
prospect.email_draft["body"] = body + "\n" + self.footer
# Final decision
if policy_failures:
prospect.status = "blocked"
prospect.dropped_reason = "; ".join(policy_failures)
else:
prospect.status = "compliant"
await self.store.save_prospect(prospect)
return prospect