Spaces:
Sleeping
Sleeping
# Smart Customer Support Assistant (Enhanced UI Version) | |
# Note: Core analysis logic remains unchanged | |
import streamlit as st | |
from transformers import pipeline | |
import re | |
# ------------------------------ | |
# Load models (same as before) | |
# ------------------------------ | |
emotion_classifier = pipeline( | |
"text-classification", | |
model="j-hartmann/emotion-english-distilroberta-base", | |
return_all_scores=True | |
) | |
intent_classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli") | |
# ------------------------------ | |
# Candidate tasks / templates | |
# ------------------------------ | |
candidate_tasks = [ | |
"change mobile plan", | |
"top up balance", | |
"report service outage", | |
"ask for billing support", | |
"reactivate service", | |
"cancel subscription", | |
"check account status", | |
"upgrade device" | |
] | |
intent_solutions = { | |
"top up balance": "Your balance is ¥12. Promo: recharge ¥100 get ¥5 bonus.", | |
"reactivate service": "Service suspended due to unpaid ¥38. Recharge to restore in 30 mins.", | |
"change mobile plan": "You're on Basic (¥68/5GB). Suggest Plus (¥98/20GB).", | |
"check account status": "Data: 3.2GB/5GB. Balance: ¥12. Calls left: 22 mins.", | |
"ask for billing support": "Last bill: ¥96 (Mar). Includes ¥16 overage.", | |
"cancel subscription": "Contract ends: 2025-06-30. No penalty after this date.", | |
"upgrade device": "Eligible for upgrade. New iPhone plan: ¥399/month.", | |
"report service outage": "Signal issues detected (ZIP: XXX). Engineers notified." | |
} | |
intent_closings = { | |
"top up balance": "Proceed with recharge now?", | |
"reactivate service": "Shall I help restart your service?", | |
"report service outage": "Shall I file a service report?", | |
"change mobile plan": "Switch to a better plan?", | |
"ask for billing support": "Show recent billing records?", | |
"cancel subscription": "Guide you through cancellation?", | |
"check account status": "Show usage and balance?", | |
"upgrade device": "See available upgrades?" | |
} | |
urgent_emotions = {"anger", "frustration", "anxiety", "urgency", "afraid", "annoyed"} | |
moderate_emotions = {"confused", "sad", "tired", "concerned", "sadness"} | |
# ------------------------------ | |
# Emotion processing | |
# ------------------------------ | |
def refine_emotion_label(text, model_emotion): | |
text_lower = text.lower() | |
urgent_keywords = ["fix", "now", "immediately", "urgent", "can't", "need", "asap"] | |
exclamations = text.count("!") | |
upper_words = sum(1 for word in text.split() if word.isupper()) | |
signal_score = sum([ | |
any(word in text_lower for word in urgent_keywords), | |
exclamations >= 2, | |
upper_words >= 1 | |
]) | |
if model_emotion.lower() in {"joy", "neutral", "sadness"} and signal_score >= 2: | |
return "urgency" | |
return model_emotion | |
def get_emotion_label(emotion_result, text): | |
sorted_emotions = sorted(emotion_result[0], key=lambda x: x['score'], reverse=True) | |
return refine_emotion_label(text, sorted_emotions[0]['label']) | |
def get_emotion_score(emotion): | |
if emotion.lower() in urgent_emotions: | |
return 1.0 | |
elif emotion.lower() in moderate_emotions: | |
return 0.6 | |
else: | |
return 0.2 | |
# ------------------------------ | |
# Streamlit UI Logic | |
# ------------------------------ | |
st.set_page_config(page_title="Smart Customer Support Assistant", layout="centered") | |
st.title("Smart Customer Support Assistant (for Agents Only)") | |
# Session state to store chat | |
if 'chat' not in st.session_state: | |
st.session_state.chat = [] | |
if 'system_result' not in st.session_state: | |
st.session_state.system_result = None | |
if 'agent_reply' not in st.session_state: | |
st.session_state.agent_reply = "" | |
# Display chat history | |
for msg in st.session_state.chat: | |
with st.chat_message(msg['role']): | |
st.markdown(msg['content']) | |
# Customer input + Analyze button | |
col1, col2 = st.columns([5,1]) | |
with col1: | |
user_input = st.text_input("Enter customer message:", key="user_input") | |
with col2: | |
if st.button("Analyze"): | |
if user_input.strip(): | |
# Run analysis pipeline | |
emotion_result = emotion_classifier(user_input) | |
emotion_label = get_emotion_label(emotion_result, user_input) | |
emotion_score = get_emotion_score(emotion_label) | |
intent_result = intent_classifier(user_input, candidate_tasks) | |
top_intents = [label for label, score in zip(intent_result['labels'], intent_result['scores']) if score > 0.15][:3] | |
content_score = 0.0 | |
if any(x in user_input.lower() for x in ["out of service", "can't", "urgent", "immediately"]): | |
content_score += 0.4 | |
if any(label in ["top up balance", "reactivate service"] for label in top_intents): | |
content_score += 0.4 | |
final_score = 0.5 * emotion_score + 0.5 * content_score | |
# Store user message | |
st.session_state.chat.append({"role": "user", "content": user_input}) | |
# Auto response or escalate to agent | |
if final_score < 0.5 and top_intents: | |
intent = top_intents[0] | |
response = f"Thank you for contacting us. I understand your concern. {intent_solutions[intent]} {intent_closings[intent]}" | |
st.session_state.chat.append({"role": "assistant", "content": response}) | |
else: | |
st.session_state.system_result = { | |
"emotion": emotion_label, | |
"tone": "Urgent" if emotion_score > 0.8 else "Concerned" if emotion_score > 0.5 else "Calm", | |
"intents": top_intents | |
} | |
# If human support needed | |
if st.session_state.system_result: | |
st.markdown("---") | |
st.subheader("Agent Response Panel") | |
# Agent editable response | |
st.session_state.agent_reply = st.text_area("Compose your reply:", value=st.session_state.agent_reply) | |
if st.button("Send Reply"): | |
if st.session_state.agent_reply.strip(): | |
st.session_state.chat.append({"role": "assistant", "content": st.session_state.agent_reply}) | |
st.session_state.agent_reply = "" | |
st.session_state.system_result = None | |
# Context info | |
st.markdown("#### Customer Status") | |
st.markdown(f"- **Emotion:** {st.session_state.system_result['emotion'].capitalize()}") | |
st.markdown(f"- **Tone:** {st.session_state.system_result['tone']}") | |
# Suggested replies | |
st.markdown("#### Detected Customer Needs") | |
for intent in st.session_state.system_result['intents']: | |
st.markdown(f"**• {intent.capitalize()}**") | |
suggestion = f"Thank you for contacting us. I understand your concern. {intent_solutions[intent]} {intent_closings[intent]}" | |
if st.button(f"Use suggestion for '{intent}'", key=intent): | |
st.session_state.agent_reply = suggestion | |