feat: add Jobgether recruiter framing to cover letter generation
Some checks failed
CI / test (push) Failing after 32s
Some checks failed
CI / test (push) Failing after 32s
When source == "jobgether", build_prompt() injects a recruiter context
note directing the LLM to address the Jobgether recruiter using
"Your client [at {company}] will appreciate..." framing rather than
addressing the employer directly. generate() and task_runner both
thread the is_jobgether flag through automatically.
This commit is contained in:
parent
e6257249cb
commit
94fd2ea332
4 changed files with 64 additions and 2 deletions
|
|
@ -189,6 +189,7 @@ def build_prompt(
|
|||
description: str,
|
||||
examples: list[dict],
|
||||
mission_hint: str | None = None,
|
||||
is_jobgether: bool = False,
|
||||
) -> str:
|
||||
parts = [SYSTEM_CONTEXT.strip(), ""]
|
||||
if examples:
|
||||
|
|
@ -202,6 +203,24 @@ def build_prompt(
|
|||
if mission_hint:
|
||||
parts.append(f"⭐ Mission alignment note (for Para 3): {mission_hint}\n")
|
||||
|
||||
if is_jobgether:
|
||||
if company and company.lower() != "jobgether":
|
||||
recruiter_note = (
|
||||
f"🤝 Recruiter context: This listing is posted by Jobgether on behalf of "
|
||||
f"{company}. Address the cover letter to the Jobgether recruiter, not directly "
|
||||
f"to the hiring company. Use framing like 'Your client at {company} will "
|
||||
f"appreciate...' rather than addressing {company} directly. The role "
|
||||
f"requirements are those of the actual employer."
|
||||
)
|
||||
else:
|
||||
recruiter_note = (
|
||||
"🤝 Recruiter context: This listing is posted by Jobgether on behalf of an "
|
||||
"undisclosed employer. Address the cover letter to the Jobgether recruiter. "
|
||||
"Use framing like 'Your client will appreciate...' rather than addressing "
|
||||
"the company directly."
|
||||
)
|
||||
parts.append(f"{recruiter_note}\n")
|
||||
|
||||
parts.append(f"Now write a new cover letter for:")
|
||||
parts.append(f" Role: {title}")
|
||||
parts.append(f" Company: {company}")
|
||||
|
|
@ -236,6 +255,7 @@ def generate(
|
|||
description: str = "",
|
||||
previous_result: str = "",
|
||||
feedback: str = "",
|
||||
is_jobgether: bool = False,
|
||||
_router=None,
|
||||
) -> str:
|
||||
"""Generate a cover letter and return it as a string.
|
||||
|
|
@ -251,7 +271,8 @@ def generate(
|
|||
mission_hint = detect_mission_alignment(company, description)
|
||||
if mission_hint:
|
||||
print(f"[cover-letter] Mission alignment detected for {company}", file=sys.stderr)
|
||||
prompt = build_prompt(title, company, description, examples, mission_hint=mission_hint)
|
||||
prompt = build_prompt(title, company, description, examples,
|
||||
mission_hint=mission_hint, is_jobgether=is_jobgether)
|
||||
|
||||
if previous_result:
|
||||
prompt += f"\n\n---\nPrevious draft:\n{previous_result}"
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ def _run_task(db_path: Path, task_id: int, task_type: str, job_id: int,
|
|||
job.get("description", ""),
|
||||
previous_result=p.get("previous_result", ""),
|
||||
feedback=p.get("feedback", ""),
|
||||
is_jobgether=job.get("source") == "jobgether",
|
||||
)
|
||||
update_cover_letter(db_path, job_id, result)
|
||||
|
||||
|
|
|
|||
|
|
@ -115,3 +115,41 @@ def test_generate_calls_llm_router():
|
|||
|
||||
mock_router.complete.assert_called_once()
|
||||
assert "Alex Rivera" in result
|
||||
|
||||
|
||||
# ── Jobgether recruiter framing tests ─────────────────────────────────────────
|
||||
|
||||
def test_build_prompt_jobgether_framing_unknown_company():
|
||||
from scripts.generate_cover_letter import build_prompt
|
||||
prompt = build_prompt(
|
||||
title="Customer Success Manager",
|
||||
company="Jobgether",
|
||||
description="CSM role at an undisclosed company.",
|
||||
examples=[],
|
||||
is_jobgether=True,
|
||||
)
|
||||
assert "Your client" in prompt
|
||||
assert "jobgether" in prompt.lower()
|
||||
|
||||
|
||||
def test_build_prompt_jobgether_framing_known_company():
|
||||
from scripts.generate_cover_letter import build_prompt
|
||||
prompt = build_prompt(
|
||||
title="Customer Success Manager",
|
||||
company="Resware",
|
||||
description="CSM role at Resware.",
|
||||
examples=[],
|
||||
is_jobgether=True,
|
||||
)
|
||||
assert "Your client at Resware" in prompt
|
||||
|
||||
|
||||
def test_build_prompt_no_jobgether_framing_by_default():
|
||||
from scripts.generate_cover_letter import build_prompt
|
||||
prompt = build_prompt(
|
||||
title="Customer Success Manager",
|
||||
company="Acme Corp",
|
||||
description="CSM role.",
|
||||
examples=[],
|
||||
)
|
||||
assert "Your client" not in prompt
|
||||
|
|
|
|||
|
|
@ -79,10 +79,12 @@ class TestTaskRunnerCoverLetterParams:
|
|||
"""Invoke _run_task for cover_letter and return captured generate() kwargs."""
|
||||
captured = {}
|
||||
|
||||
def mock_generate(title, company, description="", previous_result="", feedback="", _router=None):
|
||||
def mock_generate(title, company, description="", previous_result="", feedback="",
|
||||
is_jobgether=False, _router=None):
|
||||
captured.update({
|
||||
"title": title, "company": company,
|
||||
"previous_result": previous_result, "feedback": feedback,
|
||||
"is_jobgether": is_jobgether,
|
||||
})
|
||||
return "Generated letter"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue