Files
matchmaking-v2/tests/test_curate.py
raulgupta b1e9cdd182 Engine v2: embeddings sift + Opus curator + Postgres feed persistence
- A1: fire the hard filter (Apify is precise); embedding vibe-ranker (embed.py)
  blends with the floor-free white-box (rank.py) to sift ~90 -> top 18
- A2: Opus curator (curate.py) reads the 18 -> honest <=count + Gemini-voiced
  report cards; graceful fallback to the white-box + templated cards
- LLM via opencode.ai/zen gateway (llm.py): Opus chat + direct-OpenAI embeddings
- Run LLM work off the event loop (asyncio.to_thread) so the Redis response publishes
- C1: dedicated Postgres (app/db/) persists the per-user feed; get_scout_feed
  replays it so matches survive navigation/refresh
- match contract + report-card fields (schema.py); skills.py; tests/
2026-06-19 15:51:16 +05:30

26 lines
1.2 KiB
Python

"""A2 — curator: tolerant JSON parse, contract mapping, and the disabled→None safety net.
(Offline — the live Opus call is exercised in the cached e2e verification.)"""
from app.engine import curate as C
def test_parse_json_strips_fences_and_prose():
assert C._parse_json('```json\n{"kept":[]}\n```') == {"kept": []}
assert C._parse_json('here: {"kept":[{"id":"1"}]} thanks')["kept"][0]["id"] == "1"
def test_to_match_builds_full_contract():
m = C._to_match({
"id": "1", "score": 78, "fit": "fit", "archetype": "The Fit", "one_line": "strong but a gap",
"breakdown": [{"name": "Skill match", "score": 80, "level": "Strong", "note": "real SQL"}],
"coach_note": "lead with X", "growth": {"text": "close Y", "from": 78, "to": 85},
})
d = m.as_dict()
assert d["score"] == 78 and d["archetype"] == "The Fit" and d["fit"] == "fit"
assert d["breakdown"][0]["note"] == "real SQL" and d["coach_note"] == "lead with X"
assert d["growth"]["from"] == 78 and d["growth"]["to"] == 85 and d["proofReady"] is True
def test_curate_disabled_returns_none(monkeypatch):
monkeypatch.setattr(C, "curate_enabled", lambda: False)
assert C.curate({"title": "PM"}, None, [{"id": "1", "title": "PM"}]) is None