# 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