File size: 6,031 Bytes
efa60b3
 
66128ac
efa60b3
49f0804
 
 
 
 
 
66128ac
efa60b3
66128ac
0e52653
66128ac
0e52653
66128ac
 
 
 
b35a08e
 
0e52653
 
49f0804
 
 
 
 
 
 
66128ac
b35a08e
49f0804
b35a08e
49f0804
b35a08e
 
 
66128ac
b35a08e
 
 
 
 
 
 
 
 
 
66128ac
b35a08e
2889bc1
 
 
 
 
 
 
 
 
 
 
 
 
e3db4d0
2889bc1
 
e3db4d0
2889bc1
 
 
 
e3db4d0
 
 
2889bc1
 
 
 
 
6e13199
49f0804
b35a08e
 
6e13199
b35a08e
efa60b3
b35a08e
efa60b3
b35a08e
efa60b3
b35a08e
6e13199
49f0804
b35a08e
49f0804
b35a08e
66128ac
b35a08e
66128ac
da8d9a8
66128ac
b35a08e
 
0e52653
b35a08e
 
0e52653
b35a08e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
da8d9a8
66128ac
b35a08e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import streamlit as st
from transformers import pipeline
import re

# Load upgraded models
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 intents
candidate_tasks = [
    "change mobile plan",
    "top up balance",
    "report service outage",
    "ask for billing support",
    "reactivate service",
    "cancel subscription",
    "check account status",
    "upgrade device"
]

# Emotion categories (updated)
urgent_emotions = {"anger", "frustration", "anxiety", "urgency", "afraid", "annoyed"}
moderate_emotions = {"confused", "sad", "tired", "concerned"}

def get_emotion_label(emotion_result):
    sorted_emotions = sorted(emotion_result[0], key=lambda x: x['score'], reverse=True)
    return 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

def get_content_score(text, top_intents):
    score = 0.0
    trigger_words = ["out of service", "urgent", "not working", "stopped", "can't", "immediately"]
    if any(kw in text.lower() for kw in trigger_words):
        score += 0.3
    if any(label in ["top up balance", "reactivate service", "report service outage"] for label in top_intents):
        score += 0.4
    if any(label in ["change mobile plan", "ask for billing support"] for label in top_intents):
        score += 0.2
    return min(score + 0.1, 1.0)

def generate_reply(input_text, intent):
    # Intent-specific suggestion sentences
    intent_solutions = {
        "top up balance": "Your balance is ¥12. Current promo: recharge ¥100 get ¥5 bonus.",
        "reactivate service": "Your service is suspended due to unpaid ¥38. Recharge to restore within 30 mins.",
        "change mobile plan": "You're on Plan Basic (¥68/5GB). Suggest Plan Plus (¥98/20GB).",
        "check account status": "Your data usage is 3.2GB/5GB. Balance: ¥12. Calls left: 22 mins.",
        "ask for billing support": "Last bill was ¥96 for March. Includes data overage ¥16.",
        "cancel subscription": "Your contract ends on 2025-06-30. No penalty after this date.",
        "upgrade device": "You're eligible for upgrade. New iPhone plan starts at ¥399/month.",
        "report service outage": "We're detecting signal issues in your area (ZIP: XXX). Engineers notified."
    }

    # Intent-specific closing question
    intent_closings = {
        "top up balance": "Would you like to proceed with a recharge now?",
        "reactivate service": "Shall I help you restart your service now?",
        "report service outage": "Would you like me to file a service report for you?",
        "change mobile plan": "Would you like to switch to a better plan?",
        "ask for billing support": "Shall I show your last 3 billing records?",
        "cancel subscription": "Shall I guide you through cancellation?",
        "check account status": "Want a summary of your usage and balance?",
        "upgrade device": "Would you like me to show available upgrade options?"
    }

    solution = intent_solutions.get(intent.lower(), "Here's how we can assist you with this issue.")
    closing = intent_closings.get(intent.lower(), "Is there anything else I can help with?")
    opening = "Thank you for contacting us. I understand your concern."

    return f"{opening} {solution} {closing}"

# Streamlit UI
st.set_page_config(page_title="Customer Support Assistant", layout="centered")
st.title("📞 Smart Customer Support Assistant (for Agents Only)")

user_input = st.text_area("Enter customer's message or complaint:", height=150)

if st.button("Analyze Message"):
    if user_input.strip() == "":
        st.warning("Please enter a customer message.")
    else:
        with st.spinner("Processing..."):

            # Emotion detection (updated)
            emotion_result = emotion_classifier(user_input)
            emotion_label = get_emotion_label(emotion_result)
            emotion_score = get_emotion_score(emotion_label)

            # Intent detection
            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
            content_score = get_content_score(user_input, top_intents)

            # Final decision score
            final_score = (0.5 * emotion_score) + (0.5 * content_score)

            st.subheader("🧾 System Summary")

            if final_score < 0.5:
                st.markdown("### 🟢 This message was handled automatically.")
                if top_intents:
                    auto_intent = top_intents[0]
                    auto_reply = generate_reply(user_input, auto_intent)
                    st.markdown("#### 🤖 Auto-Response Sent to User:")
                    st.success(auto_reply)
                else:
                    st.info("No clear intent detected. A general auto-reply was used.")
            else:
                st.markdown("### 🔴 Human Support Required")

                # Customer Profile Summary
                st.markdown("#### 👤 Customer Status:")
                st.write(f"- **Emotion detected**: {emotion_label.capitalize()}")
                st.write(f"- **Tone**: {'Urgent' if emotion_score > 0.8 else 'Concerned' if emotion_score > 0.5 else 'Calm'}")

                if top_intents:
                    st.markdown("#### 🧩 Detected Customer Needs:")
                    for intent in top_intents:
                        reply = generate_reply(user_input, intent)
                        st.markdown(f"**• {intent.capitalize()}**")
                        st.write(reply)
                else:
                    st.warning("No clear intent detected. Manual review recommended.")