From 48e099ccf95233e8dbea28988dd9203ef951f6bf Mon Sep 17 00:00:00 2001 From: sudsnprasanna26 Date: Wed, 3 Sep 2025 23:58:12 -0400 Subject: [PATCH] Add files via upload --- submissions/README.md | 173 +++++++++ submissions/config.json | 31 ++ submissions/dating_coach.py | 414 ++++++++++++++++++++ submissions/rag_dating_coach.py | 647 ++++++++++++++++++++++++++++++++ submissions/requirements.txt | 13 + submissions/run_coach.py | 46 +++ 6 files changed, 1324 insertions(+) create mode 100644 submissions/README.md create mode 100644 submissions/config.json create mode 100644 submissions/dating_coach.py create mode 100644 submissions/rag_dating_coach.py create mode 100644 submissions/requirements.txt create mode 100644 submissions/run_coach.py diff --git a/submissions/README.md b/submissions/README.md new file mode 100644 index 0000000..d950dc7 --- /dev/null +++ b/submissions/README.md @@ -0,0 +1,173 @@ +# RAG-Enhanced Real-Time Dating Coach + +**AI@GT Applied Research Team Submission by John Doe** + +## Project Title +RAG-Enhanced Real-Time Dating Coach - Generative Conversation Assistant + +## What It Does + +This application is an advanced real-time conversation coach that uses **Retrieval-Augmented Generation (RAG)** with embeddings to provide dynamic, contextual conversation suggestions. Instead of pre-coded templates, it generates authentic responses by retrieving and adapting examples from a large corpus of real conversations. + +### 🚀 **Key RAG Features:** +- **Semantic Search**: Uses sentence transformers to find contextually relevant conversation examples +- **Vector Database**: FAISS index with 5,000+ processed conversation examples for fast retrieval +- **Dynamic Generation**: Creates unique suggestions adapted to current conversation context +- **Context-Aware Retrieval**: Considers sentiment, emotion, engagement, and topics for relevant examples +- **Structured Output**: Generates coherent, natural suggestions based on retrieved conversations + +### 🔥 **Advanced AI Features:** +- **Real-time sentiment analysis** using `cardiffnlp/twitter-roberta-base-sentiment-latest` +- **Emotion detection** using `j-hartmann/emotion-english-distilroberta-base` +- **Sentence embeddings** using `all-MiniLM-L6-v2` for semantic similarity +- **RAG pipeline** with `the-rizz/the-rizz-corpus` dataset (55,000+ examples) +- **Conversational lowercase style** for natural, casual suggestions +- **Multi-layered context analysis** (sentiment + emotion + engagement + topics) +- **Boundary detection** with respectful communication prioritization + +### What Makes It Special: +- **🧠 RAG-Powered Intelligence**: Retrieves contextually relevant examples from thousands of conversations +- **🎯 Dynamic Generation**: No fixed templates - generates unique suggestions every time +- **📊 Semantic Understanding**: Uses vector embeddings to understand conversation meaning and context +- **🔍 Context-Aware Retrieval**: Considers sentiment, emotion, engagement level, and conversation topics +- **💬 Natural conversational tone** - suggestions feel authentic and human-like +- **🚫 Never auto-sends** - all suggestions are for human consideration only +- **🛡️ Boundary-aware** - includes advanced boundary detection and respectful communication +- **🔒 Privacy-focused** - runs locally with FAISS vector database, no external API calls +- **📚 Continuously learning** - adapts suggestions based on conversation corpus analysis + +## How to Run It + +### Prerequisites +- Python 3.7 or higher +- Internet connection (for initial model download) + +### Installation Steps + +1. **Clone or download the project:** + ```bash + cd submissions/John_Doe/ + ``` + +2. **Create a virtual environment (recommended):** + ```bash + python -m venv venv + # On Windows: + venv\Scripts\activate + # On Mac/Linux: + source venv/bin/activate + ``` + +3. **Install required dependencies:** + ```bash + pip install -r requirements.txt + ``` + +4. **Run the application (recommended - RAG-enhanced):** + ```bash + python run_coach.py + ``` + +5. **Or run directly:** + ```bash + python rag_dating_coach.py # RAG-enhanced version (recommended) + python dating_coach.py # Original version + ``` + +### First Run Notes +- The first run will download AI models (~500MB total) - this may take a few minutes +- Models are cached locally for faster subsequent launches +- The app works entirely on CPU - no GPU required! + +## How to Use + +1. **Start the application** - A GUI window will open +2. **Paste conversation text** in the left panel (copy from your messaging app) +3. **Click "Analyze Conversation"** or enable auto-analysis +4. **Review AI suggestions** in the right panel +5. **Use suggestions as inspiration** - adapt them to your authentic voice +6. **Save analysis** for later review if desired + +### Example Usage (RAG-Enhanced): +``` +Conversation Input: +alex: hey! how was your weekend? +sam: it was incredible! went rock climbing for the first time +alex: no way! that sounds terrifying but amazing +sam: right?? i was so scared at first but the adrenaline rush was unreal +alex: i've always wanted to try that! where did you go? +sam: there's this awesome indoor gym downtown, perfect for beginners +alex: that's so cool! maybe i should check it out sometime +sam: you totally should! i'd love to go again, maybe we could go together? + +RAG-Enhanced Analysis Output: +sentiment: Positive (0.99) +emotion: Joy (0.76) +engagement: High +rag system: ✅ Active + +🤖 rag-generated suggestions based on similar conversations: +💬 that's so exciting! rock climbing sounds like such an adventure +💬 i love how you stepped out of your comfort zone! that's really inspiring +💬 you're making me want to try it too! i'd definitely be up for going together +💬 the fact that you faced your fear and loved it shows what an amazing person you are +🔥 high engagement + shared activity interest: perfect opportunity for connection! +✨ they're clearly excited and open to spending time together +🎯 next move: express genuine interest and suggest a specific plan +``` + +## Technical Details + +### AI Models & RAG Architecture: +- **Sentiment Analysis**: `cardiffnlp/twitter-roberta-base-sentiment-latest` - Robust Twitter-trained sentiment classifier +- **Emotion Recognition**: `j-hartmann/emotion-english-distilroberta-base` - Multi-emotion classification +- **Embeddings**: `all-MiniLM-L6-v2` - Sentence transformer for semantic similarity +- **Vector Database**: FAISS with cosine similarity for fast retrieval +- **Conversation Corpus**: `the-rizz/the-rizz-corpus` - 55,000+ conversation examples, filtered to 5,000 high-quality examples + +### RAG Pipeline Architecture: +1. **Corpus Processing**: Clean and filter conversation examples for quality +2. **Embedding Generation**: Create vector representations using sentence transformers +3. **Index Creation**: Build FAISS vector database for fast similarity search +4. **Context Analysis**: Analyze current conversation for sentiment, emotion, topics +5. **Retrieval**: Find most relevant conversation examples using semantic search +6. **Generation**: Adapt retrieved examples to current context and generate suggestions +7. **Filtering**: Apply safety filters and context relevance scoring + +### Safety Features: +- **Boundary Detection**: Scans for keywords indicating discomfort or disinterest +- **Respectful Templates**: Pre-vetted response suggestions that avoid toxic patterns +- **Context Awareness**: Analyzes recent message history rather than isolated responses +- **No Auto-sending**: Human always remains in control of actual communication + +### Privacy & Ethics: +- **Local Processing**: All analysis happens on your device +- **No Data Collection**: Conversations are not stored or transmitted +- **Consent-Focused**: Emphasizes respectful communication and boundary recognition +- **Educational Purpose**: Includes tips for healthy relationship communication + +## File Structure +``` +submissions/John_Doe/ +├── rag_dating_coach.py # RAG-Enhanced main application (RECOMMENDED) +├── dating_coach.py # Original implementation for comparison +├── run_coach.py # Simple launcher script +├── config.json # Configuration settings +├── requirements.txt # Python dependencies +└── README.md # This documentation +``` + +## Future Enhancements +- Voice analysis integration +- Multi-language support +- Advanced personality matching +- Integration with popular messaging platforms +- Mobile app version + +## Disclaimer +This tool is designed to promote respectful, authentic communication. It should be used as a learning aid, not as a replacement for genuine human connection and emotional intelligence. Always prioritize consent, boundaries, and authentic self-expression in your relationships. + +--- + +**Developed for AI@GT Applied Research Team Assessment** +*Focus: Hugging Face transformers, ethical AI, user interface design* diff --git a/submissions/config.json b/submissions/config.json new file mode 100644 index 0000000..bdf729d --- /dev/null +++ b/submissions/config.json @@ -0,0 +1,31 @@ +{ + "models": { + "sentiment_model": "cardiffnlp/twitter-roberta-base-sentiment-latest", + "emotion_model": "j-hartmann/emotion-english-distilroberta-base" + }, + "analysis": { + "max_messages_to_analyze": 10, + "auto_analysis_delay": 2.0, + "min_message_length": 2 + }, + "safety": { + "boundary_keywords": [ + "stop", "uncomfortable", "not interested", "leave me alone", + "busy", "can't talk", "not now", "please stop", "don't want to", + "feeling pressured", "need space", "not in the mood" + ], + "respect_filters": true, + "enable_boundary_detection": true + }, + "ui": { + "window_width": 1000, + "window_height": 700, + "auto_analyze": false, + "save_history": true + }, + "suggestions": { + "max_suggestions": 4, + "include_next_steps": true, + "personalization_level": "medium" + } +} diff --git a/submissions/dating_coach.py b/submissions/dating_coach.py new file mode 100644 index 0000000..297a766 --- /dev/null +++ b/submissions/dating_coach.py @@ -0,0 +1,414 @@ +""" +Real-Time Dating Coach - AI@GT Applied Research Team Submission +A real-time conversation coach that analyzes chat sentiment and provides respectful reply suggestions. +""" + +import tkinter as tk +from tkinter import scrolledtext, ttk +import threading +import time +from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification +import re +from datetime import datetime +from typing import List, Dict, Tuple +import json +import random +from datasets import load_dataset + +class DatingCoach: + def __init__(self): + # Initialize Hugging Face models + print("Loading AI models...") + self.sentiment_analyzer = pipeline("sentiment-analysis", + model="cardiffnlp/twitter-roberta-base-sentiment-latest") + self.emotion_analyzer = pipeline("text-classification", + model="j-hartmann/emotion-english-distilroberta-base") + + # Load the rizz corpus for better conversation training + print("Loading rizz corpus dataset...") + try: + self.rizz_dataset = load_dataset('the-rizz/the-rizz-corpus') + self.rizz_examples = self.rizz_dataset['train']['text'] + print(f"Loaded {len(self.rizz_examples)} conversation examples") + except Exception as e: + print(f"Could not load rizz corpus: {e}") + self.rizz_examples = [] + + # Initialize conversation state + self.conversation_history = [] + self.analysis_results = [] + self.suggestions_history = [] + + # Updated respectful responses with lowercase, conversational style + self.respectful_responses = { + 'positive': [ + "that's really cool! tell me more about {topic}", + "i love that! what got you into {topic}?", + "that sounds amazing! how did you discover {topic}?", + "no way, that's awesome! i'd love to hear more about {topic}", + "that's so interesting! what's your favorite thing about {topic}?" + ], + 'neutral': [ + "that's cool! what do you think about {topic}?", + "interesting! how do you feel about {topic}?", + "i'd love to hear more about your thoughts on {topic}", + "tell me more about that", + "what's that like for you?" + ], + 'negative': [ + "i understand that might be tough to talk about", + "thanks for sharing that with me", + "i appreciate you being open about that", + "that sounds challenging", + "i hear you on that" + ], + 'flirty_positive': [ + "you're making me curious about {topic} now 😊", + "i love how passionate you are about {topic}", + "you have great taste! what else are you into?", + "that's really attractive, someone who knows what they like", + "you're full of surprises! what other hidden talents do you have?" + ], + 'playful': [ + "okay now you're just showing off 😏", + "are you trying to impress me? because it's working", + "you're making this conversation way too interesting", + "i'm starting to think you're cooler than you let on", + "well now i definitely need to know more about you" + ] + } + + self.boundary_keywords = ['stop', 'uncomfortable', 'not interested', 'leave me alone', + 'busy', 'can\'t talk', 'not now', 'please stop'] + + # GUI setup + self.setup_gui() + + def setup_gui(self): + """Setup the main GUI interface""" + self.root = tk.Tk() + self.root.title("Real-Time Dating Coach - Respectful Conversation Assistant") + self.root.geometry("1000x700") + self.root.configure(bg='#f0f0f0') + + # Create main frame + main_frame = ttk.Frame(self.root, padding="10") + main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) + + # Title + title_label = ttk.Label(main_frame, text="Real-Time Dating Coach", + font=('Arial', 16, 'bold')) + title_label.grid(row=0, column=0, columnspan=2, pady=(0, 10)) + + # Conversation input area + ttk.Label(main_frame, text="Conversation (paste messages here):").grid(row=1, column=0, sticky=tk.W) + self.conversation_text = scrolledtext.ScrolledText(main_frame, height=10, width=60) + self.conversation_text.grid(row=2, column=0, padx=(0, 10), pady=(0, 10)) + + # Analysis and suggestions area + ttk.Label(main_frame, text="AI Analysis & Suggestions:").grid(row=1, column=1, sticky=tk.W) + self.suggestions_text = scrolledtext.ScrolledText(main_frame, height=10, width=60, + bg='#e8f4f8') + self.suggestions_text.grid(row=2, column=1, pady=(0, 10)) + + # Control buttons + button_frame = ttk.Frame(main_frame) + button_frame.grid(row=3, column=0, columnspan=2, pady=10) + + self.analyze_btn = ttk.Button(button_frame, text="Analyze Conversation", + command=self.analyze_conversation) + self.analyze_btn.pack(side=tk.LEFT, padx=5) + + self.clear_btn = ttk.Button(button_frame, text="Clear All", + command=self.clear_all) + self.clear_btn.pack(side=tk.LEFT, padx=5) + + self.save_btn = ttk.Button(button_frame, text="Save Analysis", + command=self.save_analysis) + self.save_btn.pack(side=tk.LEFT, padx=5) + + # Status area + self.status_label = ttk.Label(main_frame, text="Ready to analyze conversations", + foreground='green') + self.status_label.grid(row=4, column=0, columnspan=2, pady=5) + + # Auto-analysis toggle + self.auto_analyze_var = tk.BooleanVar() + auto_check = ttk.Checkbutton(main_frame, text="Auto-analyze on text change", + variable=self.auto_analyze_var) + auto_check.grid(row=5, column=0, columnspan=2, pady=5) + + # Bind text change event for real-time analysis + self.conversation_text.bind('', self.on_text_change) + + def on_text_change(self, event=None): + """Handle text changes for real-time analysis""" + if self.auto_analyze_var.get(): + # Debounce - only analyze after 2 seconds of no typing + if hasattr(self, 'analyze_timer'): + self.analyze_timer.cancel() + self.analyze_timer = threading.Timer(2.0, self.analyze_conversation) + self.analyze_timer.start() + + def extract_messages(self, text: str) -> List[str]: + """Extract individual messages from conversation text""" + # Split by common message separators + messages = [] + lines = text.strip().split('\n') + + for line in lines: + line = line.strip() + if line and len(line) > 2: # Filter out very short lines + # Remove timestamps and usernames if present + cleaned = re.sub(r'^\d{1,2}:\d{2}.*?:', '', line) + cleaned = re.sub(r'^[A-Za-z\s]+:', '', cleaned) + cleaned = cleaned.strip() + if cleaned: + messages.append(cleaned) + + return messages[-10:] # Last 10 messages for context + + def detect_boundaries(self, messages: List[str]) -> bool: + """Detect if conversation partner is setting boundaries""" + recent_text = ' '.join(messages[-3:]).lower() # Last 3 messages + + for keyword in self.boundary_keywords: + if keyword in recent_text: + return True + + return False + + def extract_rizz_wisdom(self, context: str, sentiment: str) -> List[str]: + """Extract relevant conversation examples from the rizz corpus""" + if not self.rizz_examples: + return [] + + # Look for examples that match the current context/sentiment + relevant_examples = [] + context_lower = context.lower() + + # Sample some examples and filter for relevance + sample_size = min(100, len(self.rizz_examples)) + sampled_examples = random.sample(self.rizz_examples, sample_size) + + for example in sampled_examples: + example_lower = example.lower() + # Look for examples that contain similar themes or are appropriate for the sentiment + if any(word in example_lower for word in ['witty', 'funny', 'light', 'kind', 'conversation']): + # Extract conversational parts (remove system prompts) + clean_example = re.sub(r'<>.*?<>', '', example) + clean_example = clean_example.strip() + + if clean_example and len(clean_example) > 20 and len(clean_example) < 200: + # Make it lowercase and conversational + conversational = clean_example.lower() + # Remove any remaining formatting + conversational = re.sub(r'[<>]', '', conversational) + if conversational not in relevant_examples: + relevant_examples.append(conversational) + + if len(relevant_examples) >= 3: + break + + return relevant_examples[:3] + + def analyze_sentiment_and_emotion(self, messages: List[str]) -> Dict: + """Analyze sentiment and emotion of recent messages""" + if not messages: + return {'sentiment': 'neutral', 'emotion': 'neutral', 'engagement': 'low'} + + recent_text = ' '.join(messages[-3:]) # Analyze last 3 messages + + # Sentiment analysis + sentiment_result = self.sentiment_analyzer(recent_text[:512]) # Truncate if too long + sentiment = sentiment_result[0]['label'] + sentiment_score = sentiment_result[0]['score'] + + # Emotion analysis + emotion_result = self.emotion_analyzer(recent_text[:512]) + emotion = emotion_result[0]['label'] + emotion_score = emotion_result[0]['score'] + + # Engagement analysis based on message length and frequency + avg_length = sum(len(msg) for msg in messages) / len(messages) + engagement = 'high' if avg_length > 20 else 'medium' if avg_length > 10 else 'low' + + return { + 'sentiment': sentiment.lower(), + 'sentiment_score': sentiment_score, + 'emotion': emotion.lower(), + 'emotion_score': emotion_score, + 'engagement': engagement, + 'avg_message_length': avg_length + } + + def generate_suggestions(self, analysis: Dict, messages: List[str]) -> List[str]: + """Generate respectful, conversational suggestions with rizz corpus integration""" + suggestions = [] + + # Check for boundaries first + if self.detect_boundaries(messages): + suggestions.append("⚠️ boundary detected: consider giving them space or asking if they'd prefer to chat later") + suggestions.append("respectful response: 'no worries at all! feel free to reach out whenever you'd like to chat'") + return suggestions + + # Extract potential topics from recent messages + recent_text = ' '.join(messages[-2:]) if len(messages) >= 2 else messages[-1] if messages else "" + + # Get rizz corpus wisdom for context + rizz_examples = self.extract_rizz_wisdom(recent_text, analysis['sentiment']) + + # Generate contextual suggestions based on sentiment + sentiment = analysis['sentiment'] + emotion = analysis['emotion'] + + # Determine conversation style based on emotion and engagement + if analysis['engagement'] == 'high' and sentiment in ['positive', 'joy']: + style = 'flirty_positive' + elif emotion in ['joy', 'surprise'] and analysis['engagement'] in ['medium', 'high']: + style = 'playful' + elif sentiment in ['positive', 'joy', 'optimism']: + style = 'positive' + elif sentiment in ['negative', 'sadness', 'pessimism']: + style = 'negative' + else: + style = 'neutral' + + # Get appropriate response templates + if style in self.respectful_responses: + response_templates = self.respectful_responses[style] + + # Add 2-3 template-based suggestions + for i, template in enumerate(response_templates[:3]): + suggestion = template.format(topic='that') + suggestions.append(f"💬 {suggestion}") + + # Add rizz corpus inspired suggestions + if rizz_examples: + suggestions.append("📚 rizz corpus inspiration:") + for example in rizz_examples[:2]: + # Clean up and make it a suggestion + clean_example = example.strip() + if clean_example and not clean_example.startswith('you are'): + suggestions.append(f" • {clean_example}") + + # Add engagement-based suggestions with lowercase style + if analysis['engagement'] == 'low': + suggestions.append("💡 low engagement detected - maybe ask about their interests or share something fun") + elif analysis['engagement'] == 'high': + suggestions.append("💡 high engagement! great flow - keep the energy up but stay natural") + + # Add conversation flow suggestions + if len(messages) > 5: + suggestions.append("🔄 conversation flowing well - maybe suggest moving to a different topic or activity") + + # Add playful/flirty elements if appropriate + if style in ['flirty_positive', 'playful'] and analysis['engagement'] == 'high': + playful_suggestions = [ + "😏 they seem really engaged - maybe add some light teasing or humor", + "✨ good energy here - you could be a bit more playful", + "🎯 they're responding well - don't be afraid to show your personality" + ] + suggestions.append(random.choice(playful_suggestions)) + + return suggestions[:6] # Limit to 6 suggestions + + def analyze_conversation(self): + """Main analysis function""" + self.status_label.config(text="Analyzing conversation...", foreground='orange') + self.root.update() + + try: + # Get conversation text + conv_text = self.conversation_text.get('1.0', tk.END) + messages = self.extract_messages(conv_text) + + if not messages: + self.suggestions_text.delete('1.0', tk.END) + self.suggestions_text.insert(tk.END, "No messages to analyze. Please paste some conversation text above.") + self.status_label.config(text="No messages found", foreground='red') + return + + # Perform analysis + analysis = self.analyze_sentiment_and_emotion(messages) + suggestions = self.generate_suggestions(analysis, messages) + + # Display results + self.display_analysis(analysis, suggestions, messages) + + # Store results + self.analysis_results.append({ + 'timestamp': datetime.now().isoformat(), + 'analysis': analysis, + 'suggestions': suggestions, + 'message_count': len(messages) + }) + + self.status_label.config(text="Analysis complete!", foreground='green') + + except Exception as e: + self.suggestions_text.delete('1.0', tk.END) + self.suggestions_text.insert(tk.END, f"Error during analysis: {str(e)}") + self.status_label.config(text="Analysis failed", foreground='red') + + def display_analysis(self, analysis: Dict, suggestions: List[str], messages: List[str]): + """Display analysis results in the GUI with conversational lowercase style""" + self.suggestions_text.delete('1.0', tk.END) + + # Analysis summary with conversational tone + self.suggestions_text.insert(tk.END, "🔍 conversation analysis\n") + self.suggestions_text.insert(tk.END, "="*40 + "\n\n") + + self.suggestions_text.insert(tk.END, f"sentiment: {analysis['sentiment'].title()} ({analysis['sentiment_score']:.2f})\n") + self.suggestions_text.insert(tk.END, f"emotion: {analysis['emotion'].title()} ({analysis['emotion_score']:.2f})\n") + self.suggestions_text.insert(tk.END, f"engagement: {analysis['engagement'].title()}\n") + self.suggestions_text.insert(tk.END, f"analyzed {len(messages)} recent messages\n\n") + + # Suggestions with conversational style + self.suggestions_text.insert(tk.END, "💡 conversational suggestions\n") + self.suggestions_text.insert(tk.END, "="*40 + "\n\n") + + for i, suggestion in enumerate(suggestions, 1): + self.suggestions_text.insert(tk.END, f"{suggestion}\n\n") + + # General tips with lowercase conversational style + self.suggestions_text.insert(tk.END, "📋 general vibes\n") + self.suggestions_text.insert(tk.END, "="*40 + "\n") + self.suggestions_text.insert(tk.END, "• always respect boundaries and consent\n") + self.suggestions_text.insert(tk.END, "• listen actively and show genuine interest\n") + self.suggestions_text.insert(tk.END, "• be authentic - use these as inspiration, not scripts\n") + self.suggestions_text.insert(tk.END, "• when in doubt, ask open-ended questions\n") + self.suggestions_text.insert(tk.END, "• keep it playful but respectful\n") + self.suggestions_text.insert(tk.END, "• let your personality shine through\n") + + def clear_all(self): + """Clear all text areas""" + self.conversation_text.delete('1.0', tk.END) + self.suggestions_text.delete('1.0', tk.END) + self.status_label.config(text="Ready to analyze conversations", foreground='green') + + def save_analysis(self): + """Save analysis results to file""" + if not self.analysis_results: + self.status_label.config(text="No analysis to save", foreground='red') + return + + filename = f"dating_coach_analysis_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" + + try: + with open(filename, 'w') as f: + json.dump(self.analysis_results, f, indent=2) + self.status_label.config(text=f"Analysis saved to {filename}", foreground='green') + except Exception as e: + self.status_label.config(text=f"Save failed: {str(e)}", foreground='red') + + def run(self): + """Start the application""" + print("Starting Real-Time Dating Coach...") + print("Remember: This tool is designed to help with respectful, genuine conversation!") + self.root.mainloop() + +if __name__ == "__main__": + # Create and run the dating coach app + coach = DatingCoach() + coach.run() diff --git a/submissions/rag_dating_coach.py b/submissions/rag_dating_coach.py new file mode 100644 index 0000000..329e3a1 --- /dev/null +++ b/submissions/rag_dating_coach.py @@ -0,0 +1,647 @@ +""" +Enhanced Real-Time Dating Coach with RAG and Embedding-based Generation +Uses retrieval-augmented generation with the rizz corpus for dynamic suggestions +""" + +import tkinter as tk +from tkinter import scrolledtext, ttk +import threading +import time +from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification +import re +from datetime import datetime +from typing import List, Dict, Tuple, Optional +import json +import random +import numpy as np +from datasets import load_dataset +from sentence_transformers import SentenceTransformer +import faiss +from dataclasses import dataclass + +@dataclass +class ConversationContext: + """Structured context for conversation analysis""" + messages: List[str] + sentiment: str + emotion: str + engagement_level: str + topics: List[str] + conversation_stage: str + boundary_signals: bool + +class RAGDatingCoach: + def __init__(self): + # Initialize Hugging Face models + print("Loading AI models...") + self.sentiment_analyzer = pipeline("sentiment-analysis", + model="cardiffnlp/twitter-roberta-base-sentiment-latest") + self.emotion_analyzer = pipeline("text-classification", + model="j-hartmann/emotion-english-distilroberta-base") + + # Initialize embedding model for RAG + print("Loading embedding model for RAG...") + self.embedding_model = SentenceTransformer('all-MiniLM-L6-v2') + + # Load and process the rizz corpus for RAG + print("Loading and processing rizz corpus for RAG...") + self.setup_rag_system() + + # Initialize conversation state + self.conversation_history = [] + self.analysis_results = [] + self.suggestions_history = [] + + # Safety filters and respectful response templates (fallback) + self.boundary_keywords = ['stop', 'uncomfortable', 'not interested', 'leave me alone', + 'busy', 'can\'t talk', 'not now', 'please stop', 'don\'t want to', + 'feeling pressured', 'need space', 'not in the mood'] + + # GUI setup + self.setup_gui() + + def setup_rag_system(self): + """Setup the RAG system with rizz corpus embeddings""" + try: + # Load the rizz corpus + self.rizz_dataset = load_dataset('the-rizz/the-rizz-corpus') + raw_examples = self.rizz_dataset['train']['text'] + + print("Processing conversation examples for RAG...") + + # Clean and filter the corpus + self.processed_examples = [] + self.example_metadata = [] + + for i, example in enumerate(raw_examples): + # Clean the example + cleaned = self.clean_conversation_example(example) + if cleaned and self.is_good_example(cleaned): + self.processed_examples.append(cleaned) + + # Extract metadata + metadata = self.extract_example_metadata(cleaned, example) + self.example_metadata.append(metadata) + + if len(self.processed_examples) >= 5000: # Limit for performance + break + + print(f"Processed {len(self.processed_examples)} examples for RAG") + + # Create embeddings for the corpus + print("Creating embeddings for conversation corpus...") + self.corpus_embeddings = self.embedding_model.encode(self.processed_examples) + + # Setup FAISS index for fast similarity search + self.setup_faiss_index() + + print("RAG system ready!") + + except Exception as e: + print(f"Error setting up RAG system: {e}") + self.processed_examples = [] + self.corpus_embeddings = None + self.faiss_index = None + + def clean_conversation_example(self, example: str) -> Optional[str]: + """Clean and extract useful conversation parts from corpus examples""" + # Remove system prompts + cleaned = re.sub(r'<>.*?<>', '', example, flags=re.DOTALL) + + # Remove special tokens + cleaned = re.sub(r'|\[/?INST\]', '', cleaned) + + # Clean up whitespace + cleaned = re.sub(r'\s+', ' ', cleaned).strip() + + # Remove very short or very long examples + if len(cleaned) < 10 or len(cleaned) > 300: + return None + + return cleaned.lower() + + def is_good_example(self, example: str) -> bool: + """Filter for high-quality conversation examples""" + # Check for positive conversation markers + positive_markers = ['funny', 'witty', 'light', 'kind', 'interesting', 'amazing', + 'love', 'awesome', 'great', 'wonderful', 'exciting'] + + # Check for negative markers to avoid + negative_markers = ['rude', 'mean', 'aggressive', 'inappropriate', 'offensive'] + + example_lower = example.lower() + + # Must have some positive markers and no negative ones + has_positive = any(marker in example_lower for marker in positive_markers) + has_negative = any(marker in example_lower for marker in negative_markers) + + return has_positive and not has_negative and len(example.split()) >= 3 + + def extract_example_metadata(self, cleaned_example: str, original: str) -> Dict: + """Extract metadata from conversation examples""" + return { + 'length': len(cleaned_example), + 'word_count': len(cleaned_example.split()), + 'has_question': '?' in cleaned_example, + 'has_emoji': any(char in cleaned_example for char in '😊😏😍🔥💕'), + 'energy_level': self.estimate_energy_level(cleaned_example), + 'conversation_type': self.classify_conversation_type(cleaned_example) + } + + def estimate_energy_level(self, text: str) -> str: + """Estimate the energy level of a conversation example""" + high_energy_words = ['amazing', 'awesome', 'incredible', 'fantastic', 'wow', '!'] + medium_energy_words = ['cool', 'nice', 'good', 'interesting'] + + text_lower = text.lower() + high_count = sum(1 for word in high_energy_words if word in text_lower) + medium_count = sum(1 for word in medium_energy_words if word in text_lower) + + if high_count >= 2 or '!' in text: + return 'high' + elif medium_count >= 1 or high_count >= 1: + return 'medium' + else: + return 'low' + + def classify_conversation_type(self, text: str) -> str: + """Classify the type of conversation""" + if any(word in text.lower() for word in ['flirt', 'cute', 'beautiful', 'attractive']): + return 'flirty' + elif any(word in text.lower() for word in ['funny', 'joke', 'laugh', 'hilarious']): + return 'humorous' + elif any(word in text.lower() for word in ['interest', 'hobby', 'passion', 'love doing']): + return 'interest_based' + else: + return 'general' + + def setup_faiss_index(self): + """Setup FAISS index for fast similarity search""" + if self.corpus_embeddings is not None and len(self.corpus_embeddings) > 0: + # Create FAISS index + dimension = self.corpus_embeddings.shape[1] + self.faiss_index = faiss.IndexFlatIP(dimension) # Inner product for cosine similarity + + # Normalize embeddings for cosine similarity + faiss.normalize_L2(self.corpus_embeddings) + self.faiss_index.add(self.corpus_embeddings.astype('float32')) + + print(f"FAISS index created with {self.faiss_index.ntotal} examples") + else: + self.faiss_index = None + + def retrieve_relevant_examples(self, query: str, context: ConversationContext, k: int = 5) -> List[Dict]: + """Retrieve relevant examples using RAG""" + if self.faiss_index is None or not self.processed_examples: + return [] + + try: + # Create enhanced query with context + enhanced_query = self.create_enhanced_query(query, context) + + # Get query embedding + query_embedding = self.embedding_model.encode([enhanced_query]) + faiss.normalize_L2(query_embedding) + + # Search for similar examples + scores, indices = self.faiss_index.search(query_embedding.astype('float32'), k) + + # Retrieve examples with metadata + retrieved_examples = [] + for score, idx in zip(scores[0], indices[0]): + if idx < len(self.processed_examples): + example = { + 'text': self.processed_examples[idx], + 'score': float(score), + 'metadata': self.example_metadata[idx] if idx < len(self.example_metadata) else {} + } + retrieved_examples.append(example) + + # Filter examples based on context + filtered_examples = self.filter_examples_by_context(retrieved_examples, context) + + return filtered_examples + + except Exception as e: + print(f"Error in RAG retrieval: {e}") + return [] + + def create_enhanced_query(self, original_query: str, context: ConversationContext) -> str: + """Create an enhanced query with conversation context""" + # Add context information to the query + context_parts = [original_query] + + if context.sentiment: + context_parts.append(f"sentiment: {context.sentiment}") + + if context.emotion: + context_parts.append(f"emotion: {context.emotion}") + + if context.topics: + context_parts.append(f"topics: {', '.join(context.topics)}") + + if context.engagement_level: + context_parts.append(f"engagement: {context.engagement_level}") + + return " ".join(context_parts) + + def filter_examples_by_context(self, examples: List[Dict], context: ConversationContext) -> List[Dict]: + """Filter retrieved examples based on conversation context""" + filtered = [] + + for example in examples: + metadata = example['metadata'] + + # Filter based on energy level matching + if context.engagement_level == 'high' and metadata.get('energy_level', 'low') == 'low': + continue + + # Filter based on conversation stage + if context.boundary_signals: + continue # Skip examples when boundaries are detected + + # Prefer examples with similar characteristics + if context.engagement_level == 'high' and metadata.get('energy_level') == 'high': + example['score'] += 0.1 # Boost score for matching energy + + filtered.append(example) + + # Sort by score and return top examples + filtered.sort(key=lambda x: x['score'], reverse=True) + return filtered[:3] # Return top 3 + + def generate_rag_suggestions(self, context: ConversationContext) -> List[str]: + """Generate suggestions using RAG with the conversation context""" + if not context.messages: + return ["start with a friendly greeting!"] + + # Create query from recent messages + recent_text = ' '.join(context.messages[-2:]) + + # Retrieve relevant examples + relevant_examples = self.retrieve_relevant_examples(recent_text, context) + + suggestions = [] + + # Handle boundary detection first + if context.boundary_signals: + suggestions.append("🚨 boundary detected: give them space and respect their comfort level") + suggestions.append("💬 try: 'no worries at all! feel free to reach out whenever you'd like to chat'") + return suggestions + + # Generate suggestions based on retrieved examples + if relevant_examples: + suggestions.append("🤖 rag-generated suggestions based on similar conversations:") + + for i, example in enumerate(relevant_examples[:3], 1): + # Adapt the example to current context + adapted_suggestion = self.adapt_example_to_context(example['text'], context) + suggestions.append(f"💬 option {i}: {adapted_suggestion}") + + # Add context-aware suggestions + contextual_suggestions = self.generate_contextual_suggestions(context) + suggestions.extend(contextual_suggestions) + + # Add engagement tips + engagement_tip = self.generate_engagement_tip(context) + if engagement_tip: + suggestions.append(engagement_tip) + + return suggestions[:6] # Limit to 6 suggestions + + def adapt_example_to_context(self, example_text: str, context: ConversationContext) -> str: + """Adapt retrieved example to current conversation context""" + # Basic adaptation - make it more contextual + adapted = example_text.strip() + + # Make it conversational and contextual + if context.topics: + # Try to incorporate detected topics + main_topic = context.topics[0] if context.topics else "that" + adapted = adapted.replace("it", main_topic).replace("that", main_topic) + + # Adjust energy level based on engagement + if context.engagement_level == 'high' and not any(char in adapted for char in '!😊'): + if not adapted.endswith(('!', '?', '😊')): + adapted += " 😊" + + # Ensure it's conversational lowercase style + if adapted and adapted[0].isupper(): + adapted = adapted[0].lower() + adapted[1:] + + return adapted + + def generate_contextual_suggestions(self, context: ConversationContext) -> List[str]: + """Generate additional contextual suggestions""" + suggestions = [] + + # Based on engagement level + if context.engagement_level == 'high': + if context.sentiment == 'positive': + suggestions.append("🔥 high engagement + positive vibe: perfect time to be a bit more playful!") + else: + suggestions.append("📈 they're engaged: keep the conversation flowing with open questions") + elif context.engagement_level == 'low': + suggestions.append("💡 low engagement: try asking about their interests or sharing something fun") + + # Based on conversation stage + if len(context.messages) > 6: + suggestions.append("🎯 conversation flowing: consider suggesting a specific activity or moving topics") + elif len(context.messages) <= 3: + suggestions.append("🌱 early stage: focus on finding common ground and shared interests") + + return suggestions + + def generate_engagement_tip(self, context: ConversationContext) -> Optional[str]: + """Generate engagement-specific tips""" + if context.engagement_level == 'high' and context.sentiment == 'positive': + return "✨ great chemistry detected: they're really responding well to your energy!" + elif context.boundary_signals: + return "⚠️ respect mode: give them space and let them lead the pace" + elif context.engagement_level == 'medium': + return "📊 steady engagement: you're on the right track, keep being authentic" + else: + return None + + def extract_conversation_topics(self, messages: List[str]) -> List[str]: + """Extract main topics from conversation using simple keyword extraction""" + topics = [] + common_topics = { + 'hiking': ['hike', 'hiking', 'trail', 'mountain', 'outdoor'], + 'travel': ['travel', 'trip', 'vacation', 'visit', 'country'], + 'music': ['music', 'song', 'concert', 'band', 'album'], + 'food': ['food', 'restaurant', 'cooking', 'eat', 'dinner'], + 'work': ['work', 'job', 'career', 'office', 'business'], + 'hobbies': ['hobby', 'interest', 'passion', 'love doing'], + 'movies': ['movie', 'film', 'cinema', 'watch', 'show'], + 'sports': ['sport', 'game', 'play', 'team', 'gym'] + } + + text = ' '.join(messages).lower() + + for topic, keywords in common_topics.items(): + if any(keyword in text for keyword in keywords): + topics.append(topic) + + return topics[:3] # Return top 3 topics + + def determine_conversation_stage(self, messages: List[str]) -> str: + """Determine what stage the conversation is in""" + message_count = len(messages) + + if message_count <= 2: + return 'opening' + elif message_count <= 5: + return 'getting_to_know' + elif message_count <= 10: + return 'building_connection' + else: + return 'established_flow' + + # Keep all the existing methods from the original DatingCoach class + def extract_messages(self, text: str) -> List[str]: + """Extract individual messages from conversation text""" + messages = [] + lines = text.strip().split('\n') + + for line in lines: + line = line.strip() + if line and len(line) > 2: + cleaned = re.sub(r'^\d{1,2}:\d{2}.*?:', '', line) + cleaned = re.sub(r'^[A-Za-z\s]+:', '', cleaned) + cleaned = cleaned.strip() + if cleaned: + messages.append(cleaned) + + return messages[-10:] + + def detect_boundaries(self, messages: List[str]) -> bool: + """Detect if conversation partner is setting boundaries""" + recent_text = ' '.join(messages[-3:]).lower() + + for keyword in self.boundary_keywords: + if keyword in recent_text: + return True + + return False + + def analyze_sentiment_and_emotion(self, messages: List[str]) -> Dict: + """Analyze sentiment and emotion of recent messages""" + if not messages: + return {'sentiment': 'neutral', 'emotion': 'neutral', 'engagement': 'low'} + + recent_text = ' '.join(messages[-3:]) + + sentiment_result = self.sentiment_analyzer(recent_text[:512]) + sentiment = sentiment_result[0]['label'] + sentiment_score = sentiment_result[0]['score'] + + emotion_result = self.emotion_analyzer(recent_text[:512]) + emotion = emotion_result[0]['label'] + emotion_score = emotion_result[0]['score'] + + avg_length = sum(len(msg) for msg in messages) / len(messages) + engagement = 'high' if avg_length > 20 else 'medium' if avg_length > 10 else 'low' + + return { + 'sentiment': sentiment.lower(), + 'sentiment_score': sentiment_score, + 'emotion': emotion.lower(), + 'emotion_score': emotion_score, + 'engagement': engagement, + 'avg_message_length': avg_length + } + + def create_conversation_context(self, messages: List[str], analysis: Dict) -> ConversationContext: + """Create structured conversation context for RAG""" + return ConversationContext( + messages=messages, + sentiment=analysis.get('sentiment', 'neutral'), + emotion=analysis.get('emotion', 'neutral'), + engagement_level=analysis.get('engagement', 'low'), + topics=self.extract_conversation_topics(messages), + conversation_stage=self.determine_conversation_stage(messages), + boundary_signals=self.detect_boundaries(messages) + ) + + def generate_suggestions(self, analysis: Dict, messages: List[str]) -> List[str]: + """Generate suggestions using RAG system""" + # Create conversation context + context = self.create_conversation_context(messages, analysis) + + # Use RAG to generate suggestions + rag_suggestions = self.generate_rag_suggestions(context) + + return rag_suggestions + + # Keep the GUI setup and other methods from original class + def setup_gui(self): + """Setup the main GUI interface with RAG indicators""" + self.root = tk.Tk() + self.root.title("RAG-Enhanced Dating Coach - AI Conversation Assistant") + self.root.geometry("1200x800") + self.root.configure(bg='#f0f0f0') + + main_frame = ttk.Frame(self.root, padding="10") + main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) + + # Title with RAG indicator + title_label = ttk.Label(main_frame, text="RAG-Enhanced Dating Coach", + font=('Arial', 16, 'bold')) + title_label.grid(row=0, column=0, columnspan=2, pady=(0, 5)) + + # Subtitle showing RAG capabilities + subtitle_label = ttk.Label(main_frame, text="Powered by Retrieval-Augmented Generation with 5000+ conversation examples", + font=('Arial', 10), foreground='blue') + subtitle_label.grid(row=1, column=0, columnspan=2, pady=(0, 10)) + + # Conversation input area + ttk.Label(main_frame, text="Conversation (paste messages here):").grid(row=2, column=0, sticky=tk.W) + self.conversation_text = scrolledtext.ScrolledText(main_frame, height=12, width=60) + self.conversation_text.grid(row=3, column=0, padx=(0, 10), pady=(0, 10)) + + # Analysis and suggestions area + ttk.Label(main_frame, text="RAG-Generated Analysis & Suggestions:").grid(row=2, column=1, sticky=tk.W) + self.suggestions_text = scrolledtext.ScrolledText(main_frame, height=12, width=60, + bg='#e8f4f8') + self.suggestions_text.grid(row=3, column=1, pady=(0, 10)) + + # Control buttons + button_frame = ttk.Frame(main_frame) + button_frame.grid(row=4, column=0, columnspan=2, pady=10) + + self.analyze_btn = ttk.Button(button_frame, text="Analyze with RAG", + command=self.analyze_conversation) + self.analyze_btn.pack(side=tk.LEFT, padx=5) + + self.clear_btn = ttk.Button(button_frame, text="Clear All", + command=self.clear_all) + self.clear_btn.pack(side=tk.LEFT, padx=5) + + self.save_btn = ttk.Button(button_frame, text="Save Analysis", + command=self.save_analysis) + self.save_btn.pack(side=tk.LEFT, padx=5) + + # Status area + rag_status = "Ready" if self.faiss_index is not None else "RAG system not available" + self.status_label = ttk.Label(main_frame, text=f"RAG System: {rag_status} | Ready to analyze conversations", + foreground='green' if self.faiss_index else 'orange') + self.status_label.grid(row=5, column=0, columnspan=2, pady=5) + + # Auto-analysis toggle + self.auto_analyze_var = tk.BooleanVar() + auto_check = ttk.Checkbutton(main_frame, text="Auto-analyze with RAG on text change", + variable=self.auto_analyze_var) + auto_check.grid(row=6, column=0, columnspan=2, pady=5) + + self.conversation_text.bind('', self.on_text_change) + + def on_text_change(self, event=None): + """Handle text changes for real-time analysis""" + if self.auto_analyze_var.get(): + if hasattr(self, 'analyze_timer'): + self.analyze_timer.cancel() + self.analyze_timer = threading.Timer(2.0, self.analyze_conversation) + self.analyze_timer.start() + + def analyze_conversation(self): + """Main analysis function using RAG""" + self.status_label.config(text="Analyzing conversation with RAG...", foreground='orange') + self.root.update() + + try: + conv_text = self.conversation_text.get('1.0', tk.END) + messages = self.extract_messages(conv_text) + + if not messages: + self.suggestions_text.delete('1.0', tk.END) + self.suggestions_text.insert(tk.END, "No messages to analyze. Please paste some conversation text above.") + self.status_label.config(text="No messages found", foreground='red') + return + + analysis = self.analyze_sentiment_and_emotion(messages) + suggestions = self.generate_suggestions(analysis, messages) + + self.display_analysis(analysis, suggestions, messages) + + self.analysis_results.append({ + 'timestamp': datetime.now().isoformat(), + 'analysis': analysis, + 'suggestions': suggestions, + 'message_count': len(messages), + 'rag_enabled': self.faiss_index is not None + }) + + status_text = "RAG analysis complete!" if self.faiss_index else "Analysis complete (RAG unavailable)" + self.status_label.config(text=status_text, foreground='green') + + except Exception as e: + self.suggestions_text.delete('1.0', tk.END) + self.suggestions_text.insert(tk.END, f"Error during RAG analysis: {str(e)}") + self.status_label.config(text="Analysis failed", foreground='red') + + def display_analysis(self, analysis: Dict, suggestions: List[str], messages: List[str]): + """Display analysis results with RAG indicators""" + self.suggestions_text.delete('1.0', tk.END) + + # Analysis summary with RAG indicator + self.suggestions_text.insert(tk.END, "🤖 rag-enhanced conversation analysis\n") + self.suggestions_text.insert(tk.END, "="*50 + "\n\n") + + self.suggestions_text.insert(tk.END, f"sentiment: {analysis['sentiment'].title()} ({analysis['sentiment_score']:.2f})\n") + self.suggestions_text.insert(tk.END, f"emotion: {analysis['emotion'].title()} ({analysis['emotion_score']:.2f})\n") + self.suggestions_text.insert(tk.END, f"engagement: {analysis['engagement'].title()}\n") + self.suggestions_text.insert(tk.END, f"analyzed {len(messages)} recent messages\n") + + # RAG system status + rag_status = "✅ Active" if self.faiss_index is not None else "❌ Unavailable" + self.suggestions_text.insert(tk.END, f"rag system: {rag_status}\n\n") + + # Suggestions + self.suggestions_text.insert(tk.END, "🎯 rag-generated suggestions\n") + self.suggestions_text.insert(tk.END, "="*50 + "\n\n") + + for suggestion in suggestions: + self.suggestions_text.insert(tk.END, f"{suggestion}\n\n") + + # General tips + self.suggestions_text.insert(tk.END, "📋 conversation wisdom\n") + self.suggestions_text.insert(tk.END, "="*50 + "\n") + self.suggestions_text.insert(tk.END, "• suggestions generated from thousands of real conversations\n") + self.suggestions_text.insert(tk.END, "• always respect boundaries and consent\n") + self.suggestions_text.insert(tk.END, "• use these as inspiration for your authentic voice\n") + self.suggestions_text.insert(tk.END, "• rag retrieves contextually relevant examples\n") + self.suggestions_text.insert(tk.END, "• let your personality shine through naturally\n") + + def clear_all(self): + """Clear all text areas""" + self.conversation_text.delete('1.0', tk.END) + self.suggestions_text.delete('1.0', tk.END) + rag_status = "Ready" if self.faiss_index is not None else "RAG system not available" + self.status_label.config(text=f"RAG System: {rag_status} | Ready to analyze conversations", + foreground='green' if self.faiss_index else 'orange') + + def save_analysis(self): + """Save analysis results to file""" + if not self.analysis_results: + self.status_label.config(text="No analysis to save", foreground='red') + return + + filename = f"rag_dating_coach_analysis_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" + + try: + with open(filename, 'w') as f: + json.dump(self.analysis_results, f, indent=2) + self.status_label.config(text=f"RAG analysis saved to {filename}", foreground='green') + except Exception as e: + self.status_label.config(text=f"Save failed: {str(e)}", foreground='red') + + def run(self): + """Start the RAG-enhanced application""" + print("Starting RAG-Enhanced Dating Coach...") + print("Features: Retrieval-Augmented Generation with conversation corpus!") + self.root.mainloop() + +if __name__ == "__main__": + coach = RAGDatingCoach() + coach.run() diff --git a/submissions/requirements.txt b/submissions/requirements.txt new file mode 100644 index 0000000..eee368f --- /dev/null +++ b/submissions/requirements.txt @@ -0,0 +1,13 @@ +transformers>=4.21.0 +datasets>=2.0.0 +torch>=1.12.0 +Pillow>=9.0.0 +opencv-python>=4.6.0 +pyaudio>=0.2.11 +SpeechRecognition>=3.9.0 +numpy>=1.21.0 +huggingface_hub>=0.15.0 +sentence-transformers>=2.2.0 +faiss-cpu>=1.7.0 +langchain>=0.1.0 +langchain-community>=0.0.20 diff --git a/submissions/run_coach.py b/submissions/run_coach.py new file mode 100644 index 0000000..b329d08 --- /dev/null +++ b/submissions/run_coach.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +""" +Real-Time Dating Coach - AI@GT Applied Research Team Assessment +Simple launcher script for the RAG-enhanced dating coach + +Usage: + python run_coach.py + +This will start the RAG-enhanced dating coach with GUI interface. +""" + +import sys +import os + +def main(): + """Launch the RAG-enhanced dating coach""" + print("🚀 Starting Real-Time Dating Coach...") + print("💡 RAG-Enhanced Version with HuggingFace Integration") + print("="*60) + + try: + # Import and run the RAG dating coach + from rag_dating_coach import RAGDatingCoach + + print("🤖 Initializing AI models...") + coach = RAGDatingCoach() + + print("✅ Dating Coach ready!") + print("📱 GUI interface will open shortly...") + + # Start the GUI + coach.run() + + except ImportError as e: + print(f"❌ Error importing modules: {e}") + print("💡 Please make sure all dependencies are installed:") + print(" pip install -r requirements.txt") + sys.exit(1) + except Exception as e: + print(f"❌ Error starting dating coach: {e}") + import traceback + traceback.print_exc() + sys.exit(1) + +if __name__ == "__main__": + main()