Spaces:
Runtime error
Runtime error
| """ | |
| app.py β Hugging Face Spaces Interface | |
| ======================================= | |
| Deploy this on huggingface.co/spaces to get a public web UI for the agent. | |
| In your HF Space settings, add these secrets: | |
| GROQ_API_KEY = gsk_your_groq_key_here | |
| Run locally: | |
| pip install gradio | |
| python app.py | |
| """ | |
| import os | |
| import sys | |
| import json | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), "code")) | |
| import gradio as gr | |
| from corpus_builder import build_corpus | |
| from retriever import MultiDomainRetriever | |
| from safety import should_escalate | |
| from agent import classify_ticket, generate_response, generate_escalation_message | |
| # ββ Boot ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| print("Loading corpus...") | |
| corpus = build_corpus() | |
| retriever = MultiDomainRetriever(corpus) | |
| print("Agent ready.") | |
| # ββ Core triage function ββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def triage(ticket_text: str): | |
| """Process one support ticket and return structured output.""" | |
| if not ticket_text.strip(): | |
| return "", "", "", "", "β Please enter a support issue." | |
| # Classify | |
| clf = classify_ticket(ticket_text) | |
| domain = clf.get("domain", "unknown") | |
| request_type = clf.get("request_type", "other") | |
| product_area = clf.get("product_area", "general") | |
| # Retrieve | |
| if domain in ("hackerrank", "claude", "visa"): | |
| docs = retriever.retrieve_for_domain(domain, ticket_text, top_k=4) | |
| else: | |
| docs = retriever.retrieve_all(ticket_text, top_k_per_domain=2) | |
| # Safety gate | |
| escalate, esc_reason = should_escalate(ticket_text, product_area, docs) | |
| # Generate | |
| if escalate: | |
| action = "π΄ ESCALATE β Human Required" | |
| response = generate_escalation_message(ticket_text, esc_reason) | |
| reason_out = esc_reason | |
| else: | |
| action = "π’ RESPOND β Automated" | |
| response = generate_response(ticket_text, docs) | |
| reason_out = "β" | |
| # Format sources | |
| sources = "\n".join( | |
| f"β’ [{d.get('score',0):.2f}] {d['title']}" for d in docs[:3] | |
| ) or "No sources found" | |
| classify_out = f"Domain: {domain}\nType: {request_type}\nArea: {product_area}" | |
| return classify_out, action, reason_out, sources, response | |
| # ββ Gradio UI βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| EXAMPLES = [ | |
| "How do I reset my HackerRank password?", | |
| "My Visa card was charged twice for the same transaction. I need a refund.", | |
| "How many messages can I send per day on Claude.ai free plan?", | |
| "Someone hacked my HackerRank account and is taking tests using my profile.", | |
| "What programming languages does HackerRank support for assessments?", | |
| "My Visa card was declined at an ATM but I have enough balance.", | |
| "How do I cancel my Claude Pro subscription?", | |
| "I cannot see candidate results in my HackerRank recruiter dashboard.", | |
| ] | |
| with gr.Blocks( | |
| title="Support Triage Agent", | |
| theme=gr.themes.Soft(), | |
| css=""" | |
| .header { text-align: center; padding: 20px 0; } | |
| .respond { color: #16a34a; font-weight: bold; } | |
| .escalate { color: #dc2626; font-weight: bold; } | |
| """, | |
| ) as demo: | |
| gr.HTML(""" | |
| <div class="header"> | |
| <h1>π§ Multi-Domain Support Triage Agent</h1> | |
| <p style="color: #6b7280;"> | |
| Powered by <strong>Groq (LLaMA 3)</strong> + <strong>BM25 Retrieval</strong><br> | |
| Handles: HackerRank Β· Claude AI Β· Visa | |
| </p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| ticket_input = gr.Textbox( | |
| label="π Enter support issue", | |
| placeholder="Describe the customer's problem...", | |
| lines=4, | |
| ) | |
| submit_btn = gr.Button("π Triage this ticket", variant="primary", size="lg") | |
| gr.Examples( | |
| examples=[[e] for e in EXAMPLES], | |
| inputs=[ticket_input], | |
| label="π Example tickets (click to try)", | |
| ) | |
| with gr.Column(scale=2): | |
| classify_out = gr.Textbox(label="π· Classification", lines=3, interactive=False) | |
| action_out = gr.Textbox(label="β‘ Action Decision", lines=1, interactive=False) | |
| reason_out = gr.Textbox(label="π Escalation Reason", lines=2, interactive=False) | |
| sources_out = gr.Textbox(label="π Retrieved Sources", lines=3, interactive=False) | |
| response_out = gr.Textbox( | |
| label="π¬ Agent Response", | |
| lines=6, | |
| interactive=False, | |
| show_copy_button=True, | |
| ) | |
| gr.HTML(""" | |
| <div style="text-align:center; margin-top:20px; color:#9ca3af; font-size:0.85em;"> | |
| Built for HackerRank Orchestrate Hackathon 2026 Β· Groq API Β· BM25 Retrieval Β· LLaMA 3.3 70B | |
| </div> | |
| """) | |
| submit_btn.click( | |
| fn=triage, | |
| inputs=[ticket_input], | |
| outputs=[classify_out, action_out, reason_out, sources_out, response_out], | |
| ) | |
| ticket_input.submit( | |
| fn=triage, | |
| inputs=[ticket_input], | |
| outputs=[classify_out, action_out, reason_out, sources_out, response_out], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch(share=False) | |