import os import io import base64 import requests import re from config import GROQ_API_KEY def groq_vision_answer(image, question, lang="en"): token = GROQ_API_KEY or os.getenv("GROQ_API_KEY") if not token: return "Setup Required", "Groq API Key is missing.", "Please set the GROQ_API_KEY." try: model_id = "meta-llama/llama-4-scout-17b-16e-instruct" api_url = "https://api.groq.com/openai/v1/chat/completions" headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json" } if image.mode != 'RGB': image = image.convert('RGB') image.thumbnail((500, 500)) buffered = io.BytesIO() image.save(buffered, format="JPEG", quality=85) img_b64 = base64.b64encode(buffered.getvalue()).decode("utf-8") img_data_url = f"data:image/jpeg;base64,{img_b64}" prompt = f"""Analyze this image carefully. Question: {question} CRITICAL RULES FOR YOUR RESPONSE: 1. You MUST respond strictly in the language code: {lang}. All text in your output must be translated to '{lang}'. 2. You MUST use EXACTLY the format below with these English labels. 3. You MUST provide a detailed descriptive Caption. 4. You MUST provide a highly accurate Final Answer. 5. You MUST provide an expansive, detailed Explanation justifying your answer. Respond strictly following this exact structure without any deviations or markdown blocks. Caption: Final Answer: Explanation: """ payload = { "model": model_id, "messages": [ { "role": "user", "content": [ {"type": "text", "text": prompt}, {"type": "image_url", "image_url": {"url": img_data_url}} ] } ], "max_tokens": 512, "temperature": 0.2 } response = requests.post(api_url, headers=headers, json=payload, timeout=60) if response.status_code != 200: return "Groq Native Server Error", f"HTTP {response.status_code}", response.text data = response.json() raw_text = data["choices"][0]["message"]["content"] caption_match = re.search(r'Caption:\s*(.*?)(?=Final Answer:|$)', raw_text, re.IGNORECASE | re.DOTALL) answer_match = re.search(r'Final Answer:\s*(.*?)(?=Explanation:|$)', raw_text, re.IGNORECASE | re.DOTALL) explanation_match = re.search(r'Explanation:\s*(.*)', raw_text, re.IGNORECASE | re.DOTALL) caption = caption_match.group(1).strip() if caption_match else "Caption not generated correctly." answer = answer_match.group(1).strip() if answer_match else "Answer not generated correctly." explanation = explanation_match.group(1).strip() if explanation_match else "Explanation not generated correctly." caption = caption.replace("**", "").replace("\n", " ") answer = answer.replace("**", "").replace("\n", " ") explanation = explanation.replace("**", "") return caption, answer, explanation except Exception as e: return "Groq Native API Error", "The request crashed.", repr(e)