A privacy-first local AI agent for job discovery, ranking, truthful application preparation, and human-reviewed browser assistance.
LocalJobAgent ingests public Greenhouse, Lever, and Ashby job boards, normalizes postings into typed records, deduplicates them in SQLite, applies deterministic eligibility rules, and ranks eligible roles with a local Ollama model. It can then build a provenance-backed application package, produce an ATS-readable one-page resume, assist with ordinary form fields in a visible Chromium session, and track the application lifecycle.
The browser layer has no submit capability. It stops before final submission and leaves the user in control.
- Public ATS ingestion for Greenhouse, Lever, and Ashby with conservative HTTP behavior.
- Typed normalization and source/URL deduplication backed by SQLAlchemy and SQLite.
- Official DOL OFLC LCA evidence cached locally with current-posting sponsorship overrides.
- Deterministic sponsorship and role-eligibility gates before schema-validated local LLM ranking.
- A persistent, user-editable company registry for batch Greenhouse, Lever, and Ashby discovery.
- One-command conservative autopilot plus a compact review queue and duplicate protection.
- Local application packages containing job snapshots, fit results, resume files, answers, provenance, and a human-review gate.
- Evidence-backed resume tailoring: generated claims resolve to structured candidate source IDs.
- ATS-safe PDF text and real URI annotations for verified email, profile, and project links.
- Visible Playwright-assisted form filling with an enforced hard stop before submission.
- Application state and event tracking in the local database.
- Fictional fixtures plus unit, integration, local Ollama, and Chromium safety tests.
flowchart LR
A[Public ATS job sources] --> B[Normalize and deduplicate]
B --> C[Sponsorship hard gate]
C --> D[Deterministic role eligibility]
D --> E[Local Ollama ranking]
E --> F[Truthful application preparation]
F --> G[Provenance and fact verification]
G --> H[Human-in-the-loop browser assistance]
H --> I[Review queue and tracking]
The stages exchange typed data rather than conversational transcripts. Job postings, scraped HTML, and model output are treated as untrusted inputs. Deterministic policies control factual constraints and submission safety; the local LLM is reserved for semantic scoring.
- Candidate YAML, SQLite databases, generated resumes, application packages, browser state, and
.envfiles stay local and are ignored by Git. - Runtime model inference is local through Ollama; there is no cloud-LLM fallback or telemetry.
- Candidate claims must reference structured provenance. Unsupported claims fail verification.
- Browser automation fills only ordinary recognized fields in a visible session. It does not submit, solve CAPTCHAs, evade access controls, or handle credentials.
- Committed profile templates are blank, and all test candidate data is explicitly fictional.
See Security, Architecture, and Data model for the detailed boundaries.
Python 3.12, Pydantic, SQLAlchemy, SQLite, Typer, HTTPX, Beautiful Soup, Ollama, Playwright, ReportLab, pypdf, PyYAML, pytest, Ruff, and mypy.
Prerequisites:
- Python 3.12+
uv- Ollama for semantic ranking
- Chromium installed through Playwright for browser assistance
git clone https://github.com/rohit16111999/LocalJobAgent.git
cd LocalJobAgent
uv sync --extra dev --extra browser
uv run playwright install chromium
ollama pull qwen3:14b
uv run jobagent doctorCreate private profile files from the committed blank templates, then validate them:
uv run jobagent setup
uv run jobagent profile validatesetup never overwrites an existing file. Production profile files under profile/ remain ignored.
Configuration is optional; copy .env.example to .env only when overriding defaults.
Build the local sponsorship index from the latest four official DOL fiscal-year disclosures, then configure public ATS boards. Raw workbooks, the derived index, and the registry stay gitignored:
uv run jobagent sponsorship update
uv run jobagent sponsorship check "Example Company Inc."
uv run jobagent companies add "Example Company Inc." greenhouse <board-token>
uv run jobagent companies list
uv run jobagent discoverHistorical LCA activity is evidence of employer labor-condition activity, not proof that an individual H-1B petition was approved or that future sponsorship is available. Current posting language always overrides history; weak or unknown evidence never reaches automatic preparation.
uv run jobagent autopilot
uv run jobagent autopilot --dry-run --limit 10
uv run jobagent autopilot --pilot-one
uv run jobagent reviewAutopilot validates the profile, discovers enabled boards, deduplicates jobs, applies sponsorship and
role gates, ranks only passing jobs through local Ollama, prepares high-confidence packages, and routes
them to review. --dry-run performs no package or browser writes. Auto-submit remains unavailable:
prepared applications require review and manual submission.
--pilot-one ranks at most the configured batch, tries up to three candidates, prepares the first
sponsor-compatible job scoring at least 60, opens the existing safe browser assistant, and always leaves
the application unsubmitted in READY_FOR_REVIEW. Scores below 70 are labeled explicitly as pilot-only.
Ingest one or more public ATS boards:
uv run jobagent search greenhouse <board-token>
uv run jobagent search lever <company-token>
uv run jobagent search ashby <board-token>Inspect and rank a stored job, then prepare a truthful local package:
uv run jobagent inspect 1
uv run jobagent rank 1
uv run jobagent prepare 1For deterministic offline ranking, use uv run jobagent rank 1 --no-llm.
Open a visible browser for assisted filling and record lifecycle changes:
uv run jobagent apply 1 --package applications/<prepared-package>
uv run jobagent track 1 READY
uv run jobagent trackThe apply command never submits the form. Review and submit manually.
Default tests use fictional fixtures and do not require network access, Ollama, or browser binaries:
uv run pytest
uv run ruff check .
uv run mypy srcLive Ollama and Chromium smoke tests are opt-in:
$env:JOBAGENT_RUN_LIVE_TESTS = "1"
uv run pytest tests/integration/test_live_runtime.py -qCore v1 is implemented and locally verified with qwen3:14b, official FY2026–FY2023 DOL disclosure
data, current public Greenhouse/Lever/Ashby endpoints, and Playwright Chromium. Public ATS endpoints can
change or deny automated access; failures are surfaced without bypass attempts. Resume and application
output still requires human review. LocalJobAgent does not submit applications, operate around CAPTCHAs,
provide a hosted dashboard, or synchronize candidate data to cloud services.
See STATUS.md for the current verification record.
The workflow design was informed by MadsLorentzen/ai-job-search, including its staged review flow and truthful tailoring principles. LocalJobAgent is an independent implementation; no source code from that project is included.