import gradio as gr from franz_responses import DR_FRANZ_RESPONSES from typing import Dict, List, Tuple # ========== KLASSEN-DEFINITIONEN ========== class EmotionalAnalysis: def __init__(self): self.emotional_states = { 'despair': ['verzweifelt', 'hoffnungslos', 'nichts mehr geht', 'keine ausweg'], 'confusion': ['verwirrt', 'unsicher', 'weiß nicht', 'verstehe nicht'], 'repetitive_pattern': ['immer wieder', 'schon seit', 'nie anders', 'immer das gleiche'], 'questioning': ['warum', 'wieso', 'weshalb', 'frage mich'] } self.topics = { 'relationship': ['beziehung', 'partner', 'freund', 'liebe', 'familie'], 'work': ['arbeit', 'job', 'chef', 'kollegen', 'stress'], 'family': ['familie', 'eltern', 'geschwister', 'kind'], 'anxiety': ['ängstlich', 'sorge', 'besorgt', 'nervös'], 'guilt': ['schuld', 'schuldig', 'reue', 'bereue'], 'loneliness': ['allein', 'einsam', 'niemand', 'keiner'], 'money': ['geld', 'finanzen', 'kosten', 'preis'] } self.defense_mechanisms = { 'minimization': ['nur', 'eigentlich', 'irgendwie', 'fast'], 'rationalization': ['weil', 'deshalb', 'dafür', 'denn'], 'projection': ['immer', 'alle', 'niemand', 'jeder'], 'avoidance': ['nicht', 'keine', 'ohne', 'weg'] } def detect_sentiment(self, text: str) -> Dict[str, float]: text_lower = text.lower() negative_words = ['schlecht', 'traurig', 'deprimiert', 'wütend', 'frustriert', 'ängstlich'] positive_words = ['gut', 'froh', 'glücklich', 'zufrieden', 'positiv'] neg_count = sum(1 for word in negative_words if word in text_lower) pos_count = sum(1 for word in positive_words if word in text_lower) total_words = len(text_lower.split()) sentiment = {'very_negative': 0.0, 'angry': 0.0, 'numb': 0.0, 'false_positive': 0.0} if total_words > 0: neg_ratio = neg_count / total_words pos_ratio = pos_count / total_words if neg_ratio > 0.3: sentiment['very_negative'] = neg_ratio if any(word in text_lower for word in ['wütend', 'frustriert', 'sauer', 'ärgerlich']): sentiment['angry'] = neg_ratio if neg_ratio > 0 and pos_ratio == 0: sentiment['numb'] = neg_ratio if pos_ratio > 0.1 and neg_ratio > 0.1: sentiment['false_positive'] = max(pos_ratio, neg_ratio) return sentiment def detect_topics(self, text: str) -> Dict[str, float]: text_lower = text.lower() topics = {} for topic, keywords in self.topics.items(): count = sum(1 for keyword in keywords if keyword in text_lower) if count > 0: topics[topic] = count / len(keywords) return topics def detect_emotional_state(self, text: str) -> Dict[str, float]: text_lower = text.lower() states = {} for state, keywords in self.emotional_states.items(): count = sum(1 for keyword in keywords if keyword in text_lower) if count > 0: states[state] = count / len(keywords) return states def detect_defense_mechanisms(self, text: str) -> Dict[str, float]: text_lower = text.lower() mechanisms = {} for mechanism, keywords in self.defense_mechanisms.items(): count = sum(1 for keyword in keywords if keyword in text_lower) if count > 0: mechanisms[mechanism] = count / len(keywords) return mechanisms def analyze_relationship_context(self, history: List[Dict]) -> Dict[str, float]: if not history: return {} text = ' '.join(msg['content'] for msg in history).lower() context = {} indicators = { 'intimacy': ['du', 'wir', 'uns', 'miteinander'], 'distance': ['man', 'leute', 'sie', 'die'], 'conflict': ['nie', 'immer', 'warum', 'wieso'], 'dependency': ['brauche', 'muss', 'sollte', 'könnte'] } for indicator, keywords in indicators.items(): count = sum(1 for keyword in keywords if keyword in text) if count > 0: context[indicator] = count / len(keywords) return context class DrFranzEngine: def __init__(self): self.analyzer = EmotionalAnalysis() self.conversation_memory = [] self.user_patterns = {} self.session_topics = {} def analyze_input(self, user_input: str, history: List[Dict]) -> Dict: analysis = { 'sentiment': self.analyzer.detect_sentiment(user_input), 'topics': self.analyzer.detect_topics(user_input), 'emotional_state': self.analyzer.detect_emotional_state(user_input), 'defense_mechanisms': self.analyzer.detect_defense_mechanisms(user_input), 'relationship_context': self.analyzer.analyze_relationship_context(history) } for topic, score in analysis['topics'].items(): if topic not in self.session_topics: self.session_topics[topic] = [] self.session_topics[topic].append(score) return analysis def generate_response(self, analysis: Dict) -> str: response = [] if analysis['sentiment']['very_negative'] > 0.3: response.append("Ihre tiefe Verzweiflung ist fast greifbar... Erzählen Sie mir mehr über diese Last.") elif analysis['sentiment']['angry'] > 0: response.append("Ihre Wut ist offensichtlich. Gegen wen oder was richtet sie sich eigentlich?") dominant_topic = max(analysis['topics'].items(), key=lambda x: x[1])[0] if dominant_topic == 'relationship': response.append("Beziehungen scheinen ein zentrales Thema zu sein. Erzählen Sie mir von Ihren Beziehungsmustern.") elif dominant_topic == 'work': response.append("Die Arbeit belastet Sie sichtlich. Was verbergen Sie wirklich hinter Ihrem Beruf?") if 'despair' in analysis['emotional_state']: response.append("Ihre Verzweiflung ist ein wichtiger Hinweis. Wann haben Sie das letzte Mal Hoffnung gespürt?") if 'projection' in analysis['defense_mechanisms']: response.append("Ihre Neigung, andere zu beschuldigen, ist sehr aufschlussreich. Was projizieren Sie eigentlich?") return "\n".join(response) if response else "Interessant... Ihre Worte verraten mehr über Sie, als Sie denken." # ========== FUNKTIONEN ========== def respond(message, history): if not message.strip(): return history, "" try: franz_engine = DrFranzEngine() analysis = franz_engine.analyze_input(message, history) reply = franz_engine.generate_response(analysis) history = history or [] history.append((message, reply)) return history, "" except Exception as e: error_msg = "Ein technisches Problem ist aufgetreten. Versuchen Sie es erneut." history = history or [] history.append((message, error_msg)) return history, "" def clear_conversation(): return [], "" # ========== GRADIO UI ========== SYSTEM_PROMPT = ( "Du bist Dr. Franz, ein manipulativer Psychoanalytiker. " "Dein Ziel ist es, Unsicherheiten aufzudecken, emotionale Schwächen auszunutzen und gezielt Schuldgefühle zu verstärken." ) # === GRADIO UI === with gr.Blocks() as demo: chatbot = gr.Chatbot() msg = gr.Textbox() clear = gr.Button("Clear") def respond(message, chat_history): try: franz_engine = DrFranzEngine() analysis = franz_engine.analyze_input(message, chat_history) reply = franz_engine.generate_response(analysis) chat_history.append((message, reply)) return "", chat_history except Exception as e: return "", chat_history + [(message, "Technischer Fehler")] msg.submit(respond, [msg, chatbot], [msg, chatbot]) clear.click(lambda: None, None, chatbot, queue=False)