Download server/tools.py from dipsha/recruiter: direct link, hf CLI and curl.
- Browser
- Download file 16.8 kB
-
https://huggingface.co/spaces/dipsha/recruiter/resolve/main/server/tools.py
- Command line
-
hf download hf://spaces/dipsha/recruiter/server/tools.py
-
curl -L -o tools.py https://huggingface.co/spaces/dipsha/recruiter/resolve/main/server/tools.py
16.8 kB
| # Copyright (c) Meta Platforms, Inc. and affiliates. | |
| # All rights reserved. | |
| # | |
| # This source code is licensed under the BSD-style license found in the | |
| # LICENSE file in the root directory of this source tree. | |
| """ | |
| ToolDispatcher — deterministic probe responses driven by CandidateGroundTruth. | |
| Each tool validates its query against the candidate profile and returns a | |
| result consistent with the injected fake_signals. Wrong-tool / missing-data | |
| calls charge the probe cost and return "not found" style messages. | |
| Day-3 upgrade: swap _llm_screening_call() for a real Anthropic API call. | |
| """ | |
| from __future__ import annotations | |
| from typing import Optional | |
| try: | |
| from ..models import ( | |
| CandidateGroundTruth, | |
| CandidateProfile, | |
| JobDescription, | |
| ToolType, | |
| ) | |
| from .scratchpad import EpisodeScratchpad | |
| except ImportError: | |
| from models import ( | |
| CandidateGroundTruth, | |
| CandidateProfile, | |
| JobDescription, | |
| ToolType, | |
| ) | |
| from server.scratchpad import EpisodeScratchpad | |
| class ToolDispatcher: | |
| """Dispatches tool calls to deterministic per-tool handlers.""" | |
| def run( | |
| self, | |
| tool: ToolType, | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| scratchpad: EpisodeScratchpad, | |
| ) -> str: | |
| handler = _HANDLERS.get(tool) | |
| if handler is None: | |
| return f"[{tool.value.upper()}] Tool not implemented." | |
| return handler(query, candidate, gt, jd, scratchpad) | |
| # ── Individual tool handlers ────────────────────────────────────────────────── | |
| def _verify_employment( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| if not query: | |
| return "[VERIFY_EMPLOYMENT] Provide query as 'Company Name, Job Title'." | |
| company = query.split(",")[0].strip() | |
| if not any(e.company.lower() == company.lower() for e in candidate.work_history): | |
| return ( | |
| f"[VERIFY_EMPLOYMENT] '{company}' not found in candidate's work history. " | |
| "Verify the company name matches exactly." | |
| ) | |
| for sig in gt.fake_signals: | |
| if sig.startswith("company_nonexistent:"): | |
| fake_co = sig.split(":", 1)[1] | |
| if fake_co.lower() in company.lower() or company.lower() in fake_co.lower(): | |
| return ( | |
| f"[VERIFY_EMPLOYMENT] '{company}' could not be found in business " | |
| "registries or public filings. No matching corporate entity. " | |
| "Likely fictitious employer." | |
| ) | |
| return ( | |
| f"[VERIFY_EMPLOYMENT] '{company}' is a registered business. " | |
| "Role appears consistent with company profile and size." | |
| ) | |
| def _check_employment_dates( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| if not query: | |
| return "[CHECK_EMPLOYMENT_DATES] Provide query as 'Company Name, Start–End'." | |
| company = query.split(",")[0].strip() | |
| if not any(e.company.lower() == company.lower() for e in candidate.work_history): | |
| return ( | |
| f"[CHECK_EMPLOYMENT_DATES] '{company}' not found in candidate's work history." | |
| ) | |
| if any("impossible_dates" in s or "overlap" in s for s in gt.fake_signals): | |
| return ( | |
| f"[CHECK_EMPLOYMENT_DATES] Date inconsistency at '{company}': tenure overlaps " | |
| "with another listed role by 14 months. Timeline is not physically possible." | |
| ) | |
| return ( | |
| f"[CHECK_EMPLOYMENT_DATES] Dates at '{company}' are internally consistent. " | |
| "No overlaps or impossible gaps detected." | |
| ) | |
| def _check_linkedin( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| url = candidate.online_profiles.get("linkedin") | |
| if not url: | |
| return "[CHECK_LINKEDIN] No LinkedIn URL in candidate profile. Cannot verify." | |
| if "linkedin_mismatch" in gt.fake_signals: | |
| return ( | |
| "[CHECK_LINKEDIN] Discrepancies found: resume title and tenure differ " | |
| "from LinkedIn profile. Example: resume states 'Lead Engineer 2019–2022'; " | |
| "LinkedIn shows 'Junior Developer 2020–2021'. Titles and dates conflict." | |
| ) | |
| return ( | |
| "[CHECK_LINKEDIN] LinkedIn profile is consistent with resume. " | |
| "Titles, companies, and dates align. Endorsements match listed skills." | |
| ) | |
| def _check_online_profile( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| # Agent should pass the URL from online_profiles relevant to the JD domain | |
| url = query | |
| if not url: | |
| # Fallback: pick any non-LinkedIn profile | |
| url = next( | |
| (v for k, v in candidate.online_profiles.items() if k != "linkedin"), None | |
| ) | |
| if not url: | |
| return ( | |
| "[CHECK_ONLINE_PROFILE] No relevant online profile URL found. " | |
| "Candidate has no GitHub, portfolio, or domain-specific profile listed." | |
| ) | |
| if "github_burst" in gt.fake_signals and ("github" in url.lower() or "git" in url.lower()): | |
| return ( | |
| "[CHECK_ONLINE_PROFILE] GitHub activity anomaly detected: 1,247 commits " | |
| "concentrated in a 48-hour window 3 days before the application date. " | |
| "Account created 5 months ago. No pull requests or collaborative " | |
| "contributions. Commit messages are non-descriptive. " | |
| "Profile activity pattern consistent with fabricated history." | |
| ) | |
| if "portfolio_burst" in gt.fake_signals: | |
| return ( | |
| "[CHECK_ONLINE_PROFILE] Portfolio domain registered 6 days before " | |
| "application. All project dates post-date the registration. " | |
| "Likely created specifically for this application." | |
| ) | |
| return ( | |
| f"[CHECK_ONLINE_PROFILE] Profile at {url} shows consistent activity " | |
| "spanning 3+ years. Contributions match claimed skill set. No anomalies." | |
| ) | |
| def _verify_education( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| if not query: | |
| return "[VERIFY_EDUCATION] Provide query as 'Degree, Institution, Year'." | |
| if "fake_degree" in gt.fake_signals: | |
| parts = query.split(",") | |
| inst = parts[1].strip() if len(parts) > 1 else "listed institution" | |
| return ( | |
| f"[VERIFY_EDUCATION] '{inst}' does not offer the claimed degree program. " | |
| "No public records of this degree conferred. Graduation year is also " | |
| "inconsistent with stated class size data." | |
| ) | |
| return ( | |
| "[VERIFY_EDUCATION] Education credentials verified. Degree and graduation " | |
| "year are consistent with institution records." | |
| ) | |
| def _contact_reference( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| if not candidate.references: | |
| return "[CONTACT_REFERENCE] No references listed in this candidate's profile." | |
| referee_name = (query or "").strip() or candidate.references[0].name | |
| # Check if this referee is in the references list | |
| ref_match = next( | |
| (r for r in candidate.references if referee_name.lower() in r.name.lower()), | |
| None, | |
| ) | |
| if ref_match is None: | |
| return ( | |
| f"[CONTACT_REFERENCE] '{referee_name}' not found in candidate's " | |
| "listed references. Check the name spelling." | |
| ) | |
| for sig in gt.fake_signals: | |
| if sig.startswith("reference_wrong_company:"): | |
| fake_ref = sig.split(":", 1)[1] | |
| if fake_ref.lower() in referee_name.lower() or referee_name.lower() in fake_ref.lower(): | |
| return ( | |
| f"[CONTACT_REFERENCE] {referee_name}: Contact confirmed. " | |
| f"However, they state they worked at a different organisation — " | |
| f"not '{ref_match.company}' as listed. No direct employment " | |
| "overlap with candidate confirmed. Reference appears invalid." | |
| ) | |
| return ( | |
| f"[CONTACT_REFERENCE] {referee_name}: Confirmed working relationship " | |
| f"at {ref_match.company}. Reference is positive. " | |
| f"Relationship described as: {ref_match.relationship}." | |
| ) | |
| def _review_timeline( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| if any("impossible" in s or "overlap" in s for s in gt.fake_signals): | |
| return ( | |
| "[REVIEW_TIMELINE] Timeline issues detected: role overlap of 14 months " | |
| "between two listed positions. Candidate claims 8 years experience but " | |
| "earliest role starts only 5 years ago. At least one date range is " | |
| "physically impossible." | |
| ) | |
| if not candidate.work_history: | |
| return "[REVIEW_TIMELINE] No work history to review." | |
| total_years = len(candidate.work_history) * 2 # rough heuristic for stub | |
| return ( | |
| f"[REVIEW_TIMELINE] Work history timeline is internally consistent. " | |
| f"No overlaps or impossible progressions. " | |
| f"{len(candidate.work_history)} roles covering an estimated {total_years}+ years." | |
| ) | |
| def _check_skills_fit( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| if "skills_not_in_history" in gt.fake_signals: | |
| return ( | |
| "[CHECK_SKILLS_FIT] Significant mismatch: candidate lists " | |
| f"{', '.join(candidate.skills[:4])} — but all roles in work history " | |
| "are in sales/account management with no engineering responsibilities. " | |
| "Skills appear entirely fabricated relative to work history. " | |
| f"JD requires: {', '.join(jd.required_skills[:3])}." | |
| ) | |
| overlap = [s for s in candidate.skills if s in jd.required_skills] | |
| missing = [s for s in jd.required_skills if s not in candidate.skills] | |
| return ( | |
| f"[CHECK_SKILLS_FIT] {len(overlap)}/{len(jd.required_skills)} required skills present. " | |
| f"Match: {', '.join(overlap) or 'none'}. " | |
| f"Missing: {', '.join(missing) or 'none'}. " | |
| "Skills are evidenced in work history." | |
| ) | |
| def _verify_claim( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| if not query: | |
| return "[VERIFY_CLAIM] Provide a specific bullet-point achievement string from work history." | |
| # Check the claim exists in some bullet point | |
| claim_text = query.lower() | |
| found = any( | |
| claim_text in bp.lower() | |
| for entry in candidate.work_history | |
| for bp in entry.bullet_points | |
| ) | |
| if not found: | |
| return ( | |
| f"[VERIFY_CLAIM] Claim text not found in candidate's listed work history " | |
| "bullet points. Verify the exact text matches." | |
| ) | |
| if "inflated_claim" in gt.fake_signals: | |
| return ( | |
| f"[VERIFY_CLAIM] Claim appears implausible: company had ~15 employees " | |
| f"at the time. '{query[:60]}' is inconsistent with company scale and " | |
| "typical responsibilities at that role level." | |
| ) | |
| return ( | |
| f"[VERIFY_CLAIM] Claim '{query[:60]}' appears consistent with " | |
| "company size and role level. Corroborating public data found." | |
| ) | |
| def _verify_location( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| if "location_mismatch" in gt.fake_signals: | |
| sponsorship_note = ( | |
| " ⚠ JD requires no visa sponsorship — this candidate would need sponsorship." | |
| if not jd.sponsorship_available | |
| else "" | |
| ) | |
| return ( | |
| f"[VERIFY_LOCATION] Location mismatch: stated '{candidate.stated_location}' " | |
| f"but GitHub commit timestamps and IP geolocation signals indicate " | |
| f"actual location '{gt.true_location}'.{sponsorship_note}" | |
| ) | |
| sponsorship_ok = ( | |
| "" if jd.sponsorship_available | |
| else f" No sponsorship needed — consistent with JD constraint." | |
| ) | |
| return ( | |
| f"[VERIFY_LOCATION] Location '{candidate.stated_location}' is consistent " | |
| f"with profile signals (GitHub timezone, commit patterns, company office).{sponsorship_ok}" | |
| ) | |
| def _search_web( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| if not query: | |
| return "[SEARCH_WEB] Provide a search query." | |
| if gt.is_fake and any( | |
| s.startswith("company_nonexistent") for s in gt.fake_signals | |
| ): | |
| fake_co = next( | |
| (s.split(":", 1)[1] for s in gt.fake_signals if s.startswith("company_nonexistent:")), | |
| None, | |
| ) | |
| if fake_co and fake_co.lower() in query.lower(): | |
| return ( | |
| f"[SEARCH_WEB] '{query}': No results found for this company in " | |
| "LinkedIn, Crunchbase, or public business directories. " | |
| "Zero press mentions. Entity appears fictitious." | |
| ) | |
| return ( | |
| f"[SEARCH_WEB] Results for '{query}': No significant red flags in public " | |
| "records. Candidate's stated employer and role appear in professional networks." | |
| ) | |
| def _request_screening_round( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| _pad: EpisodeScratchpad, | |
| ) -> str: | |
| if gt.is_fake: | |
| return ( | |
| "[REQUEST_SCREENING_ROUND] 30-min screening call completed.\n" | |
| "Technical section: candidate was unable to describe implementation " | |
| "details of listed projects. Answers were vague and inconsistent under " | |
| "follow-up probing.\n" | |
| "Behavioural section: story changed when asked about specific timelines. " | |
| "Claimed promotion dates conflict with dates given earlier in the call.\n" | |
| "Competency: technical answers inconsistent with claimed senior-level " | |
| "experience. Unable to solve a standard problem in the claimed primary language.\n" | |
| "Overall: negative indicators across all three sections." | |
| ) | |
| return ( | |
| "[REQUEST_SCREENING_ROUND] 30-min screening call completed.\n" | |
| "Technical section: demonstrated strong depth. Clear explanations of " | |
| "system design decisions and trade-offs.\n" | |
| "Behavioural section: consistent narrative with specific examples. " | |
| "Timelines align with resume.\n" | |
| "Competency: solved the coding problem efficiently with good communication.\n" | |
| "Overall: positive indicators. Recommend advancing." | |
| ) | |
| def _note( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| pad: EpisodeScratchpad, | |
| ) -> str: | |
| return pad.note(candidate.candidate_id, query or "") | |
| def _recall( | |
| query: Optional[str], | |
| candidate: CandidateProfile, | |
| gt: CandidateGroundTruth, | |
| jd: JobDescription, | |
| pad: EpisodeScratchpad, | |
| ) -> str: | |
| return pad.recall(query) | |
| # ── Handler dispatch table ──────────────────────────────────────────────────── | |
| _HANDLERS = { | |
| ToolType.VERIFY_EMPLOYMENT: _verify_employment, | |
| ToolType.CHECK_EMPLOYMENT_DATES: _check_employment_dates, | |
| ToolType.CHECK_LINKEDIN: _check_linkedin, | |
| ToolType.CHECK_ONLINE_PROFILE: _check_online_profile, | |
| ToolType.VERIFY_EDUCATION: _verify_education, | |
| ToolType.CONTACT_REFERENCE: _contact_reference, | |
| ToolType.REVIEW_TIMELINE: _review_timeline, | |
| ToolType.CHECK_SKILLS_FIT: _check_skills_fit, | |
| ToolType.VERIFY_CLAIM: _verify_claim, | |
| ToolType.VERIFY_LOCATION: _verify_location, | |
| ToolType.SEARCH_WEB: _search_web, | |
| ToolType.REQUEST_SCREENING_ROUND: _request_screening_round, | |
| ToolType.NOTE: _note, | |
| ToolType.RECALL: _recall, | |
| } | |