Spaces:
Sleeping
Sleeping
File size: 5,021 Bytes
daede4b | 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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | """
Simulate the WORST production case: LLM returns only 2 roles (drops BYJU's
and ML Edutech), no recruiter pitch, 3 bullets per role. Verify the v4
backfill + pitch enforcement + weaving brings it to 90%+.
"""
import os, sys, io, shutil
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
src_pdf = r'C:\Users\Nxtwave\Desktop\resume\Saiteja_Tirunagari_Resume A 26 - Copy.pdf'
dst_pdf = 'data/resume/resume.pdf'
os.makedirs(os.path.dirname(dst_pdf), exist_ok=True)
if not os.path.exists(dst_pdf):
shutil.copyfile(src_pdf, dst_pdf)
# Monkey-patch the LLM call to return a deliberately weak v4 response
from src.resume_customizer import ResumeCustomizer, _read_docx_text
from src.llm_client import LLMClient
from src.ats_scorer import score_resume
def make_weak_response(resume_dict, job_title, company):
"""Mimic worst-case LLM: 2 roles only, no pitch, 3 bullets each."""
return {
"name": resume_dict["name"],
"contact": resume_dict["contact"],
# NO recruiter pitch — generic 2-sentence summary
"summary": (
"Product Manager with 5+ years of experience driving product development "
"in fast-paced startups. Built funnel optimization and AI-powered features "
"that scaled to 140,000+ users with measurable business impact."
),
"roles": [
# Only 2 of the 4 original roles — LLM dropped older ones
{
"title": resume_dict["roles"][0]["title"],
"company": resume_dict["roles"][0]["company"],
"location": resume_dict["roles"][0]["location"],
"dates": resume_dict["roles"][0]["dates"],
"bullets": [
"Led NIAT Application Portal revamp scaling to 141,269 verified leads",
"Drove payment conversion lift of +35.87 percentage points",
"Built AI chatbot generating 6,776 leads",
],
},
{
"title": resume_dict["roles"][1]["title"],
"company": resume_dict["roles"][1]["company"],
"location": resume_dict["roles"][1]["location"],
"dates": resume_dict["roles"][1]["dates"],
"bullets": [
"Managed 20 customer-success specialists covering 40,000 customers",
"Maintained refund rate below 5% and satisfaction above 95%",
],
},
],
"achievements": [
"Scaled to 141,269 verified leads",
"Lifted payment conversion +35.87 pp",
],
"education": resume_dict["education"],
}
# Patch LLMClient.tailor_resume_v4 to return our weak response
_original_v4 = LLMClient.tailor_resume_v4
def _mocked_v4(self, cfg, resume_dict, jd_text, job_title, company, assessment):
return make_weak_response(resume_dict, job_title, company)
LLMClient.tailor_resume_v4 = _mocked_v4
from src.llm_client import LLMClient as LC
rc = ResumeCustomizer.__new__(ResumeCustomizer)
rc.llm = LC.__new__(LC)
rc.resume_text = ''
rc.output_dir = 'data/output/resumes/_v4_backfill_test'
os.makedirs(rc.output_dir, exist_ok=True)
rc.fast_model_cfg = {"model": "fake", "api_key": "fake", "base_url": "https://fake"}
rc._pending_summary_inject = []
print('━' * 78)
print(f'{"JD":<48} {"v4_only":>9} {"FinalATS":>9} {"Roles":>6} {"Words":>6}')
print('━' * 78)
jd_files = {
'airtel_pm': ('Product Manager', 'Airtel'),
'sumo_logic_pm': ('Product Manager', 'Sumo Logic'),
'edgeverve_pm': ('Product Manager', 'EdgeVerve'),
'aditya_birla_apm': ('Associate Product Manager', 'Aditya Birla Capital'),
}
for jd_file, (role_title, company) in jd_files.items():
with open(f'tests/fixtures/jds/{jd_file}.txt', encoding='utf-8') as f:
jd = f.read()
job = {
"title": role_title,
"company": company,
"description": jd,
"_raw_assessment": {"ats_keywords": []},
}
filepath = os.path.join(rc.output_dir, f'{company.replace(" ", "_")}_{jd_file}.docx')
# Call the actual v4 flow
result = rc._generate_resume_v4(job, cfg=rc.fast_model_cfg, filepath=filepath)
if not result:
print(f'{(role_title + " @ " + company):<48} v4 FAILED')
continue
text = _read_docx_text(result)
r = score_resume(text, jd)
# Count roles + words in the actual generated DOCX
from docx import Document
doc = Document(result)
role_lines = sum(
1 for p in doc.paragraphs
if p.text and any(co in p.text for co in ["NxtWave", "Think & Learn", "ML Edutech", "BYJU"])
)
print(f'{(role_title + " @ " + company):<48} {"weak":>9} {r["ats_score"]:>8} {role_lines:>4} {r["word_count"]:>5}')
print('━' * 78)
print('\nThis test simulates the WORST case: LLM returns 2 roles only, no')
print('pitch, 3 bullets each. v4 backfill + pitch enforcement + weaving')
print('should still produce 90%+ resumes with all 4 candidate roles preserved.')
|