AIproject / agent /tools.py
RubaKhan242's picture
Deploy FastAPI backend for AI recruitment system
e663c0c
import json
import logging
from agents import function_tool
logger = logging.getLogger(__name__)
@function_tool
async def extract_resume_info(resume_text: str) -> str:
"""
Extract structured information from raw resume text.
Returns a JSON string with candidate name, skills, experience years,
education level, and certifications.
"""
result = {
"candidate_name": "Unknown",
"skills": [],
"experience_years": 0,
"education": "Unknown",
"certifications": []
}
logger.debug("extract_resume_info called with %d chars of resume text", len(resume_text))
return json.dumps(result)
@function_tool
async def match_skills(resume_skills: str, required_skills: str) -> str:
"""
Compare resume skills against required job skills.
Args:
resume_skills: comma-separated list of skills found in the resume
required_skills: comma-separated list of skills required for the job
Returns:
JSON string with matched_skills, missing_skills, and match_percentage
"""
resume_set = {s.strip().lower() for s in resume_skills.split(",") if s.strip()}
required_set = {s.strip().lower() for s in required_skills.split(",") if s.strip()}
if not required_set:
return json.dumps({
"matched_skills": [],
"missing_skills": [],
"match_percentage": 0.0
})
matched = sorted(resume_set & required_set)
missing = sorted(required_set - resume_set)
match_percentage = round((len(matched) / len(required_set)) * 100, 2)
result = {
"matched_skills": matched,
"missing_skills": missing,
"match_percentage": match_percentage
}
logger.debug("match_skills: %d/%d matched (%.1f%%)", len(matched), len(required_set), match_percentage)
return json.dumps(result)
@function_tool
async def calculate_ats_score(
skill_match_percentage: float,
experience_years_candidate: int,
experience_years_required: int,
education_level: str,
resume_quality: str
) -> str:
"""
Calculate ATS score (0–100) based on multiple criteria.
"""
skill_match_percentage = max(0.0, min(100.0, float(skill_match_percentage)))
skill_score = round(50 * skill_match_percentage / 100, 2)
if experience_years_candidate >= experience_years_required:
experience_score = 25
elif experience_years_required > 0 and experience_years_candidate >= experience_years_required / 2:
experience_score = 12
else:
experience_score = 0
education_map = {
"phd": 15, "masters": 15, "master": 15,
"bachelors": 12, "bachelor": 12, "diploma": 8,
}
education_score = education_map.get(education_level.strip().lower(), 4)
quality_map = {"good": 10, "average": 6, "poor": 2}
quality_score = quality_map.get(resume_quality.strip().lower(), 6)
ats_score = round(skill_score + experience_score + education_score + quality_score, 2)
ats_score = max(0, min(100, ats_score))
result = {
"ats_score": ats_score,
"breakdown": {
"skill_score": skill_score,
"experience_score": experience_score,
"education_score": education_score,
"quality_score": quality_score
}
}
logger.debug("calculate_ats_score: total=%.2f", ats_score)
return json.dumps(result)
@function_tool
async def make_decision(
ats_score: int,
candidate_name: str,
missing_skills: str,
job_title: str
) -> str:
"""
Make a hiring decision based on ATS score.
"""
missing_list = [s.strip() for s in missing_skills.split(",") if s.strip()]
if ats_score >= 70:
status = "selected"
recommendation_message = (
f"Congratulations, {candidate_name}! Your profile is a strong match for the "
f"{job_title} position. Our recruitment team will be in touch with next steps shortly."
)
else:
status = "rejected"
if missing_list:
skills_str = ", ".join(missing_list)
recommendation_message = (
f"Thank you for applying, {candidate_name}. Unfortunately your profile did not meet "
f"the minimum requirements for the {job_title} role at this time. "
f"We recommend strengthening the following areas: {skills_str}."
)
else:
recommendation_message = (
f"Thank you for applying, {candidate_name}. Unfortunately your profile did not meet "
f"the minimum requirements for the {job_title} role at this time."
)
result = {
"status": status,
"ats_score": ats_score,
"missing_skills": missing_list,
"recommendation_message": recommendation_message
}
logger.debug("make_decision: %s (score=%d)", status, ats_score)
return json.dumps(result)