import os import re from groq import Groq from dotenv import load_dotenv load_dotenv() client = Groq(api_key=os.environ.get("GROQ_API_KEY")) def is_meaningful(text): """Checks if the text contains actual words or just gibberish.""" text_stripped = text.strip() # 1. Basic length check (already enforced by UI, but good for safety) if len(text_stripped) < 3: return False # 2. Check for vowel ratio (catches 'bdfghj') vowels = len(re.findall(r'[aeiouAEIOU]', text_stripped)) total_chars = len(re.findall(r'[a-zA-Z]', text_stripped)) if total_chars > 0 and (vowels / total_chars) < 0.1: return False # 3. Check for repetitive characters (catches 'aaaaaa') if re.search(r'(.)\1{4,}', text_stripped): return False return True def analyze_sentiment(review_text, rating=3): """ Core sentiment logic. Gibberish is filtered locally; meaningful text is analyzed by Llama 3.1. """ text_clean = str(review_text).strip() # --- STEP 1: SENSE CHECK (GIBBERISH FILTER) --- if not is_meaningful(text_clean): return "Neutral" # --- STEP 2: AI LOGIC --- # Enhanced prompt to ensure 'bad product' is caught as Negative system_msg = ( "You are a strict sentiment classifier. Output ONLY one word: Positive, Negative, or Neutral. " "Priority Rule: If the text contains negative words (bad, poor, hate, worst), " "the output MUST be Negative, regardless of the star rating." ) user_prompt = f"Review Text: '{text_clean}'\nStar Rating: {rating}/5\nSentiment:" try: chat_completion = client.chat.completions.create( messages=[ {"role": "system", "content": system_msg}, {"role": "user", "content": user_prompt} ], model="llama-3.1-8b-instant", temperature=0, # Zero temperature ensures the most predictable result max_tokens=3 ) # Clean the output from the AI result = chat_completion.choices[0].message.content.strip().replace(".", "") if result in ["Positive", "Negative", "Neutral"]: return result return "Neutral" except Exception as e: print(f"Error calling Groq API: {e}") return "Neutral"