92 lines
3.3 KiB
Python
92 lines
3.3 KiB
Python
from typing import Dict, List, Optional, Tuple, Any
|
|
from pydantic import BaseModel, Field, field_validator
|
|
from models import JSONResume, EvaluationData
|
|
from llm_utils import initialize_llm_provider, extract_json_from_response
|
|
import logging
|
|
import json
|
|
import re
|
|
|
|
MAX_BONUS_POINTS = 20
|
|
MIN_FINAL_SCORE = -20
|
|
MAX_FINAL_SCORE = 120
|
|
|
|
from prompt import (
|
|
DEFAULT_MODEL,
|
|
MODEL_PARAMETERS,
|
|
MODEL_PROVIDER_MAPPING,
|
|
GEMINI_API_KEY,
|
|
)
|
|
from prompts.template_manager import TemplateManager
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ResumeEvaluator:
|
|
def __init__(self, model_name: str = DEFAULT_MODEL, model_params: dict = None):
|
|
if not model_name:
|
|
raise ValueError("Model name cannot be empty")
|
|
|
|
self.model_name = model_name
|
|
self.model_params = model_params or MODEL_PARAMETERS.get(
|
|
model_name, {"temperature": 0.5, "top_p": 0.9}
|
|
)
|
|
self.template_manager = TemplateManager()
|
|
self._initialize_llm_provider()
|
|
|
|
def _initialize_llm_provider(self):
|
|
"""Initialize the appropriate LLM provider based on the model."""
|
|
self.provider = initialize_llm_provider(self.model_name)
|
|
|
|
def _load_evaluation_prompt(self, resume_text: str) -> str:
|
|
criteria_template = self.template_manager.render_template(
|
|
"resume_evaluation_criteria", text_content=resume_text
|
|
)
|
|
if criteria_template is None:
|
|
raise ValueError("Failed to load resume evaluation criteria template")
|
|
return criteria_template
|
|
|
|
def evaluate_resume(self, resume_text: str) -> EvaluationData:
|
|
self._last_resume_text = resume_text
|
|
full_prompt = self._load_evaluation_prompt(resume_text)
|
|
# logger.info(f"🔤 Evaluation prompt being sent: {full_prompt}")
|
|
try:
|
|
system_message = self.template_manager.render_template(
|
|
"resume_evaluation_system_message"
|
|
)
|
|
if system_message is None:
|
|
raise ValueError(
|
|
"Failed to load resume evaluation system message template"
|
|
)
|
|
|
|
# Prepare chat parameters
|
|
chat_params = {
|
|
"model": self.model_name,
|
|
"messages": [
|
|
{"role": "system", "content": system_message},
|
|
{"role": "user", "content": full_prompt},
|
|
],
|
|
"options": {
|
|
"stream": False,
|
|
"temperature": self.model_params.get("temperature", 0.5),
|
|
"top_p": self.model_params.get("top_p", 0.9),
|
|
},
|
|
}
|
|
|
|
# Add format parameter for structured output
|
|
kwargs = {"format": EvaluationData.model_json_schema()}
|
|
# Use the appropriate provider to make the API call
|
|
response = self.provider.chat(**chat_params, **kwargs)
|
|
|
|
response_text = response["message"]["content"]
|
|
response_text = extract_json_from_response(response_text)
|
|
logger.error(f"🔤 Prompt response: {response_text}")
|
|
|
|
evaluation_dict = json.loads(response_text)
|
|
evaluation_data = EvaluationData(**evaluation_dict)
|
|
|
|
return evaluation_data
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error evaluating resume: {str(e)}")
|
|
raise
|