HR-ATS-Portal/backend/agent/decorators.py

77 lines
2.4 KiB
Python

"""Agent response parsers and input normalizers.
Pure module: no FastAPI imports, no HTTPException, and no module-level state.
Mirrors job/candidate/decorators.py — helpers that clean/shape data before or
after the graph nodes run.
"""
from __future__ import annotations
import uuid
def normalize_job_posts(job_posts) -> list[dict]:
"""Keep only dict items with an id field; stringify ids for the LLM."""
if not job_posts:
return []
normalized: list[dict] = []
for item in job_posts:
if not isinstance(item, dict):
continue
job_id = item.get("id")
if job_id is None:
continue
normalized.append(
{
"id": str(job_id),
"title": item.get("title") or "",
"description": item.get("description") or "",
"post_text": item.get("post_text") or "",
"requirements": item.get("requirements") or [],
"optional_skills": item.get("optional_skills") or [],
"location": item.get("location") or "",
"employment_type": item.get("employment_type") or "",
}
)
return normalized
def parse_match_response(data, allowed_ids) -> tuple[list[str], str, str]:
"""Filter model JSON ids to the allowed job-post set."""
if not isinstance(data, dict):
raise RuntimeError(f"model did not return a JSON object: {data!r}")
allowed = set(allowed_ids or [])
raw_ids = data.get("suggested_job_post_ids") or []
if not isinstance(raw_ids, list):
raw_ids = []
suggested: list[str] = []
seen: set[str] = set()
for raw_id in raw_ids:
job_id = str(raw_id).strip()
if not job_id or job_id not in allowed or job_id in seen:
continue
try:
uuid.UUID(job_id)
except ValueError:
continue
seen.add(job_id)
suggested.append(job_id)
summary = data.get("summary")
if not isinstance(summary, str):
summary = ""
reasoning = data.get("reasoning")
if isinstance(reasoning, list):
reasoning = "\n".join(str(item) for item in reasoning)
if not isinstance(reasoning, str):
reasoning = ""
experience = data.get("experience")
if not isinstance(experience, str):
experience = ""
return suggested, summary.strip(), reasoning.strip(), experience.strip()