Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -2,99 +2,83 @@ import gradio as gr
|
|
| 2 |
import sys
|
| 3 |
from typing import List, Dict, Any
|
| 4 |
|
| 5 |
-
#
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
|
|
|
| 14 |
|
| 15 |
-
#
|
| 16 |
-
def
|
| 17 |
-
"""
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
for
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
results.append(result)
|
| 26 |
-
except Exception as e:
|
| 27 |
-
results.append({"error": str(e), "intent_score": 0, "readiness": "error"})
|
| 28 |
-
return results
|
| 29 |
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
|
| 36 |
-
#
|
| 37 |
-
def
|
| 38 |
-
"""
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
}
|
| 47 |
-
|
| 48 |
-
if AGENT_AVAILABLE:
|
| 49 |
-
try:
|
| 50 |
-
result = lead_scoring_agent.score_lead(lead)
|
| 51 |
-
return f"""Lead Scoring Result:
|
| 52 |
-
- Intent Score: {result.get('intent_score', 'N/A')}
|
| 53 |
-
- Readiness: {result.get('readiness', 'N/A')}
|
| 54 |
-
- Details: {result}"""
|
| 55 |
-
except Exception as e:
|
| 56 |
-
return f"Error scoring lead: {str(e)}"
|
| 57 |
-
else:
|
| 58 |
-
return f"""Lead Scoring Agent Demo (Agent Not Available)
|
| 59 |
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
|
| 65 |
-
|
| 66 |
-
|
|
|
|
| 67 |
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
lead_name = gr.Textbox(label="Lead Name", placeholder="John Doe")
|
| 80 |
-
lead_company = gr.Textbox(label="Company", placeholder="Acme Corp")
|
| 81 |
-
lead_title = gr.Textbox(label="Job Title", placeholder="CTO")
|
| 82 |
-
submit_btn = gr.Button("Score Lead", variant="primary")
|
| 83 |
-
|
| 84 |
-
with gr.Column():
|
| 85 |
-
output = gr.Textbox(label="Scoring Result", lines=10)
|
| 86 |
-
|
| 87 |
-
submit_btn.click(fn=demo_score_lead, inputs=[lead_name, lead_company, lead_title], outputs=output)
|
| 88 |
-
|
| 89 |
-
gr.Markdown("""---
|
| 90 |
-
### Troubleshooting Guide
|
| 91 |
-
If you encounter errors:
|
| 92 |
-
1. Check that all required dependencies are installed (see requirements.txt)
|
| 93 |
-
2. Verify that the lead_scoring_agent module is available
|
| 94 |
-
3. Check container logs for detailed error messages
|
| 95 |
-
4. See README.md for complete troubleshooting documentation
|
| 96 |
-
""")
|
| 97 |
|
| 98 |
-
# Launch the interface
|
| 99 |
if __name__ == "__main__":
|
| 100 |
-
demo.launch()
|
|
|
|
|
|
| 2 |
import sys
|
| 3 |
from typing import List, Dict, Any
|
| 4 |
|
| 5 |
+
# --- Consent/Event Audit Panel ---
|
| 6 |
+
def consent_audit_panel(consent_events: List[Dict[str, Any]]):
|
| 7 |
+
"""
|
| 8 |
+
UI Panel to show all consent events, opt-outs, and compliance flags per contact and batch.
|
| 9 |
+
Accepts a list of consent event dicts with structure as returned from backend JSON.
|
| 10 |
+
"""
|
| 11 |
+
audit_md = "# Consent/Event Audit\nPer-contact and batch consent history."
|
| 12 |
+
for event in consent_events:
|
| 13 |
+
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','?')})"
|
| 14 |
+
return gr.Markdown(audit_md)
|
| 15 |
|
| 16 |
+
# --- Dynamic Branching Composer for Cadence Editing ---
|
| 17 |
+
def branching_composer(branches: List[Dict[str, Any]]):
|
| 18 |
+
"""
|
| 19 |
+
Visual sequence builder for editing cadences.
|
| 20 |
+
Structure assumed to be a list of dict branches with JSON mirroring backend.
|
| 21 |
+
"""
|
| 22 |
+
builder_md = "# Dynamic Cadence Branching\n" + "\n## Sequence Tree:"
|
| 23 |
+
for b in branches:
|
| 24 |
+
builder_md += f"\n- Step {b.get('step','?')}: {b.get('description','?')} (Next: {b.get('next','?')})"
|
| 25 |
+
return gr.Markdown(builder_md)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
+
# --- Live Diagnostics Panel for Cadence Errors/Health ---
|
| 28 |
+
def diagnostics_panel(events: List[Dict[str, Any]]):
|
| 29 |
+
"""
|
| 30 |
+
Incident/event log UI widget to show errors and health of cadence system.
|
| 31 |
+
Format is a simple list of event dicts from backend state.
|
| 32 |
+
"""
|
| 33 |
+
diag_md = "# Live Diagnostics: Cadence Health\n"
|
| 34 |
+
for e in events:
|
| 35 |
+
diag_md += f"\n- [{e.get('timestamp','?')}] {e.get('type','?')}: {e.get('message','?')}{' [ERROR]' if e.get('level','').lower()=='error' else ''}"
|
| 36 |
+
return gr.Markdown(diag_md)
|
| 37 |
|
| 38 |
+
# --- Exportable Audit Trail Widget ---
|
| 39 |
+
def audit_trail_widget(audit_history: List[Dict[str, Any]]):
|
| 40 |
+
"""
|
| 41 |
+
Compliance and debug history view for export.
|
| 42 |
+
Accepts audit events from backend JSON/state.
|
| 43 |
+
"""
|
| 44 |
+
audit_log = 'Contact,Event,Opt-out,Compliance\n'
|
| 45 |
+
for item in audit_history:
|
| 46 |
+
audit_log += f"{item.get('contact_id','?')},{item.get('event_type','?')},{item.get('opt_out',False)},{item.get('compliance_flag','?')}\n"
|
| 47 |
+
return gr.Textbox(label="Audit Trail CSV", value=audit_log, lines=10)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
+
# Example usage in Gradio Blocks
|
| 50 |
+
with gr.Blocks(title="StrategyStack UI") as demo:
|
| 51 |
+
gr.Markdown("# Outreach Cadence & Compliance Dashboard")
|
| 52 |
+
consent_events_sample = [
|
| 53 |
+
{"contact_id": "C001", "event_type": "consent_given", "opt_out": False, "compliance_flag": "ok"},
|
| 54 |
+
{"contact_id": "C002", "event_type": "opt_out", "opt_out": True, "compliance_flag": "flagged"}
|
| 55 |
+
]
|
| 56 |
+
branches_sample = [
|
| 57 |
+
{"step": 1, "description": "Initial Email", "next": 2},
|
| 58 |
+
{"step": 2, "description": "Follow-up Call", "next": "End"}
|
| 59 |
+
]
|
| 60 |
+
diagnostics_sample = [
|
| 61 |
+
{"timestamp": "2025-11-05T20:50Z", "type": "error", "message": "Cadence execution failed", "level": "error"},
|
| 62 |
+
{"timestamp": "2025-11-05T20:46Z", "type": "info", "message": "Cadence started", "level": "info"}
|
| 63 |
+
]
|
| 64 |
+
audit_history_sample = consent_events_sample
|
| 65 |
|
| 66 |
+
with gr.Tab("Consent/Event Audit"):
|
| 67 |
+
consent_panel = consent_audit_panel(consent_events_sample)
|
| 68 |
+
gr.Markdown(conset_panel.value)
|
| 69 |
|
| 70 |
+
with gr.Tab("Cadence Branching Composer"):
|
| 71 |
+
composer_panel = branching_composer(branches_sample)
|
| 72 |
+
gr.Markdown(composer_panel.value)
|
| 73 |
+
|
| 74 |
+
with gr.Tab("Diagnostics"):
|
| 75 |
+
diag_panel = diagnostics_panel(diagnostics_sample)
|
| 76 |
+
gr.Markdown(diag_panel.value)
|
| 77 |
+
|
| 78 |
+
with gr.Tab("Exportable Audit Trail"):
|
| 79 |
+
audit_trail = audit_trail_widget(audit_history_sample)
|
| 80 |
+
gr.Textbox(value=audit_trail.value, label="Audit Trail CSV")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
|
|
|
| 82 |
if __name__ == "__main__":
|
| 83 |
+
demo.launch()
|
| 84 |
+
# Inline documentation for all panels and backend mapping is included above.
|