adiprog14's picture
Update app.py
7779048 verified
Raw
History Blame Contribute Delete
3.85 kB
import os
import gradio as gr
import pandas as pd
import faiss
from sentence_transformers import SentenceTransformer
from huggingface_hub import hf_hub_download, InferenceClient
# ---------- Load data + search index from the dataset repo ----------
REPO = "adiprog14/lingrow-support-tickets"
idx_path = hf_hub_download(repo_id=REPO, filename="lingrow_faiss.index", repo_type="dataset")
uniq_path = hf_hub_download(repo_id=REPO, filename="lingrow_unique_tickets.parquet", repo_type="dataset")
index = faiss.read_index(idx_path)
unique_df = pd.read_parquet(uniq_path)
embedder = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2")
# ---------- Generation client (RAG) ----------
GEN_MODEL = "meta-llama/Llama-3.3-70B-Instruct"
CONFIDENCE_THRESHOLD = 0.5
client = InferenceClient(token=os.environ.get("HF_TOKEN"))
def find_similar(query, k=4):
q = embedder.encode([query], convert_to_numpy=True)
faiss.normalize_L2(q)
scores, idx = index.search(q, k)
out = []
for s, i in zip(scores[0], idx[0]):
row = unique_df.iloc[i]
out.append((float(s), row["topic_key"], row["customer_message"], row["resolution_steps"]))
return out
def generate_reply(question, results):
context = "\n\n".join(
f"Ticket {i+1} (topic: {t}):\nCustomer: {m}\nVerified solution: {a}"
for i, (s, t, m, a) in enumerate(results)
)
prompt = f"""You are the Lingrow Support Copilot. Lingrow is a real-time
multilingual translation app (live captions, spoken translation, QR-join sessions).
A customer asked: "{question}"
Here are the most similar past tickets and their VERIFIED solutions:
{context}
Write ONE helpful support reply (3-5 sentences max). Rules:
- Base your answer ONLY on the verified solutions above. Do not invent features.
- If the question has multiple issues, address each one using the matching ticket.
- Be friendly, direct, and specific (mention exact buttons/icons when given).
- IMPORTANT: Reply in the SAME language the customer used. If the question is in
Hebrew, your entire reply must be in Hebrew. If Spanish, reply in Spanish."""
resp = client.chat_completion(
model=GEN_MODEL,
messages=[{"role": "user", "content": prompt}],
max_tokens=220,
temperature=0.3,
)
return resp.choices[0].message.content.strip()
def support_copilot(message, history):
results = find_similar(message, k=4)
top_score = results[0][0]
if top_score < CONFIDENCE_THRESHOLD:
return rtl_wrap("I'm not confident I found a matching case for this. "
"Could you describe the issue in a bit more detail? "
"For example: what were you doing, and what did you see on screen?")
try:
return rtl_wrap(generate_reply(message, results))
except Exception as e:
print(f"GENERATION FAILED: {e}", flush=True)
best = results[0]
return rtl_wrap(f"Thanks for reaching out! Here's how to solve this: {best[3]}")
rtl_css = """
.message-wrap .message, .message-wrap p, .prose p, .prose li {
unicode-bidi: plaintext;
text-align: start;
}
textarea, input[type="text"] {
unicode-bidi: plaintext;
text-align: start;
}
"""
def rtl_wrap(text):
"""Wrap reply so the browser aligns it by its language (Hebrew -> right)."""
return f'<div dir="auto">{text}</div>'
demo = gr.ChatInterface(
fn=support_copilot,
title="Lingrow Support Copilot",
description=("Ask about any Lingrow issue — login, sessions, captions, audio, "
"translation — and get an answer based on verified past solutions."),
examples=[
"I keep getting an invalid token error when I log in",
"The subtitles are too small and I can't hear any audio",
"How do I invite more people into my live session?",
],
)
demo.launch()