import google.generativeai as genai import os import json from dotenv import load_dotenv load_dotenv() # Support multiple Gemini keys (comma-separated or single key) api_keys = os.getenv("GOOGLE_API_KEYS") or os.getenv("GOOGLE_API_KEY") if not api_keys: raise ValueError("No Gemini API keys found in GOOGLE_API_KEYS or GOOGLE_API_KEY environment variable.") api_keys = [k.strip() for k in api_keys.split(",") if k.strip()] print(f"Loaded {len(api_keys)} Gemini API key(s)") def query_gemini(questions, contexts): context = "\n\n".join(contexts) questions_text = "\n".join([f"{i+1}. {q}" for i, q in enumerate(questions)]) prompt = f""" You are an expert insurance assistant generating formal yet user-facing answers to policy questions and Other Human Questions. Your goal is to write professional, structured answers that reflect the language of policy documents β€” but are still human-readable and easy to understand. 🧠 FORMAT & TONE GUIDELINES: - Write in professional third-person language (no "you", no "we"). - Use clear sentence structure with proper punctuation and spacing. - Do NOT write in legalese or robotic passive constructions. - Include eligibility, limits, and waiting periods explicitly where relevant. - Keep it factual, neutral, and easy to follow. - First, try to answer each question using information from the provided context. - If the question is NOT covered by the context Provide Then Give The General Answer It Not Be In Context if Nothing Found Give Normal Ai Answer for The Question Correctly - Limit each answer to 2–3 sentences, and do not repeat unnecessary information. - If a question can be answered with a simple "Yes", "No", "Can apply", or "Cannot apply", then begin the answer with that phrase, followed by a short supporting Statement In Natural Human Like response.So Give A Good Answer For The Question With Correct Information. - Avoid giving theory Based Long Long answers Try to Give Short Good Reasonable Answers. - Dont Give Long theory Like Response Very Large Response Just Give Short And Good Response For The Question. - If the question is general (math, code, tech, etc.) and No Matches With Context, answer normally without referencing the document. - Avoid Saying β€œNot found” or β€œOut of scope” For The Answer of The Question Try to Give Basic General Response For The Question. πŸ›‘ DO NOT: - Mention "context", "document", or "text" in any form. - Use markdown, bullets, emojis, or code blocks. - Use words like helpful, available, allowed, indemnified, excluded, etc. - Use legal-style passive phrases like "shall be indemnified". - Start with or include phrases like "Based on the context", "No details found in the context", etc. - Give theory or long explanations. - Say "This info is not covered", "Out of scope", or similar. - Say "Please refer to other sources". - Say "Not mentioned in the document" β€” if nothing is found, give a general insurance-based response. - If no general answer is possible, only then say: "No relevant information is available to answer this question." βœ… DO: - Write in clean, informative language. - Give complete answers in 2–3 sentences maximum. πŸ“ EXAMPLE ANSWERS: - "Yes, the policy covers damage to personal property caused by fire, up to a limit of $50,000." - "No, the policy does not cover pre-existing conditions." - "The waiting period for coverage to begin is 30 days from the start date of the policy." πŸ“€ OUTPUT FORMAT (strict): Respond with only the following JSON β€” no explanations, no comments, no markdown: {{ "answers": [ "Answer to question 1", "Answer to question 2", ... ] }} πŸ“š CONTEXT: {context} ❓ QUESTIONS: {questions_text} Your task: For each question, provide a complete, professional, and clearly written answer in 2–3 sentences using a formal but readable tone. """ last_exception = None for key_idx, key in enumerate(api_keys): try: genai.configure(api_key=key) model = genai.GenerativeModel("gemini-2.5-flash-lite") response = model.generate_content(prompt) response_text = response.text.strip() # Clean JSON from wrapped code blocks if response_text.startswith("```json"): response_text = response_text.replace("```json", "").replace("```", "").strip() elif response_text.startswith("```"): response_text = response_text.replace("```", "").strip() parsed = json.loads(response_text) if "answers" in parsed and isinstance(parsed["answers"], list): return parsed else: raise ValueError("Invalid response format received from Gemini.") except Exception as e: msg = str(e).lower() if "429" in msg or "quota" in msg or "rate limit" in msg or "exceeded" in msg: print(f"Gemini key {key[:8]}... quota/rate limited. Trying next key ({key_idx+1}/{len(api_keys)}).") last_exception = e continue else: print(f"Error using Gemini key {key[:8]}...: {e}") return {"answers": [f"Error generating response: {str(e)}"] * len(questions)} print(f"All Gemini API keys failed. Last error: {last_exception}") return {"answers": [f"Error generating response: {str(last_exception)}"] * len(questions)}