Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,57 +1,108 @@
|
|
1 |
import gradio as gr
|
2 |
-
from transformers import pipeline
|
3 |
import re
|
|
|
4 |
|
5 |
-
# Load
|
6 |
-
sst_classifier =
|
7 |
"text-classification",
|
8 |
-
model="SamanthaStorm/tether-sst",
|
9 |
top_k=None,
|
10 |
truncation=True
|
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 |
iface = gr.Interface(
|
50 |
-
fn=
|
51 |
-
inputs=gr.Textbox(lines=4, placeholder="Paste message here..."),
|
52 |
outputs="text",
|
53 |
-
title="Tether SST
|
54 |
-
description="
|
55 |
)
|
56 |
|
57 |
iface.launch()
|
|
|
1 |
import gradio as gr
|
|
|
2 |
import re
|
3 |
+
from transformers import pipeline as hf_pipeline
|
4 |
|
5 |
+
# Load models
|
6 |
+
sst_classifier = hf_pipeline(
|
7 |
"text-classification",
|
8 |
+
model="SamanthaStorm/tether-sst",
|
9 |
top_k=None,
|
10 |
truncation=True
|
11 |
)
|
12 |
|
13 |
+
emotion_pipeline = hf_pipeline(
|
14 |
+
"text-classification",
|
15 |
+
model="j-hartmann/emotion-english-distilroberta-base",
|
16 |
+
top_k=None,
|
17 |
+
truncation=True
|
18 |
+
)
|
19 |
+
|
20 |
+
# Functions
|
21 |
+
def get_emotion_profile(text):
|
22 |
+
emotions = emotion_pipeline(text)
|
23 |
+
if isinstance(emotions, list) and isinstance(emotions[0], list):
|
24 |
+
emotions = emotions[0]
|
25 |
+
return {e['label'].lower(): round(e['score'], 3) for e in emotions}
|
26 |
+
|
27 |
+
def get_emotional_tone_tag(emotions, sentiment, patterns, abuse_score):
|
28 |
+
sadness = emotions.get("sadness", 0)
|
29 |
+
joy = emotions.get("joy", 0)
|
30 |
+
neutral = emotions.get("neutral", 0)
|
31 |
+
disgust = emotions.get("disgust", 0)
|
32 |
+
anger = emotions.get("anger", 0)
|
33 |
+
fear = emotions.get("fear", 0)
|
34 |
+
|
35 |
+
if (
|
36 |
+
sadness > 0.4 and
|
37 |
+
any(p in patterns for p in ["blame shifting", "guilt tripping", "recovery phase"]) and
|
38 |
+
(sentiment == "undermining" or abuse_score > 40)
|
39 |
+
):
|
40 |
+
return "performative regret"
|
41 |
+
if (
|
42 |
+
(joy > 0.3 or sadness > 0.4) and
|
43 |
+
any(p in patterns for p in ["control", "gaslighting"]) and
|
44 |
+
sentiment == "undermining"
|
45 |
+
):
|
46 |
+
return "coercive warmth"
|
47 |
+
if (
|
48 |
+
(neutral + disgust) > 0.5 and
|
49 |
+
any(p in patterns for p in ["dismissiveness", "projection", "obscure language"]) and
|
50 |
+
sentiment == "undermining"
|
51 |
+
):
|
52 |
+
return "cold invalidation"
|
53 |
+
if (
|
54 |
+
(sadness + fear) > 0.5 and
|
55 |
+
sentiment == "supportive" and
|
56 |
+
all(p in ["recovery phase"] for p in patterns)
|
57 |
+
):
|
58 |
+
return "genuine vulnerability"
|
59 |
+
if (
|
60 |
+
(anger + disgust) > 0.5 and
|
61 |
+
any(p in patterns for p in ["control", "threat", "insults", "dismissiveness"]) and
|
62 |
+
sentiment == "undermining"
|
63 |
+
):
|
64 |
+
return "emotional threat"
|
65 |
+
if (
|
66 |
+
sadness > 0.6 and
|
67 |
+
any(p in patterns for p in ["guilt tripping", "projection"]) and
|
68 |
+
sentiment == "undermining"
|
69 |
+
):
|
70 |
+
return "weaponized sadness"
|
71 |
+
if (
|
72 |
+
neutral > 0.5 and
|
73 |
+
any(p in patterns for p in ["dismissiveness", "obscure language"]) and
|
74 |
+
sentiment == "undermining"
|
75 |
+
):
|
76 |
+
return "toxic resignation"
|
77 |
+
|
78 |
+
return None
|
79 |
+
|
80 |
+
# Main interface function
|
81 |
+
def analyze_message(text):
|
82 |
+
sst_result = sst_classifier(text)[0]
|
83 |
+
sentiment_label = "supportive" if sst_result["label"] == "LABEL_0" else "undermining"
|
84 |
+
sentiment_score = round(sst_result["score"] * 100, 2)
|
85 |
+
|
86 |
+
emotions = get_emotion_profile(text)
|
87 |
+
emotion_summary = "\n".join([f"{k.title()}: {v:.2f}" for k, v in emotions.items()])
|
88 |
+
|
89 |
+
|
90 |
+
tone_tag = get_emotional_tone_tag(emotions, sentiment_label, patterns, abuse_score)
|
91 |
+
tone_output = tone_tag if tone_tag else "None detected"
|
92 |
+
|
93 |
+
return (
|
94 |
+
f"🧠 Sentiment: {sentiment_label.title()} ({sentiment_score}%)\n\n"
|
95 |
+
f"🎭 Emotional Profile:\n{emotion_summary}\n\n"
|
96 |
+
f"🔍 Tone Tag: {tone_output}"
|
97 |
+
)
|
98 |
|
99 |
+
# Gradio app
|
100 |
iface = gr.Interface(
|
101 |
+
fn=analyze_message,
|
102 |
+
inputs=gr.Textbox(lines=4, placeholder="Paste a message here..."),
|
103 |
outputs="text",
|
104 |
+
title="Tether SST + Emotional Tone Tagger",
|
105 |
+
description="Detects Supportive vs Undermining sentiment, emotion profile, and custom tone tags using behavioral logic."
|
106 |
)
|
107 |
|
108 |
iface.launch()
|