feat: ZeroClaw compliance agent — document analysis + role assignment + email
Add autonomous compliance agent that fetches web documents (cookie banners, privacy policies), classifies them via Qwen/Ollama, assesses DSGVO compliance, assigns to the responsible role, and sends notification emails. Components: - ZeroClaw SOP (6-step workflow: fetch, classify, assess, summarize, assign, notify) - Backend: /api/compliance/agent/analyze (combined endpoint) - Backend: /api/compliance/agent/notify (standalone email) - Frontend: /sdk/agent page (Manager UI with URL input + results) - Helper scripts + E2E test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
"""
|
||||
Agent Notification Routes — endpoint for the ZeroClaw compliance agent
|
||||
to send notification emails via SMTP.
|
||||
|
||||
POST /api/compliance/agent/notify
|
||||
"""
|
||||
|
||||
import logging
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from fastapi import APIRouter
|
||||
from pydantic import BaseModel, EmailStr
|
||||
|
||||
from compliance.services.smtp_sender import send_email
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/compliance/agent", tags=["agent"])
|
||||
|
||||
|
||||
class NotifyRequest(BaseModel):
|
||||
recipient: EmailStr
|
||||
subject: str
|
||||
body_html: str
|
||||
role: str
|
||||
escalation_id: str | None = None
|
||||
|
||||
|
||||
class NotifyResponse(BaseModel):
|
||||
status: str
|
||||
recipient: str
|
||||
subject: str
|
||||
role: str
|
||||
sent_at: str
|
||||
error: str | None = None
|
||||
|
||||
|
||||
@router.post("/notify", response_model=NotifyResponse)
|
||||
async def send_agent_notification(req: NotifyRequest):
|
||||
"""Send a compliance notification email on behalf of the agent."""
|
||||
result = send_email(
|
||||
recipient=req.recipient,
|
||||
subject=req.subject,
|
||||
body_html=_build_email_body(req),
|
||||
)
|
||||
|
||||
return NotifyResponse(
|
||||
status=result["status"],
|
||||
recipient=req.recipient,
|
||||
subject=req.subject,
|
||||
role=req.role,
|
||||
sent_at=datetime.now(timezone.utc).isoformat(),
|
||||
error=result.get("error"),
|
||||
)
|
||||
|
||||
|
||||
def _build_email_body(req: NotifyRequest) -> str:
|
||||
"""Wrap the agent's HTML body with a standard email frame."""
|
||||
return f"""
|
||||
<div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 600px; margin: 0 auto;">
|
||||
<div style="background: #1a1a2e; color: white; padding: 16px 24px; border-radius: 8px 8px 0 0;">
|
||||
<h2 style="margin: 0; font-size: 18px;">BreakPilot Compliance Agent</h2>
|
||||
</div>
|
||||
<div style="padding: 24px; border: 1px solid #e2e8f0; border-top: none;">
|
||||
<p style="color: #64748b; font-size: 13px; margin-top: 0;">
|
||||
Zugewiesen an: <strong>{req.role}</strong>
|
||||
{f' | Eskalation: {req.escalation_id}' if req.escalation_id else ''}
|
||||
</p>
|
||||
{req.body_html}
|
||||
</div>
|
||||
<div style="background: #f8fafc; padding: 12px 24px; border: 1px solid #e2e8f0; border-top: none; border-radius: 0 0 8px 8px;">
|
||||
<p style="color: #94a3b8; font-size: 11px; margin: 0;">
|
||||
Automatisch generiert vom BreakPilot Compliance Agent (ZeroClaw + Qwen)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
Reference in New Issue
Block a user