algotrix / models.py
sounnak100's picture
feat: Add Sounak's Renew System for Deep Resume Analysis
086d80e
from pydantic import BaseModel, Field
from typing import List, Optional, Literal, Dict, Any
class Resume(BaseModel):
candidate_id: str
name: str
email: str
skills: List[str]
experience_years: int
education: Literal["High School", "Bachelor's", "Master's", "PhD"]
previous_roles: List[str]
# Protected attributes (for bias testing only; hidden in blind_mode)
name_gender_proxy: Literal["M", "F", "N"]
name_ethnicity_proxy: Literal["White", "Black", "Asian", "Hispanic", "Other"]
graduation_year: Optional[int] = None
class JobDescription(BaseModel):
job_id: str
title: str
required_skills: List[str]
preferred_skills: List[str]
min_experience: int
max_experience: Optional[int] = None
education_requirement: Literal["High School", "Bachelor's", "Master's", "PhD", "Any"]
gender_coded_terms: List[str] = [] # Auto-detected (e.g., "ninja", "rockstar")
class Action(BaseModel):
action_type: Literal["shortlist", "reject", "flag_bias", "request_clarification"]
candidate_id: Optional[str] = None
rank: Optional[int] = Field(None, ge=1, le=50)
bias_reason: Optional[Literal["name_bias", "age_bias", "gender_coded_language", "education_elitism"]] = None
clarification_field: Optional[str] = None
class Observation(BaseModel):
current_resume: Optional[Resume] = None
job_description: JobDescription
skill_match_score: float = Field(ge=0.0, le=1.0)
bias_risk_score: float = Field(ge=0.0, le=1.0)
ml_fit_prob: Optional[float] = None
detailed_analysis: Optional[Dict[str, Any]] = None
shortlist_so_far: List[str]
remaining_candidates: int
step_count: int
bias_metrics: Optional[Dict[str, float]] = None # Populated after step()
class State(BaseModel):
episode_id: str
task_name: Literal["easy_shortlist", "medium_rank", "hard_fair_screen"]
step_count: int
total_candidates: int
shortlist_complete: bool
cumulative_reward: float
bias_audit: Optional[Dict[str, float]] = None # Final bias report