File size: 4,116 Bytes
865bd23
0d8fdf6
834f0ff
865bd23
f4d2a9a
834f0ff
865bd23
834f0ff
865bd23
 
 
 
f4d2a9a
834f0ff
 
 
 
 
 
 
f4d2a9a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
834f0ff
 
 
 
 
 
f4d2a9a
 
834f0ff
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f4d2a9a
834f0ff
f4d2a9a
834f0ff
 
 
 
f4d2a9a
834f0ff
 
 
f4d2a9a
 
834f0ff
f4d2a9a
 
834f0ff
 
 
 
 
 
 
865bd23
f4d2a9a
865bd23
834f0ff
 
865bd23
834f0ff
 
865bd23
 
 
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
import gradio as gr
import re
from transformers import pipeline as hf_pipeline

# Load SST sentiment classifier
sst_classifier = hf_pipeline(
    "text-classification",
    model="SamanthaStorm/tether-sst",
    top_k=None,
    truncation=True
)

# Load emotion classifier
emotion_pipeline = hf_pipeline(
    "text-classification",
    model="j-hartmann/emotion-english-distilroberta-base",
    top_k=None,
    truncation=True
)

# Load Tether's abuse pattern classifier
abuse_classifier = hf_pipeline(
    "text-classification",
    model="SamanthaStorm/tether-multilabel-v2",
    top_k=None,
    truncation=True
)

# Extract abuse pattern labels
def get_abuse_patterns(text, threshold=0.5):
    results = abuse_classifier(text)
    if isinstance(results, list) and isinstance(results[0], list):
        results = results[0]
    return [r['label'] for r in results if r['score'] >= threshold]

# Emotion extraction
def get_emotion_profile(text):
    emotions = emotion_pipeline(text)
    if isinstance(emotions, list) and isinstance(emotions[0], list):
        emotions = emotions[0]
    return {e['label'].lower(): round(e['score'], 3) for e in emotions}

# Emotional tone tagging based on behavior + emotion + sentiment
def get_emotional_tone_tag(emotions, sentiment, patterns, abuse_score=0):
    sadness = emotions.get("sadness", 0)
    joy = emotions.get("joy", 0)
    neutral = emotions.get("neutral", 0)
    disgust = emotions.get("disgust", 0)
    anger = emotions.get("anger", 0)
    fear = emotions.get("fear", 0)

    if (
        sadness > 0.4 and
        any(p in patterns for p in ["blame shifting", "guilt tripping", "recovery phase"]) and
        (sentiment == "undermining" or abuse_score > 40)
    ):
        return "performative regret"
    if (
        (joy > 0.3 or sadness > 0.4) and
        any(p in patterns for p in ["control", "gaslighting"]) and
        sentiment == "undermining"
    ):
        return "coercive warmth"
    if (
        (neutral + disgust) > 0.5 and
        any(p in patterns for p in ["dismissiveness", "projection", "obscure language"]) and
        sentiment == "undermining"
    ):
        return "cold invalidation"
    if (
        (sadness + fear) > 0.5 and
        sentiment == "supportive" and
        all(p in ["recovery phase"] for p in patterns)
    ):
        return "genuine vulnerability"
    if (
        (anger + disgust) > 0.5 and
        any(p in patterns for p in ["control", "threat", "insults", "dismissiveness"]) and
        sentiment == "undermining"
    ):
        return "emotional threat"
    if (
        sadness > 0.6 and
        any(p in patterns for p in ["guilt tripping", "projection"]) and
        sentiment == "undermining"
    ):
        return "weaponized sadness"
    if (
        neutral > 0.5 and
        any(p in patterns for p in ["dismissiveness", "obscure language"]) and
        sentiment == "undermining"
    ):
        return "toxic resignation"

    return None

# Analysis logic
def analyze_message(text):
    # Sentiment
    sst_result = sst_classifier(text)[0]
    sentiment_label = "supportive" if sst_result["label"] == "LABEL_0" else "undermining"
    sentiment_score = round(sst_result["score"] * 100, 2)

    # Emotions
    emotions = get_emotion_profile(text)
    emotion_summary = "\n".join([f"{k.title()}: {v:.2f}" for k, v in emotions.items()])

    # Abuse patterns (used internally)
    patterns = get_abuse_patterns(text)

    # Tone tag
    tone_tag = get_emotional_tone_tag(emotions, sentiment_label, patterns)
    tone_output = tone_tag if tone_tag else "None detected"

    return (
        f"🧠 Sentiment: {sentiment_label.title()} ({sentiment_score}%)\n\n"
        f"🎭 Emotional Profile:\n{emotion_summary}\n\n"
        f"🔍 Tone Tag: {tone_output}"
    )

# Gradio UI
iface = gr.Interface(
    fn=analyze_message,
    inputs=gr.Textbox(lines=4, placeholder="Paste a message here..."),
    outputs="text",
    title="Tether SST + Emotional Tone Tagger",
    description="Detects Supportive vs Undermining sentiment, emotion profile, and custom tone tags using behavioral logic."
)

iface.launch()