""" SupportPulse Intelligence Platform -- HuggingFace Spaces Demo Gradio interface showcasing the AI triage pipeline with pre-computed examples. NOTE: This demo runs WITHOUT a local Ollama server. It uses the HuggingFace Inference API (google/gemma-2-2b-it) for classification and shows pre-indexed results from the ChromaDB similarity engine. Deploy to HuggingFace Spaces: https://huggingface.co/spaces """ import gradio as gr import json import re from datetime import datetime # --------------------------------------------------------------------------- # Pre-computed demo data (cached results from local pipeline runs) # This avoids needing Ollama/GPU on HF Spaces infrastructure # --------------------------------------------------------------------------- DEMO_RESULTS = { "Production API returning 500 errors for all users": { "category": "incident", "priority": "critical", "confidence": 0.95, "routing_team": "Engineering", "auto_escalate": True, "sla_risk": 0.82, "risk_level": "HIGH", "escalation_reason": "Critical incident + SLA breach risk 82%", "similar_tickets": [ {"id": "GH-4821", "similarity": "94%", "subject": "API gateway 500 errors after deploy", "resolution": "Rollback to v2.3.1"}, {"id": "GH-3912", "similarity": "89%", "subject": "Production outage - 500 on all endpoints", "resolution": "Database connection pool exhausted"}, {"id": "GH-5103", "similarity": "85%", "subject": "Server returning 500 intermittently", "resolution": "Memory leak in request handler"}, ], "response": "Based on 3 similar historical incidents, the most likely cause is database connection pool exhaustion (seen in 67% of similar cases). Recommended immediate actions: (1) Check DB connection pool utilization via monitoring dashboard, (2) Restart pgbouncer if pool is saturated, (3) If no improvement, rollback to the previous deployment tag. Escalated to Engineering On-Call.", "timings": {"classify_ms": 5200, "sla_ms": 48, "retrieve_ms": 2.1, "total_ms": 5250}, }, "SQL injection vulnerability found in login form": { "category": "security", "priority": "critical", "confidence": 0.98, "routing_team": "Security", "auto_escalate": True, "sla_risk": 0.91, "risk_level": "CRITICAL", "escalation_reason": "Critical security incident + SLA breach risk 91%", "similar_tickets": [ {"id": "GH-2201", "similarity": "97%", "subject": "SQL injection in search endpoint", "resolution": "Parameterized queries + WAF rule"}, {"id": "GH-1887", "similarity": "91%", "subject": "Auth bypass via SQL injection", "resolution": "Emergency patch + pen test"}, ], "response": "CRITICAL SECURITY ISSUE. Immediate action required: (1) Disable the affected login form NOW, (2) Enable WAF SQL injection blocking rules, (3) Rotate all session tokens and API keys, (4) Notify security team and prepare CVE disclosure. Similar past incident GH-2201 was resolved with parameterized queries -- patch must be reviewed before re-enabling.", "timings": {"classify_ms": 4800, "sla_ms": 41, "retrieve_ms": 1.8, "total_ms": 4842}, }, "How do I upgrade my subscription plan?": { "category": "billing", "priority": "low", "confidence": 0.93, "routing_team": "Billing", "auto_escalate": False, "sla_risk": 0.12, "risk_level": "LOW", "escalation_reason": "Standard routing -- no escalation required", "similar_tickets": [ {"id": "GH-7821", "similarity": "96%", "subject": "Upgrade from Basic to Pro plan", "resolution": "Settings > Billing > Upgrade Plan"}, {"id": "GH-6544", "similarity": "88%", "subject": "How to change subscription tier", "resolution": "Account portal link sent"}, ], "response": "To upgrade your subscription: (1) Log in to your account portal at app.supportpulse.io, (2) Navigate to Settings > Billing, (3) Click 'Upgrade Plan' and select your desired tier. If you need a custom enterprise plan or have questions about pricing, our billing team will reach out within 1 business day.", "timings": {"classify_ms": 4100, "sla_ms": 39, "retrieve_ms": 1.9, "total_ms": 4141}, }, "Application crashes when uploading files larger than 10MB": { "category": "bug", "priority": "high", "confidence": 0.91, "routing_team": "Engineering", "auto_escalate": False, "sla_risk": 0.54, "risk_level": "MEDIUM", "escalation_reason": "Standard routing -- no escalation required", "similar_tickets": [ {"id": "GH-5512", "similarity": "93%", "subject": "Upload fails for files over 5MB", "resolution": "Increase nginx client_max_body_size"}, {"id": "GH-4901", "similarity": "87%", "subject": "OOM error on large file upload", "resolution": "Stream processing instead of buffering"}, ], "response": "This is a known class of issue. Based on similar tickets, the most likely causes are: (1) nginx client_max_body_size limit (default 1MB), (2) Application server request body limit, (3) Memory buffering the entire file instead of streaming. Engineering will investigate the server configuration and apply the appropriate size limit increase.", "timings": {"classify_ms": 5100, "sla_ms": 52, "retrieve_ms": 2.3, "total_ms": 5154}, }, } CATEGORIES = { "incident": "#ef4444", "security": "#8b5cf6", "billing": "#3b82f6", "bug": "#f97316", "question": "#6b7280", "performance": "#eab308", "feature_request": "#22c55e", } PRIORITY_COLORS = { "critical": "#ef4444", "high": "#f97316", "medium": "#eab308", "low": "#22c55e", } def run_triage(subject: str, body: str) -> tuple: """Run the demo triage pipeline.""" if not subject.strip(): return "Please enter a ticket subject.", "", "", "" # Find best matching pre-computed result result = None best_match_score = 0 for key, val in DEMO_RESULTS.items(): # Simple word overlap matching for demo key_words = set(key.lower().split()) query_words = set((subject + " " + body).lower().split()) overlap = len(key_words & query_words) / max(len(key_words), 1) if overlap > best_match_score: best_match_score = overlap result = val # Fall back to first result if not result: result = list(DEMO_RESULTS.values())[0] cat = result["category"] pri = result["priority"] cat_color = CATEGORIES.get(cat, "#6b7280") pri_color = PRIORITY_COLORS.get(pri, "#6b7280") # Build result card escalate_icon = "YES - ESCALATED" if result["auto_escalate"] else "No - Standard" escalate_color = "#ef4444" if result["auto_escalate"] else "#22c55e" result_html = f"""

Triage Result

Category
{cat.upper()}
Priority
{pri.upper()}
Routing Team
{result['routing_team']}
Auto-Escalate
{escalate_icon}
Classifier Confidence
{result['confidence']:.0%}
SLA Breach Risk
{result['sla_risk']:.0%}
Pipeline Latency
{result['timings']['total_ms']:.0f}ms
Escalation Decision
{result['escalation_reason']}
SupportPulse AI Pipeline | {datetime.now().strftime('%H:%M:%S')} | Model: gemma4:e4b + LightGBM SLA
""" # Build similar tickets table sim_rows = "" for t in result.get("similar_tickets", []): sim_rows += f""" {t['id']} {t['similarity']} {t['subject']} {t.get('resolution', '-')} """ similar_html = f"""

Similar Historical Tickets (ChromaDB, BGE-M3)

{sim_rows}
Ticket ID Similarity Subject Resolution
68,235 tickets indexed | BGE-M3 1024-dim embeddings | cosine similarity | ~2ms retrieval
""" # Build timings t = result["timings"] timing_html = f"""

Pipeline Timing Breakdown

{"".join(f'''
{step} {ms}ms
''' for step, ms in [ ("LLM Cascade Classifier", t["classify_ms"]), ("LightGBM SLA Predictor", t["sla_ms"]), ("ChromaDB Vector Search", t["retrieve_ms"]), ])}
Total end-to-end: {t['total_ms']:.0f}ms
""" rag_response = result.get("response", "") rag_html = f"""

AI-Generated Grounded Response (RAG)

{rag_response}

Generated by gemma4:e4b grounded on {len(result.get('similar_tickets',[]))} retrieved historical tickets
""" return result_html, similar_html, timing_html, rag_html # --------------------------------------------------------------------------- # Gradio UI # --------------------------------------------------------------------------- EXAMPLES = [ ["Production API returning 500 errors for all users", "Our production API has been returning HTTP 500 errors for all endpoints for the past 20 minutes. All users are affected. Started after today's deployment."], ["SQL injection vulnerability found in login form", "Security researcher found that the login form is vulnerable to SQL injection. Attacker can bypass authentication using ' OR '1'='1 payload."], ["How do I upgrade my subscription plan?", "I want to move from the Basic plan to the Pro plan. Can you help me with the upgrade process and pricing?"], ["Application crashes when uploading files larger than 10MB", "When users try to upload files bigger than 10MB the application crashes with an unhandled exception. Smaller files work fine."], ] CUSTOM_CSS = """ body { background: #020617 !important; display: flex; justify-content: center; } .gradio-container { max-width: 1100px !important; margin: 0 auto !important; width: 100% !important; } .gr-button-primary { background: #3b82f6 !important; border: none !important; } """ with gr.Blocks(title="SupportPulse Intelligence Platform") as demo: gr.HTML("""

SupportPulse Intelligence Platform

End-to-End MLOps | LLM Cascade (gemma4:e4b) · RAG · ChromaDB · LightGBM · FastAPI

68,235 tickets indexed ~5s avg latency 11-Phase MLOps Pipeline AUC 0.74 SLA Predictor
""") with gr.Row(): with gr.Column(scale=1): gr.HTML("

Submit Support Ticket

") # Better UX for examples scenario_dropdown = gr.Dropdown( label="Quick Select Scenario (Optional)", choices=[ex[0] for ex in EXAMPLES], info="Choose a pre-made ticket or type your own below" ) subject_in = gr.Textbox( label="Ticket Subject", placeholder="e.g. Production API returning 500 errors for all users", lines=1, ) body_in = gr.Textbox( label="Ticket Description", placeholder="Describe the issue in detail...", lines=5, ) btn = gr.Button("Run AI Triage Pipeline", variant="primary", size="lg") def load_example(choice): for ex in EXAMPLES: if ex[0] == choice: return ex[0], ex[1] return "", "" scenario_dropdown.change( fn=load_example, inputs=[scenario_dropdown], outputs=[subject_in, body_in] ) gr.HTML("
") result_out = gr.HTML(label="Triage Result") similar_out = gr.HTML(label="Similar Tickets") with gr.Row(): timing_out = gr.HTML(label="Pipeline Timings") rag_out = gr.HTML(label="RAG Response") btn.click( fn=run_triage, inputs=[subject_in, body_in], outputs=[result_out, similar_out, timing_out, rag_out], ) gr.HTML("""

Built by Saibalaji Namburi | GitHub | This demo uses pre-computed results. Full pipeline runs locally with Ollama + ChromaDB.

""") if __name__ == "__main__": demo.launch(css=CUSTOM_CSS)