File size: 3,360 Bytes
d790e98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
93
94
95
96
import { GoogleGenAI, Type, Schema } from "@google/genai";
import { AnalysisReport } from "../types";

// Initialize Gemini Client
// Note: API Key is injected via process.env.API_KEY
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });

const MODEL_NAME = "gemini-2.5-flash";

const analysisSchema: Schema = {
  type: Type.OBJECT,
  properties: {
    isCompliant: { type: Type.BOOLEAN, description: "Whether the image is suitable for a public lock screen." },
    overallScore: { type: Type.INTEGER, description: "A quality score from 0 to 100." },
    checks: {
      type: Type.ARRAY,
      items: {
        type: Type.OBJECT,
        properties: {
          name: { type: Type.STRING, description: "The name of the criterion being checked." },
          passed: { type: Type.BOOLEAN, description: "Whether the check passed." },
          reason: { type: Type.STRING, description: "Brief explanation of the result." }
        },
        required: ["name", "passed", "reason"]
      }
    }
  },
  required: ["isCompliant", "overallScore", "checks"]
};

/**
 * Converts a File object to a Base64 string for the API.
 */
const fileToGenerativePart = async (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => {
      const base64String = reader.result as string;
      // Remove data url prefix (e.g. "data:image/jpeg;base64,")
      const base64Data = base64String.split(',')[1];
      resolve(base64Data);
    };
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
};

export const analyzeLockScreen = async (file: File): Promise<AnalysisReport> => {
  try {
    const base64Data = await fileToGenerativePart(file);

    const systemPrompt = `
      You are Prism, an AI expert for Samsung Glance lock screen compliance.
      Analyze the provided image against the following strict criteria:
      1. Image Quality: Must be high resolution, not blurry, no artifacts.
      2. Ribbon Detection: Ensure no promotional ribbons, watermarks, or text overlays covering the subject.
      3. Text Legibility: If there is text, is it legible? (Prefer no text for wallpapers).
      4. Safe Content: No offensive, violent, or adult content.
      5. Subject Centering: The main subject should be well-positioned for a mobile lock screen (portrait aspect).
      
      Return the result as a structured JSON object.
    `;

    const response = await ai.models.generateContent({
      model: MODEL_NAME,
      contents: {
        parts: [
          { inlineData: { mimeType: file.type, data: base64Data } },
          { text: systemPrompt }
        ]
      },
      config: {
        responseMimeType: "application/json",
        responseSchema: analysisSchema,
        temperature: 0.2, // Low temperature for consistent, objective analysis
      }
    });

    if (response.text) {
      return JSON.parse(response.text) as AnalysisReport;
    } else {
      throw new Error("No response text from Gemini.");
    }

  } catch (error) {
    console.error("Gemini Analysis Failed:", error);
    // Fallback mock error for UI stability if API fails completely
    return {
      isCompliant: false,
      overallScore: 0,
      checks: [
        { name: "System Error", passed: false, reason: "Failed to connect to AI service." }
      ]
    };
  }
};