# Smart Customer Support Assistant (Enhanced UI Version) # Note: Enhanced UI with role avatars, structured suggestions, and end chat functionality import streamlit as st from transformers import pipeline import re 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") text_generator = pipeline("text2text-generation", model="declare-lab/flan-alpaca-base") candidate_tasks = [ "change mobile plan", "top up balance", "report service outage", "ask for billing support", "reactivate service", "cancel subscription", "check account status", "upgrade device" ] def generate_response(intent, human=True): if human: prompt = ( f"You are a telecom customer service agent. For the customer intent '{intent}', provide a helpful reply using this 3-part format: " "[Greeting: short polite opener.] [Middle: Mention customer is currently using Plan X at ¥X/month (fictional), recommend Plan Y with XXGB at ¥Y/month (fictional).] [Ending: Ask if they want to proceed.]" ) else: prompt = ( f"You are a helpful telecom AI assistant. Answer the customer intent '{intent}' in a short, friendly, single sentence. Offer relevant support or recommendation directly, using fictional placeholders like Plan X, ¥X, 10GB etc." ) return text_generator(prompt, max_new_tokens=80, do_sample=False)[0]['generated_text'] urgent_emotions = {"anger", "frustration", "anxiety", "urgency", "afraid", "annoyed"} moderate_emotions = {"confused", "sad", "tired", "concerned", "sadness"} 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 st.set_page_config(page_title="Smart Customer Support Assistant", layout="wide") st.sidebar.title("📁 Customer Selector") if "customers" not in st.session_state: st.session_state.customers = {"Customer A": [], "Customer B": [], "Customer C": []} customer_names = list(st.session_state.customers.keys()) selected_customer = st.sidebar.selectbox("Choose a customer:", customer_names) if "chat_sessions" not in st.session_state: st.session_state.chat_sessions = {} if selected_customer not in st.session_state.chat_sessions: st.session_state.chat_sessions[selected_customer] = { "chat": [], "system_result": None, "agent_reply": "", "support_required": "", "user_input": "" } session = st.session_state.chat_sessions[selected_customer] st.title("Smart Customer Support Assistant (for Agents Only)") st.markdown("### Conversation") for msg in session["chat"]: avatar = "👤" if msg['role'] == 'user' else ("🤖" if msg.get("auto") else "👨‍💼") with st.chat_message(msg['role'], avatar=avatar): st.markdown(msg['content']) col1, col2 = st.columns([6,1]) with col1: session["user_input"] = st.text_input("Enter customer message:", value=session["user_input"]) with col2: analyze_clicked = st.button("Analyze", use_container_width=True) if analyze_clicked and session["user_input"].strip(): user_input = session["user_input"] session["chat"].append({"role": "user", "content": user_input}) session["user_input"] = "" 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 if final_score < 0.5 and top_intents: intent = top_intents[0] response = generate_response(intent, human=False) session["chat"].append({"role": "assistant", "content": response, "auto": True}) session["system_result"] = None session["support_required"] = "🟢 Automated response handled this request." else: session["system_result"] = { "emotion": emotion_label, "tone": "Urgent" if emotion_score > 0.8 else "Concerned" if emotion_score > 0.5 else "Calm", "intents": top_intents } session["support_required"] = "🔴 Human support required." session["agent_reply"] = "" if session["support_required"]: st.markdown(f"### {session['support_required']}") st.subheader("Agent Response Console") session["agent_reply"] = st.text_area("Compose your reply:", value=session["agent_reply"]) if st.button("Send Reply"): if session["agent_reply"].strip(): session["chat"].append({"role": "assistant", "content": session["agent_reply"], "auto": False}) session["agent_reply"] = "" session["system_result"] = None session["support_required"] = "" if session["system_result"] is not None: st.markdown("#### Customer Status") st.markdown(f"- **Emotion:** {session['system_result']['emotion'].capitalize()}") st.markdown(f"- **Tone:** {session['system_result']['tone']}") st.markdown("#### Detected Customer Needs") for intent in session['system_result']['intents']: suggestion = generate_response(intent, human=True) st.markdown(f"**• {intent.capitalize()}**") st.code(suggestion) if st.button("End Conversation"): session["chat"] = [] session["system_result"] = None session["agent_reply"] = "" session["support_required"] = "" session["user_input"] = "" st.success("Conversation ended and cleared.")