Spaces:
Sleeping
Sleeping
File size: 2,959 Bytes
35709fb | 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 |
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
}
|