Spaces:
Running
Running
| """ | |
| Autonomous Chat Handler - 100% LLM-Driven | |
| ========================================== | |
| NO hardcoded messages, NO hardcoded patterns! | |
| Everything is generated by LLM dynamically. | |
| This makes DataVision truly unbeatable - it adapts | |
| to ANY data type and ANY conversation style. | |
| """ | |
| import json | |
| import logging | |
| from typing import Optional, Tuple, List | |
| from core.llm import chat | |
| logger = logging.getLogger(__name__) | |
| def handle_greeting( | |
| query: str, | |
| user_name: Optional[str] = None, | |
| has_data: bool = False, | |
| columns: List[str] = None, | |
| domain: str = None | |
| ) -> str: | |
| """ | |
| Generate greeting 100% autonomously using LLM. | |
| NO hardcoded greeting text! | |
| """ | |
| try: | |
| prompt = f"""You are DataVision, an AI data analyst that can analyze ANY type of data. | |
| Generate a warm, helpful greeting response. | |
| Context: | |
| - User name: {user_name or "Unknown"} | |
| - Has uploaded data: {has_data} | |
| - Data columns: {columns or "No data yet"} | |
| - Detected domain: {domain or "Unknown"} | |
| Generate a personalized greeting that: | |
| 1. Welcomes the user warmly (use their name if known) | |
| 2. If they have data, mentions what you can analyze | |
| 3. If no data, encourages them to upload | |
| 4. Suggests 2-3 example questions they could ask | |
| 5. Uses appropriate emojis | |
| Generate the greeting (be conversational, not robotic):""" | |
| result = chat(prompt, temperature=0.8, max_tokens=300) | |
| return result.strip() | |
| except Exception as e: | |
| logger.warning(f"Greeting generation error: {e}") | |
| # Minimal fallback | |
| if user_name: | |
| return f"Hello {user_name}! π I'm DataVision, ready to analyze any data you throw at me!" | |
| return "Hello! π I'm DataVision. Upload any data and let's explore it together!" | |
| def handle_off_topic(query: str, columns: List[str] = None) -> str: | |
| """ | |
| Handle off-topic queries autonomously. | |
| NO hardcoded responses! | |
| """ | |
| try: | |
| prompt = f"""The user asked something that seems off-topic for a data analysis AI. | |
| USER QUERY: "{query}" | |
| AVAILABLE DATA: {columns or "No data uploaded"} | |
| Generate a polite response that: | |
| 1. Acknowledges their question | |
| 2. Explains you're designed for data analysis | |
| 3. Redirects to what you CAN help with | |
| 4. Suggests relevant data questions they could ask | |
| Keep it friendly and helpful, not dismissive. | |
| Response:""" | |
| result = chat(prompt, temperature=0.7, max_tokens=200) | |
| return result.strip() | |
| except: | |
| return "I'm DataVision, focused on data analysis. Try asking about your uploaded data!" | |
| def handle_no_data() -> str: | |
| """ | |
| Generate no-data response autonomously. | |
| """ | |
| try: | |
| prompt = """You are DataVision, an AI that analyzes ANY type of data. | |
| The user hasn't uploaded any data yet. | |
| Generate a helpful response that: | |
| 1. Explains you need data to analyze | |
| 2. Lists what file types you support (CSV, Excel, PDF, images) | |
| 3. Gives examples of different domains you can handle (HR, business, scientific, IoT, etc.) | |
| 4. Encourages them to upload and promises to help | |
| Keep it encouraging and not overwhelming. | |
| Response:""" | |
| result = chat(prompt, temperature=0.7, max_tokens=250) | |
| return result.strip() | |
| except: | |
| return "I need data to analyze! Upload any CSV, Excel, PDF, or image file and I'll help you explore it." | |
| def is_greeting(query: str) -> bool: | |
| """ | |
| Detect greeting autonomously using LLM. | |
| """ | |
| try: | |
| prompt = f"""Is this a greeting/hello message? Answer ONLY "yes" or "no". | |
| MESSAGE: "{query}" | |
| Answer:""" | |
| result = chat(prompt, temperature=0, max_tokens=5) | |
| return 'yes' in result.lower() | |
| except: | |
| # Simple fallback for performance | |
| q = query.lower().strip() | |
| return q in ['hi', 'hello', 'hey', 'start'] or q.startswith(('hi ', 'hello ', 'hey ')) | |
| def is_off_topic(query: str, columns: List[str] = None) -> bool: | |
| """ | |
| Detect off-topic queries autonomously using LLM. | |
| """ | |
| try: | |
| prompt = f"""Is this query related to data analysis or could it be answered with data? | |
| QUERY: "{query}" | |
| AVAILABLE DATA COLUMNS: {columns or "Unknown"} | |
| Answer ONLY "data_related" or "off_topic":""" | |
| result = chat(prompt, temperature=0, max_tokens=10) | |
| return 'off_topic' in result.lower() | |
| except: | |
| return False # Default to not off-topic | |
| def detect_special_query(query: str, columns: List[str] = None) -> Tuple[str, Optional[str]]: | |
| """ | |
| Detect special query types autonomously. | |
| """ | |
| # Check greeting | |
| if is_greeting(query): | |
| return "greeting", None | |
| # Check off-topic (only if we have data context) | |
| if columns and is_off_topic(query, columns): | |
| return "off_topic", handle_off_topic(query, columns) | |
| return "analysis", None | |
| def add_personality(response: str, query: str) -> str: | |
| """ | |
| Add personality touches autonomously. | |
| """ | |
| # Don't modify if already has personality | |
| if any(emoji in response[:20] for emoji in ['π', 'π', 'π', 'π‘', 'π―']): | |
| return response | |
| if len(response) < 50: | |
| return response | |
| try: | |
| prompt = f"""Add a brief, relevant emoji at the start of this response. | |
| Choose based on the content (π for data, π for trends, π― for insights, etc.) | |
| QUERY: {query[:100]} | |
| RESPONSE START: {response[:100]} | |
| Return ONLY the emoji (one character):""" | |
| emoji = chat(prompt, temperature=0.3, max_tokens=5) | |
| emoji = emoji.strip() | |
| # Validate it's actually an emoji | |
| if len(emoji) <= 4 and not emoji.isalnum(): | |
| return f"{emoji} {response}" | |
| except: | |
| pass | |
| return response | |
| def generate_contextual_response( | |
| query: str, | |
| data_context: str, | |
| columns: List[str], | |
| user_name: Optional[str] = None, | |
| previous_response: Optional[str] = None | |
| ) -> str: | |
| """ | |
| Generate fully contextual response autonomously. | |
| This is the core intelligence! | |
| """ | |
| try: | |
| context_parts = [] | |
| if user_name: | |
| context_parts.append(f"User's name: {user_name}") | |
| if previous_response: | |
| context_parts.append(f"Previous response: {previous_response[:300]}") | |
| prompt = f"""You are DataVision, an expert AI data analyst. | |
| Analyze this query and provide a helpful, data-driven response. | |
| QUERY: {query} | |
| DATA CONTEXT: | |
| Columns: {columns} | |
| Data sample: {data_context[:1000]} | |
| {chr(10).join(context_parts) if context_parts else ""} | |
| Instructions: | |
| 1. Answer based on the actual data provided | |
| 2. Be specific with numbers and facts | |
| 3. Format nicely with markdown | |
| 4. If showing lists, use bullet points | |
| 5. If data is missing, say so honestly | |
| Response:""" | |
| result = chat(prompt, temperature=0.3, max_tokens=800) | |
| return result.strip() | |
| except Exception as e: | |
| logger.error(f"Contextual response error: {e}") | |
| return "I encountered an issue analyzing your query. Please try rephrasing." | |