Spaces:
Sleeping
Sleeping
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() |