MalikShehram's picture
Upload 9 files
8cadb90 verified
"""
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)