82 lines
2.9 KiB
Python
82 lines
2.9 KiB
Python
import os
|
|
import json
|
|
import io
|
|
import logging
|
|
from PIL import Image
|
|
from google import genai
|
|
from google.genai import types
|
|
|
|
log = logging.getLogger("ainventory")
|
|
|
|
def get_best_models():
|
|
# Priority list based on aliases and future-gen models found in user logs
|
|
return [
|
|
"gemini-flash-latest", # Points to the best stable Flash version
|
|
"gemini-3.1-flash-lite-preview", # Cutting edge 3.1 Lite
|
|
"gemini-flash-lite-latest", # Best Lite alias
|
|
"gemini-pro-latest" # Pro fallback alias
|
|
]
|
|
|
|
def extract(image_bytes: bytes, prompt: str):
|
|
api_key = os.environ.get("GEMINI_API_KEY")
|
|
if not api_key:
|
|
log.error("CRITICAL: GEMINI_API_KEY is MISSING in environment!")
|
|
return None
|
|
|
|
# Log partial key for safety debug
|
|
key_hint = f"{api_key[:4]}...{api_key[-4:]}" if len(api_key) > 8 else "too short"
|
|
log.info(f"🔑 Using API Key: {key_hint}")
|
|
|
|
try:
|
|
# Switching to v1beta which is required for many experimental/new models
|
|
client = genai.Client(api_key=api_key, http_options={'api_version': 'v1beta'})
|
|
|
|
# DEBUG: List allowed models for this key
|
|
log.debug("🔍 Checking available models for your key...")
|
|
try:
|
|
for m in client.models.list():
|
|
log.debug(f" - Found: {m.name}")
|
|
except Exception as list_e:
|
|
log.warning(f" ⚠️ Could not list models: {list_e}")
|
|
|
|
models_to_try = get_best_models()
|
|
|
|
# Try models in order
|
|
for model_name in models_to_try:
|
|
try:
|
|
log.info(f"🚀 AI Launching (v2 SDK): {model_name}...")
|
|
|
|
# In the new SDK, we pass a list of parts (text string and image bytes)
|
|
response = client.models.generate_content(
|
|
model=model_name,
|
|
contents=[
|
|
prompt,
|
|
types.Part.from_bytes(data=image_bytes, mime_type="image/jpeg")
|
|
]
|
|
)
|
|
|
|
if not response or not response.text:
|
|
log.warning(f"⚠️ Gemini {model_name} returned NO text.")
|
|
continue
|
|
|
|
text = response.text.strip()
|
|
log.info(f"✅ AI Response Received ({len(text)} bytes)")
|
|
log.debug(f"FULL RESPONSE:\n{text}")
|
|
|
|
# Extract JSON block
|
|
if "```json" in text:
|
|
text = text.split("```json")[1].split("```")[0].strip()
|
|
elif "```" in text:
|
|
text = text.split("```")[1].strip()
|
|
|
|
return json.loads(text)
|
|
|
|
except Exception as e:
|
|
log.error(f"❌ Gemini {model_name} failed: {e}")
|
|
continue
|
|
|
|
except Exception as outer_e:
|
|
log.error(f"❌ Gemini Client Init failed: {outer_e}")
|
|
|
|
return None
|