project-asclepius / modules /gemini_handler.py
mgbam's picture
Update modules/gemini_handler.py
0876e61 verified
# modules/gemini_handler.py
"""
Dedicated module for all interactions with the Google Gemini API.
It initializes and configures the models, and provides clean, async functions
for both text and multi-modal (vision) generation, including robust error handling.
"""
import google.generativeai as genai
from PIL import Image
# ==============================================================================
# CORRECTED LINE: The import path now correctly points to api_clients/config.py
from api_clients.config import GEMINI_API_KEY
# ==============================================================================
# --- Configuration ---
if not GEMINI_API_KEY:
raise ValueError("FATAL: GEMINI_API_KEY not found. Please set it in your environment/secrets.")
genai.configure(api_key=GEMINI_API_KEY)
# Configuration for predictable, factual responses
generation_config = {
"temperature": 0.1,
"top_p": 0.95,
"top_k": 40,
"max_output_tokens": 8192, # Increased for detailed reports
}
# Safety settings are relaxed slightly for medical context, but still block high-risk content.
# This prevents the model from refusing to discuss health topics.
safety_settings = [
{"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
{"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_ONLY_HIGH"},
{"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"},
]
# --- Model Initialization ---
try:
# Model for text-based tasks (synthesis, extraction)
text_model = genai.GenerativeModel(
model_name="gemini-1.5-flash-latest", # Use a fast and capable model
generation_config=generation_config,
safety_settings=safety_settings
)
# Model for multi-modal tasks (analyzing medical images)
vision_model = genai.GenerativeModel(
model_name="gemini-1.5-flash-latest", # Vision models are also great at text
generation_config=generation_config,
safety_settings=safety_settings
)
except Exception as e:
raise RuntimeError(f"Failed to initialize Gemini models: {e}")
async def generate_text_response(prompt: str) -> str:
"""
Calls the Gemini text model with a given prompt.
Args:
prompt (str): The detailed prompt for the AI.
Returns:
str: The AI's generated text response, or an error message.
"""
try:
response = await text_model.generate_content_async(prompt)
if not response.parts:
return "Error: The AI response was blocked, possibly due to safety filters or lack of content. Please rephrase."
return response.text
except Exception as e:
print(f"Gemini API Error (Text): {e}")
return f"An error occurred while communicating with the AI model. Details: {e}"
async def analyze_image_with_text(prompt: str, image: Image.Image) -> str:
"""
Calls the Gemini vision model with a text prompt and an image.
Args:
prompt (str): The text prompt to guide the image analysis.
image (Image.Image): The PIL image to be analyzed.
Returns:
str: The AI's generated text analysis, or an error message.
"""
try:
response = await vision_model.generate_content_async([prompt, image])
if not response.parts:
return "Error: The AI response for the image was blocked. The image may violate safety policies."
return response.text
except Exception as e:
print(f"Gemini API Error (Vision): {e}")
return f"An error occurred while analyzing the image with the AI. Details: {e}"