Noo88ear's picture
πŸš€ Initial deployment of Multi-Agent Job Application Assistant
7498f2c
from __future__ import annotations
from dataclasses import dataclass
from typing import Callable, Dict, Any, List, Tuple
import re
@dataclass
class Guideline:
id: str
description: str
condition: Callable[[Dict[str, Any]], bool]
validate: Callable[[str, Dict[str, Any]], Tuple[bool, str]]
enforce: Callable[[str, Dict[str, Any]], str]
class GuidelineEngine:
def __init__(self, rules: List[Guideline]) -> None:
self.rules = rules
def check_and_enforce(self, text: str, ctx: Dict[str, Any]) -> Tuple[str, List[str], List[str]]:
matched: List[str] = []
fixed: List[str] = []
out = text or ""
for g in self.rules:
try:
if not g.condition(ctx):
continue
matched.append(g.id)
ok, _ = g.validate(out, ctx)
if not ok:
out = g.enforce(out, ctx)
fixed.append(g.id)
except Exception:
# fail-safe, do not block
continue
return out, matched, fixed
# ---------- Helpers ----------
_BUZZWORDS = [
"results-driven", "team player", "people person", "perfectionist",
"multi-tasker", "multi tasker", "dynamic go-getter", "rockstar",
"guru", "ninja"
]
_WEAK_OPENERS = [
(re.compile(r"^\s*[-β€’]\s*responsible for\s+", re.I), "- Led "),
(re.compile(r"^\s*[-β€’]\s*tasked with\s+", re.I), "- Executed "),
(re.compile(r"^\s*[-β€’]\s*worked on\s+", re.I), "- Delivered "),
(re.compile(r"^\s*[-β€’]\s*helped\s+", re.I), "- Supported "),
(re.compile(r"^\s*[-β€’]\s*assisted with\s+", re.I), "- Supported "),
(re.compile(r"^\s*[-β€’]\s*handled\s+", re.I), "- Managed "),
]
def _enforce_exact_length(text: str, target_len: int) -> str:
if target_len <= 0:
return text or ""
txt = (text or "")
if len(txt) == target_len:
return txt
if len(txt) > target_len:
return txt[:target_len]
return txt + (" " * (target_len - len(txt)))
def _ensure_headings(text: str) -> str:
"""Ensure key headings exist: SUMMARY, SKILLS, EXPERIENCE, EDUCATION."""
t = text or ""
low = t.lower()
out = t
def add_heading(h: str) -> None:
nonlocal out
if h.lower() not in low:
out = (out + f"\n\n{h}\n").strip()
for h in ["SUMMARY", "SKILLS", "EXPERIENCE", "EDUCATION"]:
if h.lower() not in low:
add_heading(h)
return out
def _strip_tabs(text: str) -> str:
return (text or "").replace("\t", " ")
def _scrub_buzzwords(text: str) -> str:
out = text or ""
low = out.lower()
for bw in _BUZZWORDS:
if bw in low:
out = re.sub(re.escape(bw), "", out, flags=re.I)
return out
def _strengthen_action_verbs(text: str) -> str:
lines = (text or "").splitlines()
fixed: List[str] = []
for ln in lines:
new_ln = ln
for pat, repl in _WEAK_OPENERS:
if pat.search(new_ln):
new_ln = pat.sub(repl, new_ln)
break
fixed.append(new_ln)
return "\n".join(fixed)
def _remove_first_person(text: str) -> str:
# Remove leading "I " / "My " in bullets only
lines = (text or "").splitlines()
out: List[str] = []
for ln in lines:
m = re.match(r"^\s*[-β€’]\s*(i|my|we)\b", ln, flags=re.I)
if m:
ln = re.sub(r"^\s*([-β€’]\s*)(i|my|we)\b\s*", r"\1", ln, flags=re.I)
out.append(ln)
return "\n".join(out)
def _ats_plain_text(text: str) -> str:
# normalize bullets and strip odd symbols
out = _strip_tabs(text)
out = out.replace("β€’\t", "- ").replace("β€’ ", "- ")
out = re.sub(r"[β– β–ͺβ—¦β—β—‹βœ”βœ¦β™¦]", "-", out)
return out
def _enforce_uk_habits(text: str) -> str:
# normalize currency symbol spacing and percentages
out = re.sub(r"\s*Β£\s*", " Β£", text or "")
out = re.sub(r"\s*%\s*", "%", out)
return out
def _allowed_skills_from_profile(ctx: Dict[str, Any]) -> List[str]:
p = (ctx.get("profile_text") or "").lower()
# naive split of alphanum skill-like tokens
cands = re.findall(r"[a-zA-Z][a-zA-Z0-9+_.#-]{2,}", p)
seen: Dict[str, int] = {}
for c in cands:
seen[c.lower()] = 1
return list(seen.keys())
def _no_invented_skills(text: str, ctx: Dict[str, Any]) -> Tuple[bool, str]:
allowed = set(_allowed_skills_from_profile(ctx))
if not allowed:
return True, "no baseline"
skills_block = re.search(r"(?is)\n\s*(skills|core skills)[\s:]*\n(.+?)(\n\n|$)", text or "")
if not skills_block:
return True, "no skills block"
block = skills_block.group(0)
found = re.findall(r"[A-Za-z][A-Za-z0-9+_.#-]{2,}", block)
for f in found:
if f.lower() not in allowed:
return False, f
return True, "ok"
# ---------- Rule sets ----------
def build_resume_rules() -> List[Guideline]:
return [
Guideline(
id="exact_length",
description="Enforce exact target length when provided",
condition=lambda ctx: bool(ctx.get("target_len")),
validate=lambda txt, ctx: (len(txt or "") == int(ctx.get("target_len", 0)), "len"),
enforce=lambda txt, ctx: _enforce_exact_length(txt, int(ctx.get("target_len", 0))),
),
Guideline(
id="headings_present",
description="Ensure key headings exist",
condition=lambda ctx: True,
validate=lambda txt, ctx: (all(h.lower() in (txt or "").lower() for h in ["summary", "experience", "education", "skills"]), "headings"),
enforce=lambda txt, ctx: _ensure_headings(txt),
),
Guideline(
id="ats_plain_text",
description="Normalize bullets/tabs for ATS",
condition=lambda ctx: True,
validate=lambda txt, ctx: ("\t" not in (txt or ""), "tabs"),
enforce=lambda txt, ctx: _ats_plain_text(txt),
),
Guideline(
id="buzzword_scrub",
description="Remove common buzzwords",
condition=lambda ctx: True,
validate=lambda txt, ctx: (not any(bw in (txt or "").lower() for bw in _BUZZWORDS), "buzz"),
enforce=lambda txt, ctx: _scrub_buzzwords(txt),
),
Guideline(
id="verb_strengthen",
description="Strengthen weak bullet openers",
condition=lambda ctx: True,
validate=lambda txt, ctx: (True, "noop"),
enforce=lambda txt, ctx: _strengthen_action_verbs(txt),
),
Guideline(
id="remove_first_person",
description="Remove first-person pronouns on bullets",
condition=lambda ctx: True,
validate=lambda txt, ctx: (not re.search(r"^\s*[-β€’]\s*(i|my|we)\b", txt or "", re.I | re.M), "pronouns"),
enforce=lambda txt, ctx: _remove_first_person(txt),
),
Guideline(
id="uk_normalization",
description="Normalize UK currency/percent spacing",
condition=lambda ctx: True,
validate=lambda txt, ctx: (True, "noop"),
enforce=lambda txt, ctx: _enforce_uk_habits(txt),
),
Guideline(
id="no_invented_skills",
description="Prevent skills not evidenced in profile",
condition=lambda ctx: True,
validate=_no_invented_skills,
enforce=lambda txt, ctx: txt, # log-only to avoid false positives
),
]
def build_cover_rules() -> List[Guideline]:
return [
Guideline(
id="exact_length",
description="Enforce exact target length when provided",
condition=lambda ctx: bool(ctx.get("target_len")),
validate=lambda txt, ctx: (len(txt or "") == int(ctx.get("target_len", 0)), "len"),
enforce=lambda txt, ctx: _enforce_exact_length(txt, int(ctx.get("target_len", 0))),
),
Guideline(
id="ats_plain_text",
description="Normalize bullets/tabs for ATS",
condition=lambda ctx: True,
validate=lambda txt, ctx: ("\t" not in (txt or ""), "tabs"),
enforce=lambda txt, ctx: _ats_plain_text(txt),
),
Guideline(
id="buzzword_scrub",
description="Remove common buzzwords",
condition=lambda ctx: True,
validate=lambda txt, ctx: (not any(bw in (txt or "").lower() for bw in _BUZZWORDS), "buzz"),
enforce=lambda txt, ctx: _scrub_buzzwords(txt),
),
]
def apply_resume_guidelines(text: str, ctx: Dict[str, Any]) -> Tuple[str, List[str], List[str]]:
engine = GuidelineEngine(build_resume_rules())
return engine.check_and_enforce(text, ctx)
def apply_cover_guidelines(text: str, ctx: Dict[str, Any]) -> Tuple[str, List[str], List[str]]:
engine = GuidelineEngine(build_cover_rules())
return engine.check_and_enforce(text, ctx)