iris_backend / backend /src /services /analysis.py
Saandraahh's picture
Added AI score and Insights
35709fb
import os
import json
import numpy as np
from typing import List, Dict, Any
from google import genai
import google.genai.types as types
from src.embeddings.local_embedder import generate_embedding, generate_list_embedding, get_model
# Initialize Gemini Client
client = genai.Client(api_key="AIzaSyB2Dw-nep3SwQav5S_1qJ2FoVc4I83a2yk")
def cosine_similarity(v1, v2):
v1 = np.array(v1)
v2 = np.array(v2)
return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
def identify_missing_skills(job_skills: List[str], profile_skills: List[str], threshold: float = 0.7) -> List[str]:
"""
Identifies skills required by the job but missing (semantically) in the profile.
"""
if not job_skills:
return []
if not profile_skills:
return job_skills
# Generate embeddings for profile skills
model = get_model()
profile_embeddings = model.encode(profile_skills, normalize_embeddings=True)
job_embeddings = model.encode(job_skills, normalize_embeddings=True)
missing_skills = []
for i, job_skill in enumerate(job_skills):
job_vec = job_embeddings[i]
# Find max similarity with any profile skill
similarities = [np.dot(job_vec, prof_vec) for prof_vec in profile_embeddings]
max_sim = max(similarities) if similarities else 0
if max_sim < threshold:
missing_skills.append(job_skill)
return missing_skills
def generate_ai_analysis(profile_text: str, job_description: str) -> Dict[str, Any]:
"""
Uses Gemini to generate a professional summary and evaluation.
"""
system_prompt = """
You are an expert HR Analyst. Analyze the provided candidate resume text against the job description.
Return a JSON object with:
- "summary": A 2-3 sentence professional summary of why the candidate is or isn't a good fit.
- "strengths": A list of top 3 core strengths matching the job.
- "weaknesses": A list of top 2-3 areas for improvement or missing qualifications.
- "score": An overall suitability score from 0 to 100 based on their experience and skills relative to the job requirements.
Be objective, professional, and concise.
"""
user_content = f"JOB DESCRIPTION:\n{job_description}\n\nCANDIDATE RESUME:\n{profile_text}"
try:
response = client.models.generate_content(
model="gemini-2.5-flash-lite", # Updated to confirmed model name
contents=system_prompt + "\n\n" + user_content,
config=types.GenerateContentConfig(
temperature=0.2,
response_mime_type="application/json"
)
)
return json.loads(response.text)
except Exception as e:
print(f"❌ AI Analysis failed: {e}")
return {
"summary": "Analysis currently unavailable.",
"strengths": [],
"weaknesses": [],
"score": 0
}