job-chat / skills.py
codegood's picture
major changes including skills added, router, ats, etc
be97847
Raw History Blame Contribute Delete
1.8 kB
"""Skill registry.
Each skill is a markdown file in skills/ that becomes the model's operating
instructions for one task. The four buttons in the UI run them directly, and the
semantic router sends matching free-form requests to the same skills.
"""
from dataclasses import dataclass
from functools import lru_cache
from config import PROJECT_ROOT
SKILLS_DIR = PROJECT_ROOT / "skills"
@dataclass(frozen=True)
class Skill:
label: str # button text
filename: str
instruction: str # the user turn a button click sends
SKILLS = {
"review": Skill(
"Resume review",
"review-resume-detailed.md",
"Run the resume review skill on my resume against the loaded job description.",
),
"ats": Skill(
"ATS score & keywords",
"analyze-ats-keywords.md",
"Run the ATS keyword analysis skill on my resume against the loaded job description.",
),
"cover_letter": Skill(
"Cover letter",
"write-cover-letter.md",
"Write my cover letter for the loaded job description using the cover letter skill.",
),
"email": Skill(
"Application email",
"email-writing.md",
"Write my direct application email for the loaded job description using the email skill.",
),
}
# Skills that write prose rather than analyse, and so use a higher temperature.
DRAFTING_SKILLS = {"cover_letter", "email"}
# Button order and (label, instruction) pairs, as the UI consumes them.
ACTIONS = {key: (skill.label, skill.instruction) for key, skill in SKILLS.items()}
@lru_cache(maxsize=None)
def load_skill(key: str) -> str:
"""The skill's markdown, read once. Raises if the file is missing."""
path = SKILLS_DIR / SKILLS[key].filename
return path.read_text(encoding="utf-8").strip()