/** * Gemini Service - AI Analysis API Client */ import { GoogleGenerativeAI } from "@google/generative-ai"; import { SYSTEM_INSTRUCTION, GEMINI_CONFIG } from "../constants"; import type { AnalysisResponse } from "../types"; let genAI: GoogleGenerativeAI | null = null; /** * Initialize Gemini API client */ export const initGemini = (): void => { const apiKey = (import.meta as any).env?.VITE_GEMINI_API_KEY || (window as any).env?.VITE_GEMINI_API_KEY; if (!apiKey) { console.error("❌ VITE_GEMINI_API_KEY is missing"); console.error("Add it to frontend/.env.local"); return; } try { genAI = new GoogleGenerativeAI(apiKey); console.log("✅ Gemini AI initialized successfully"); } catch (error) { console.error("❌ Failed to initialize Gemini:", error); } }; /** * Analyze a video frame for security threats */ export const analyzeFrame = async ( base64Image: string ): Promise => { if (!genAI) { initGemini(); if (!genAI) return null; } try { const model = genAI.getGenerativeModel({ model: GEMINI_CONFIG.MODEL }); // Clean base64 const cleanBase64 = base64Image.includes(",") ? base64Image.split(",")[1] : base64Image; const result = await model.generateContent([ SYSTEM_INSTRUCTION, { inlineData: { mimeType: "image/jpeg", data: cleanBase64 } } ]); const response = await result.response; const text = response.text(); if (!text) { console.error("Empty response from Gemini"); return null; } // Parse JSON safely try { let cleanText = text.trim(); if (cleanText.startsWith("```")) { cleanText = cleanText .replace(/```json/g, "") .replace(/```/g, "") .trim(); } const parsed = JSON.parse(cleanText) as AnalysisResponse; // Normalize severity if (parsed.severity) { parsed.severity = parsed.severity.toLowerCase(); } // Ensure fields if (typeof parsed.incident === "undefined") { parsed.incident = false; } return parsed; } catch (parseError) { console.error("❌ JSON parse failed"); console.error("RAW:", text); return null; } } catch (error) { console.error("❌ Gemini API Error:", error); return null; } }; /** * Test Gemini connection */ export const testConnection = async (): Promise => { if (!genAI) { initGemini(); if (!genAI) return false; } try { const model = genAI.getGenerativeModel({ model: GEMINI_CONFIG.MODEL }); const result = await model.generateContent( 'Respond with "OK"' ); const text = result.response.text(); console.log("✅ Gemini test success:", text); return true; } catch (error) { console.error("❌ Gemini test failed:", error); return false; } };