Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -37,43 +37,64 @@ THRESHOLDS = {
|
|
37 |
"projection": 0.09, "recovery phase": 0.33, "threat": 0.15
|
38 |
}
|
39 |
|
40 |
-
|
41 |
-
# ——— 3) Emotional-tone tagging (no abuse_score / DARVO) —————————————————————————————
|
42 |
def get_emotional_tone_tag(emotion_profile, patterns):
|
43 |
-
|
44 |
-
disgust = emotion_profile.get("disgust", 0)
|
45 |
sadness = emotion_profile.get("sadness", 0)
|
46 |
joy = emotion_profile.get("joy", 0)
|
47 |
neutral = emotion_profile.get("neutral", 0)
|
|
|
|
|
48 |
fear = emotion_profile.get("fear", 0)
|
49 |
|
50 |
-
# 1
|
51 |
-
if
|
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 |
-
return "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
|
78 |
return None
|
79 |
|
@@ -95,7 +116,13 @@ def analyze_message(text):
|
|
95 |
if prob >= THRESHOLDS[label]
|
96 |
]
|
97 |
|
98 |
-
# 4)
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
tone_tag = get_emotional_tone_tag(emotion_profile, active_patterns)
|
100 |
|
101 |
return {
|
@@ -105,7 +132,7 @@ def analyze_message(text):
|
|
105 |
}
|
106 |
|
107 |
|
108 |
-
# ——— 5) Composite wrapper (handles
|
109 |
def analyze_composite(uploaded_file, *texts):
|
110 |
outputs = []
|
111 |
|
@@ -153,10 +180,12 @@ message_inputs = [gr.Textbox(label=f"Message {i+1}") for i in range(3)]
|
|
153 |
|
154 |
iface = gr.Interface(
|
155 |
fn=analyze_composite,
|
156 |
-
inputs=[
|
|
|
|
|
157 |
outputs=gr.Textbox(label="Analysis"),
|
158 |
-
title="Tether Analyzer (
|
159 |
-
description="Emotion profiling, pattern tags, and tone
|
160 |
)
|
161 |
|
162 |
if __name__ == "__main__":
|
|
|
37 |
"projection": 0.09, "recovery phase": 0.33, "threat": 0.15
|
38 |
}
|
39 |
|
40 |
+
# ——— 3) Emotional-tone tagging (detailed categories) —————————————————————————————
|
|
|
41 |
def get_emotional_tone_tag(emotion_profile, patterns):
|
42 |
+
# unpack emotion scores
|
|
|
43 |
sadness = emotion_profile.get("sadness", 0)
|
44 |
joy = emotion_profile.get("joy", 0)
|
45 |
neutral = emotion_profile.get("neutral", 0)
|
46 |
+
disgust = emotion_profile.get("disgust", 0)
|
47 |
+
anger = emotion_profile.get("anger", 0)
|
48 |
fear = emotion_profile.get("fear", 0)
|
49 |
|
50 |
+
# 1. Performative Regret
|
51 |
+
if (
|
52 |
+
sadness > 0.4 and
|
53 |
+
any(p in patterns for p in ["blame shifting", "guilt tripping", "recovery phase"])
|
54 |
+
):
|
55 |
+
return "performative regret"
|
56 |
+
|
57 |
+
# 2. Coercive Warmth
|
58 |
+
if (
|
59 |
+
(joy > 0.3 or sadness > 0.4) and
|
60 |
+
any(p in patterns for p in ["control", "gaslighting"])
|
61 |
+
):
|
62 |
+
return "coercive warmth"
|
63 |
+
|
64 |
+
# 3. Cold Invalidation
|
65 |
+
if (
|
66 |
+
(neutral + disgust) > 0.5 and
|
67 |
+
any(p in patterns for p in ["dismissiveness", "projection", "obscure language"])
|
68 |
+
):
|
69 |
+
return "cold invalidation"
|
70 |
+
|
71 |
+
# 4. Genuine Vulnerability
|
72 |
+
if (
|
73 |
+
(sadness + fear) > 0.5 and
|
74 |
+
all(p == "recovery phase" for p in patterns)
|
75 |
+
):
|
76 |
+
return "genuine vulnerability"
|
77 |
+
|
78 |
+
# 5. Emotional Threat
|
79 |
+
if (
|
80 |
+
(anger + disgust) > 0.5 and
|
81 |
+
any(p in patterns for p in ["control", "threat", "insults", "dismissiveness"])
|
82 |
+
):
|
83 |
+
return "emotional threat"
|
84 |
+
|
85 |
+
# 6. Weaponized Sadness
|
86 |
+
if (
|
87 |
+
sadness > 0.6 and
|
88 |
+
any(p in patterns for p in ["guilt tripping", "projection"])
|
89 |
+
):
|
90 |
+
return "weaponized sadness"
|
91 |
+
|
92 |
+
# 7. Toxic Resignation
|
93 |
+
if (
|
94 |
+
neutral > 0.5 and
|
95 |
+
any(p in patterns for p in ["dismissiveness", "obscure language"])
|
96 |
+
):
|
97 |
+
return "toxic resignation"
|
98 |
|
99 |
return None
|
100 |
|
|
|
116 |
if prob >= THRESHOLDS[label]
|
117 |
]
|
118 |
|
119 |
+
# 4) add recovery-phase on apology keywords
|
120 |
+
low = text.lower()
|
121 |
+
if any(k in low for k in ["sorry", "apolog", "forgive"]):
|
122 |
+
if "recovery phase" not in active_patterns:
|
123 |
+
active_patterns.append("recovery phase")
|
124 |
+
|
125 |
+
# 5) tone tagging with detailed rules
|
126 |
tone_tag = get_emotional_tone_tag(emotion_profile, active_patterns)
|
127 |
|
128 |
return {
|
|
|
132 |
}
|
133 |
|
134 |
|
135 |
+
# ——— 5) Composite wrapper (handles uploads + text boxes) ——————————————————————————
|
136 |
def analyze_composite(uploaded_file, *texts):
|
137 |
outputs = []
|
138 |
|
|
|
180 |
|
181 |
iface = gr.Interface(
|
182 |
fn=analyze_composite,
|
183 |
+
inputs=[
|
184 |
+
gr.File(file_types=[".txt", ".png", ".jpg", ".jpeg"], label="Upload text or image")
|
185 |
+
] + message_inputs,
|
186 |
outputs=gr.Textbox(label="Analysis"),
|
187 |
+
title="Tether Analyzer (detailed tone tags)",
|
188 |
+
description="Emotion profiling, pattern tags, and nuanced tone categories—no abuse score or DARVO."
|
189 |
)
|
190 |
|
191 |
if __name__ == "__main__":
|