import gradio as gr import sys from typing import List, Dict, Any # --- Consent/Event Audit Panel --- def consent_audit_panel(consent_events: List[Dict[str, Any]]): """ UI Panel to show all consent events, opt-outs, and compliance flags per contact and batch. Accepts a list of consent event dicts with structure as returned from backend JSON. """ audit_md = "# Consent/Event Audit\nPer-contact and batch consent history." for event in consent_events: audit_md += f"\n- Contact: {event.get('contact_id','?')} | Event: {event.get('event_type','?')} | Opt-out: {event.get('opt_out',False)} | Compliance: {event.get('compliance_flag','?')})" return gr.Markdown(audit_md) # --- Dynamic Branching Composer for Cadence Editing --- def branching_composer(branches: List[Dict[str, Any]]): """ Visual sequence builder for editing cadences. Structure assumed to be a list of dict branches with JSON mirroring backend. """ builder_md = "# Dynamic Cadence Branching\n" + "\n## Sequence Tree:" for b in branches: builder_md += f"\n- Step {b.get('step','?')}: {b.get('description','?')} (Next: {b.get('next','?')})" return gr.Markdown(builder_md) # --- Live Diagnostics Panel for Cadence Errors/Health --- def diagnostics_panel(events: List[Dict[str, Any]]): """ Incident/event log UI widget to show errors and health of cadence system. Format is a simple list of event dicts from backend state. """ diag_md = "# Live Diagnostics: Cadence Health\n" for e in events: diag_md += f"\n- [{e.get('timestamp','?')}] {e.get('type','?')}: {e.get('message','?')}{' [ERROR]' if e.get('level','').lower()=='error' else ''}" return gr.Markdown(diag_md) # --- Exportable Audit Trail Widget --- def audit_trail_widget(audit_history: List[Dict[str, Any]]): """ Compliance and debug history view for export. Accepts audit events from backend JSON/state. """ audit_log = 'Contact,Event,Opt-out,Compliance\n' for item in audit_history: audit_log += f"{item.get('contact_id','?')},{item.get('event_type','?')},{item.get('opt_out',False)},{item.get('compliance_flag','?')}\n" return gr.Textbox(label="Audit Trail CSV", value=audit_log, lines=10) # Example usage in Gradio Blocks with gr.Blocks(title="StrategyStack UI") as demo: gr.Markdown("# Outreach Cadence & Compliance Dashboard") consent_events_sample = [ { "contact_id": "LEAD_001", "event_type": "consent_given", "timestamp": "2025-11-06T06:20:00Z", "opt_out": False, "compliance_flag": "ok", "region": "EU", "method": "checkbox_onboarding_form", "actor": "user", "batch_id": "BATCH_Q4_2025_HEALTHCARE" }, { "contact_id": "LEAD_002", "event_type": "opt_out", "timestamp": "2025-11-06T06:21:00Z", "opt_out": True, "compliance_flag": "flagged", "region": "US", "method": "footer_unsubscribe", "actor": "user", "batch_id": "BATCH_Q4_2025_HEALTHCARE" }, { "contact_id": "LEAD_003", "event_type": "consent_given", "timestamp": "2025-11-06T07:15:00Z", "opt_out": False, "compliance_flag": "ok", "region": "US", "method": "api_integration", "actor": "system", "batch_id": "BATCH_Q4_2025_SAAS" } ] branches_sample = [ { "step": 1, "description": "Initial Welcome Email - Personalized Industry Context", "channel": "email", "timing": "immediate", "next": 2, "condition": "not_opted_out" }, { "step": 2, "description": "LinkedIn Connection Request with Custom Note", "channel": "linkedin", "timing": "2_days_after_step_1", "next": 3, "condition": "no_reply_from_step_1" }, { "step": 3, "description": "Follow-up Call - Pain Point Discovery", "channel": "phone", "timing": "3_days_after_step_2", "next": 4, "condition": "engagement_score_below_0.7" }, { "step": 4, "description": "Case Study Email - Relevant to Industry", "channel": "email", "timing": "1_day_after_step_3", "next": "END", "condition": "not_connected" } ] diagnostics_sample = [ { "timestamp": "2025-11-06T06:23:00Z", "type": "info", "message": "Cadence started for BATCH_Q4_2025_HEALTHCARE with 150 leads", "level": "info", "agent": "cadence_orchestrator" }, { "timestamp": "2025-11-06T06:29:00Z", "type": "error", "message": "Compliance block: Message suppressed for LEAD_002 - opted out via footer_unsubscribe", "level": "error", "agent": "compliance_agent" }, { "timestamp": "2025-11-06T06:33:00Z", "type": "warning", "message": "Rate limit reached for LinkedIn API; implementing exponential backoff for 15 minutes", "level": "warning", "agent": "outreach_agent" }, { "timestamp": "2025-11-06T06:45:00Z", "type": "success", "message": "Enrichment completed for 45 leads with intent_score > 0.8", "level": "info", "agent": "enrichment_agent" }, { "timestamp": "2025-11-06T07:00:00Z", "type": "warning", "message": "5 leads flagged for human validation due to incomplete firmographic data", "level": "warning", "agent": "validation_agent" } ] audit_history_sample = consent_events_sample