init: resume 작성 하네스 설계
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from resume_harness.io import load_model
|
||||
from resume_harness.models import (
|
||||
CandidateProfile,
|
||||
ContentPlan,
|
||||
EvidenceMap,
|
||||
GenerationConfig,
|
||||
JobAnalysis,
|
||||
JobPosting,
|
||||
QualityReport,
|
||||
ResumeDraft,
|
||||
)
|
||||
from resume_harness.pipeline import PipelineStatus, ResumePipeline
|
||||
from resume_harness.renderer import render_markdown
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class GoldenFixtureBackend:
|
||||
def __init__(self, responses: list[tuple[str, BaseModel]]) -> None:
|
||||
self._responses = list(responses)
|
||||
|
||||
def complete_json(
|
||||
self,
|
||||
*,
|
||||
stage: str,
|
||||
system_prompt: str,
|
||||
task_prompt: str,
|
||||
user_payload: Mapping[str, Any],
|
||||
output_model: type[BaseModel],
|
||||
) -> BaseModel:
|
||||
assert system_prompt and task_prompt and user_payload
|
||||
expected_stage, response = self._responses.pop(0)
|
||||
assert stage == expected_stage
|
||||
assert isinstance(response, output_model)
|
||||
return response
|
||||
|
||||
|
||||
def test_professional_golden_fixture_passes_full_pipeline_and_renders() -> None:
|
||||
profile = load_model(ROOT / "examples/candidate.sample.yaml", CandidateProfile)
|
||||
posting = load_model(ROOT / "examples/job.sample.yaml", JobPosting)
|
||||
config = load_model(ROOT / "examples/config.sample.yaml", GenerationConfig)
|
||||
analysis = load_model(ROOT / "examples/job-analysis.sample.yaml", JobAnalysis)
|
||||
evidence_map = load_model(ROOT / "examples/evidence-map.sample.yaml", EvidenceMap)
|
||||
plan = load_model(ROOT / "examples/content-plan.sample.yaml", ContentPlan)
|
||||
draft = load_model(ROOT / "examples/draft.sample.yaml", ResumeDraft)
|
||||
report = load_model(ROOT / "examples/quality-report.sample.yaml", QualityReport)
|
||||
backend = GoldenFixtureBackend(
|
||||
[
|
||||
("analyze-job", analysis),
|
||||
("map-evidence", evidence_map),
|
||||
("plan-content", plan),
|
||||
("draft-resume", draft),
|
||||
("evaluate-resume", report),
|
||||
]
|
||||
)
|
||||
|
||||
result = ResumePipeline(backend).run(profile, posting, config)
|
||||
|
||||
assert result.status is PipelineStatus.PASSED
|
||||
assert result.deterministic_findings == []
|
||||
assert result.quality_report is not None
|
||||
assert result.quality_report.evidence_coverage == 1.0
|
||||
assert result.quality_report.requirement_coverage == 1.0
|
||||
markdown = render_markdown(result.draft, profile, config, analysis=analysis)
|
||||
assert "## 핵심 역량" in markdown
|
||||
assert "## 경력" in markdown
|
||||
assert "## 주요 프로젝트" in markdown
|
||||
assert "## 자격" in markdown
|
||||
assert markdown.count("\n- ") >= 16
|
||||
Reference in New Issue
Block a user