Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -2,123 +2,101 @@ import streamlit as st
|
|
2 |
from transformers import pipeline
|
3 |
import re
|
4 |
|
5 |
-
# Load
|
6 |
-
emotion_classifier = pipeline("text-classification", model="bhadresh-savani/distilbert-base-uncased-emotion", top_k=
|
7 |
intent_classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")
|
|
|
8 |
|
9 |
# Candidate intents
|
10 |
candidate_tasks = [
|
11 |
"change mobile plan",
|
12 |
-
"upgrade phone",
|
13 |
"top up balance",
|
14 |
"report service outage",
|
15 |
"ask for billing support",
|
16 |
-
"request human support",
|
17 |
"reactivate service",
|
18 |
"cancel subscription",
|
19 |
-
"check account status"
|
|
|
20 |
]
|
21 |
|
22 |
-
#
|
23 |
urgent_emotions = {"anger", "annoyance", "disgust", "frustration", "sadness"}
|
24 |
moderate_emotions = {"confusion", "concern", "nervousness", "fear"}
|
25 |
|
26 |
-
|
27 |
-
def calculate_support_score(text, emotion):
|
28 |
-
score = 0.0
|
29 |
-
|
30 |
-
# Emotion-based scoring
|
31 |
if emotion in urgent_emotions:
|
32 |
-
|
33 |
elif emotion in moderate_emotions:
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
if "!" in text:
|
38 |
-
score += 0.1 * min(text.count("!"), 3) # max +0.3
|
39 |
-
|
40 |
-
# Keyword triggers
|
41 |
-
urgent_keywords = ["not working", "out of service", "no signal", "urgent", "immediately", "stopped"]
|
42 |
-
for kw in urgent_keywords:
|
43 |
-
if kw in text.lower():
|
44 |
-
score += 0.2
|
45 |
-
break
|
46 |
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
"change mobile plan": "You can change your mobile plan by visiting your account dashboard or exploring our latest offers here: [link].",
|
53 |
-
"top up balance": "To restore service, please top up your balance through our payment portal: [link].",
|
54 |
-
"check account status": "You can check your account status and active services via our self-service portal: [link].",
|
55 |
-
}
|
56 |
-
return intent_responses.get(top_intent.lower(), "We have received your request and are processing it.")
|
57 |
|
58 |
-
#
|
59 |
-
st.set_page_config(page_title="
|
60 |
-
st.title("π
|
61 |
|
62 |
-
user_input = st.text_area("
|
63 |
|
64 |
-
if st.button("Analyze"):
|
65 |
if user_input.strip() == "":
|
66 |
-
st.warning("Please enter a message
|
67 |
else:
|
68 |
-
with st.spinner("
|
69 |
-
|
70 |
-
# 1. Emotion Analysis
|
71 |
-
emotion_results = emotion_classifier(user_input)
|
72 |
-
top_emotion = emotion_results[0][0]
|
73 |
-
emotion_label = top_emotion['label']
|
74 |
-
emotion_score = top_emotion['score']
|
75 |
|
76 |
-
#
|
77 |
-
|
|
|
|
|
78 |
|
79 |
-
#
|
80 |
intent_result = intent_classifier(user_input, candidate_tasks)
|
81 |
-
|
82 |
-
top_scores = intent_result['scores']
|
83 |
-
intent_pairs = list(zip(top_labels, top_scores))
|
84 |
-
filtered_intents = [(label, score) for label, score in intent_pairs if score > 0.15]
|
85 |
-
|
86 |
-
# Display emotion
|
87 |
-
st.subheader("π Emotion Analysis")
|
88 |
-
st.write(f"**Primary Emotion**: {emotion_label}")
|
89 |
-
st.write(f"**Confidence Score**: {emotion_score:.2f}")
|
90 |
-
|
91 |
-
# Display support recommendation
|
92 |
-
st.subheader("ποΈ Human Support Priority")
|
93 |
-
st.write(f"**Support Score**: {support_score:.2f}")
|
94 |
-
if support_score >= 0.7:
|
95 |
-
st.error("π΄ Strongly Recommend Human Support")
|
96 |
-
elif support_score >= 0.4:
|
97 |
-
st.warning("π Consider Human Support")
|
98 |
-
else:
|
99 |
-
st.success("π’ Automated Response is Sufficient")
|
100 |
-
|
101 |
-
# Output decision
|
102 |
-
st.subheader("π§ System Recommendation")
|
103 |
-
if support_score < 0.4:
|
104 |
-
top_intent = top_labels[0]
|
105 |
-
st.markdown(f"π€ **Auto-reply Recommendation**: _{top_intent}_")
|
106 |
-
st.info(generate_auto_reply(top_intent))
|
107 |
-
else:
|
108 |
-
st.markdown("π©βπΌ **Customer Intent Summary for Human Agent:**")
|
109 |
|
110 |
-
|
111 |
-
|
112 |
-
st.markdown(f"- **Primary Intent**: {filtered_intents[0][0]} (confidence: {filtered_intents[0][1]:.2f})")
|
113 |
|
114 |
-
|
115 |
-
|
116 |
-
for label, score in filtered_intents[1:]:
|
117 |
-
st.markdown(f"- {label} (confidence: {score:.2f})")
|
118 |
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
else:
|
124 |
-
st.
|
|
|
2 |
from transformers import pipeline
|
3 |
import re
|
4 |
|
5 |
+
# Load models
|
6 |
+
emotion_classifier = pipeline("text-classification", model="bhadresh-savani/distilbert-base-uncased-emotion", top_k=1)
|
7 |
intent_classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")
|
8 |
+
text_generator = pipeline("text2text-generation", model="google/flan-t5-base", max_new_tokens=100)
|
9 |
|
10 |
# Candidate intents
|
11 |
candidate_tasks = [
|
12 |
"change mobile plan",
|
|
|
13 |
"top up balance",
|
14 |
"report service outage",
|
15 |
"ask for billing support",
|
|
|
16 |
"reactivate service",
|
17 |
"cancel subscription",
|
18 |
+
"check account status",
|
19 |
+
"upgrade device"
|
20 |
]
|
21 |
|
22 |
+
# Emotion scoring
|
23 |
urgent_emotions = {"anger", "annoyance", "disgust", "frustration", "sadness"}
|
24 |
moderate_emotions = {"confusion", "concern", "nervousness", "fear"}
|
25 |
|
26 |
+
def get_emotion_score(emotion):
|
|
|
|
|
|
|
|
|
27 |
if emotion in urgent_emotions:
|
28 |
+
return 1.0
|
29 |
elif emotion in moderate_emotions:
|
30 |
+
return 0.6
|
31 |
+
else:
|
32 |
+
return 0.2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
+
def get_content_score(text, top_intents):
|
35 |
+
score = 0.0
|
36 |
+
trigger_words = ["out of service", "urgent", "not working", "stopped", "can't", "immediately"]
|
37 |
+
if any(kw in text.lower() for kw in trigger_words):
|
38 |
+
score += 0.3
|
39 |
+
if any(label in ["top up balance", "reactivate service", "report service outage"] for label in top_intents):
|
40 |
+
score += 0.4
|
41 |
+
if any(label in ["change mobile plan", "ask for billing support"] for label in top_intents):
|
42 |
+
score += 0.2
|
43 |
+
return min(score + 0.1, 1.0)
|
44 |
|
45 |
+
def generate_reply(input_text, intent):
|
46 |
+
prompt = f"Generate a polite and helpful customer service reply to this intent: '{intent}'. Customer said: '{input_text}'"
|
47 |
+
return text_generator(prompt)[0]['generated_text']
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
+
# UI
|
50 |
+
st.set_page_config(page_title="Customer Support Assistant", layout="centered")
|
51 |
+
st.title("π Smart Customer Support Assistant (for Agents Only)")
|
52 |
|
53 |
+
user_input = st.text_area("Enter customer's message or complaint:", height=150)
|
54 |
|
55 |
+
if st.button("Analyze Message"):
|
56 |
if user_input.strip() == "":
|
57 |
+
st.warning("Please enter a customer message.")
|
58 |
else:
|
59 |
+
with st.spinner("Processing..."):
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
+
# Emotion detection
|
62 |
+
emotion_result = emotion_classifier(user_input)
|
63 |
+
emotion_label = emotion_result[0]['label']
|
64 |
+
emotion_score = get_emotion_score(emotion_label)
|
65 |
|
66 |
+
# Intent detection
|
67 |
intent_result = intent_classifier(user_input, candidate_tasks)
|
68 |
+
top_intents = [label for label, score in zip(intent_result['labels'], intent_result['scores']) if score > 0.2]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
+
# Content score
|
71 |
+
content_score = get_content_score(user_input, top_intents)
|
|
|
72 |
|
73 |
+
# Final decision score
|
74 |
+
final_score = (0.5 * emotion_score) + (0.5 * content_score)
|
|
|
|
|
75 |
|
76 |
+
st.subheader("π§Ύ System Summary")
|
77 |
+
|
78 |
+
if final_score < 0.5:
|
79 |
+
st.markdown("### π’ This message was handled automatically.")
|
80 |
+
if top_intents:
|
81 |
+
auto_intent = top_intents[0]
|
82 |
+
auto_reply = generate_reply(user_input, auto_intent)
|
83 |
+
st.markdown("#### π€ Auto-Response Sent to User:")
|
84 |
+
st.success(auto_reply)
|
85 |
+
else:
|
86 |
+
st.info("No clear intent detected. A general auto-reply was used.")
|
87 |
+
else:
|
88 |
+
st.markdown("### π΄ Human Support Required")
|
89 |
+
|
90 |
+
# Customer Profile Summary
|
91 |
+
st.markdown("#### π€ Customer Status:")
|
92 |
+
st.write(f"- **Emotion detected**: {emotion_label.capitalize()}")
|
93 |
+
st.write(f"- **Tone**: {'Urgent' if emotion_score > 0.8 else 'Concerned' if emotion_score > 0.5 else 'Calm'}")
|
94 |
+
|
95 |
+
if top_intents:
|
96 |
+
st.markdown("#### π§© Detected Customer Needs:")
|
97 |
+
for intent in top_intents:
|
98 |
+
reply = generate_reply(user_input, intent)
|
99 |
+
st.markdown(f"**β’ {intent.capitalize()}**")
|
100 |
+
st.write(f"Recommended Action: {reply}")
|
101 |
else:
|
102 |
+
st.warning("No clear intent detected. Manual review recommended.")
|