Skip to content

luisvid/JobGraph

Repository files navigation

JobGraph

JobGraph is an agentic job-discovery system for senior AI engineers. It ingests postings from high-signal sources, scores each against a structured candidate profile using a LangGraph pipeline, and delivers a daily email digest of top opportunities. Built on Python 3.12, LangGraph, and PostgreSQL; deployed on GCP Cloud Run.

Full design in docs/architecture.md; significant decisions are recorded as ADRs in docs/decisions/.

How it works

ingest  →  score (LangGraph)  →  daily digest
  1. Ingest — pull postings from curated sources (MVP: agentic-engineering-jobs.com), dedup by sha256(normalize(company) + normalize(title)), and persist the source's structured fields (locationType, geoRegion, seniority, salary, tech tags, …) in postings.source_metadata.
  2. Score — a LangGraph pipeline: deterministic hard filters → fact extraction (facts derived from the structured metadata, LLM only for domain tags + yellow flags) → remote-eligibility filter → dimension scoring → aggregate to a 0–100 score and a recommend / consider / skip / hard_reject decision. See ADR-0002 and ADR-0003.
  3. Digest — render the top postings to markdown, convert to HTML, and send a daily email (SMTP + STARTTLS).

The LLM provider is configurable via .env; the MVP runs on OpenAI (ADR-0001).

Quick start

Prerequisites: Python 3.12+, uv, Docker (for Postgres).

# 1. Install dependencies
uv sync --group dev

# 2. Configure — copy the template and fill in your keys
cp .env.example .env
#   set LLM_PROVIDER / LLM_MODEL_* (OpenAI by default), OPENAI_API_KEY,
#   and the SMTP_* / DIGEST_* values for email delivery

# 3. Start Postgres and run migrations
docker compose up -d postgres
uv run alembic upgrade head

# 4. Smoke-test LLM connectivity
uv run python scripts/smoke_llm.py        # prints PONG

Usage

# Ingest one source
uv run jobgraph ingest --source agentic-engineering-jobs

# Full pipeline: ingest → score → send digest (if due)
uv run jobgraph run

# Force-send the digest now (bypasses the 24h guard)
uv run jobgraph digest send

# Reset all data to run like the first time (prompts; --yes to skip)
uv run python scripts/reset_db.py

Development

make test       # pytest (DB tests use testcontainers — Docker must be running)
make lint       # ruff check
make format     # ruff format
make typecheck  # mypy

DB tests spin up a throwaway Postgres via testcontainers. On some Docker setups you may need to export DOCKER_HOST (your Docker socket) and TESTCONTAINERS_RYUK_DISABLED=true.

Layout

src/jobgraph/
  config/      pydantic-settings (.env)
  llm/         provider-agnostic factory over init_chat_model()
  db/          asyncpg + raw-SQL repositories
  ingestion/   source ingestors (RawPosting → postings)
  scoring/     LangGraph pipeline (graph, nodes, models)
  digest/      render (markdown→HTML) + SMTP delivery
  pipeline/    orchestration (ingest → score → digest)
migrations/    Alembic revisions
scripts/       smoke_llm.py, reset_db.py
docs/          architecture.md, decisions/ (ADRs)

About

Agentic job-discovery system for AI engineers. It ingests postings from high-signal sources, scores each against a structured candidate profile using a LangGraph pipeline, and delivers a daily email digest of top opportunities.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages