File size: 3,695 Bytes
aac4d20
 
 
aa3b805
 
aac4d20
 
aa3b805
0876e61
 
 
 
 
aac4d20
aa3b805
aac4d20
aa3b805
aac4d20
 
aa3b805
aac4d20
aa3b805
 
 
 
aac4d20
 
aa3b805
 
aac4d20
 
 
aa3b805
aac4d20
 
 
aa3b805
 
 
 
 
 
 
 
aac4d20
aa3b805
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aac4d20
aa3b805
aac4d20
aa3b805
aac4d20
 
aa3b805
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# 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}"