Spaces:
Sleeping
Sleeping
| title: Recruitment Copilot | |
| emoji: π― | |
| colorFrom: green | |
| colorTo: blue | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| license: mit | |
| short_description: Agentic recruitment copilot for HR teams. | |
| # Recruitment Copilot | |
| An end-to-end agentic recruitment workspace built on **Google ADK** + **FastMCP**, with a Next.js chat UI rendered through the free **Crayon UI** components from the Thesys SDK. | |
| It lets a recruiter: | |
| - π Find candidates by natural-language queries (`"give me top AI engineers"`, `"anyone with NLP background"`). | |
| - π Ingest scanned or text PDFs β Gemini OCR is used as a fallback when `pypdf` returns nothing. | |
| - π Pull all company HR policies in one click, rendered as a tabbed infographic with a donut chart. | |
| - π Draft a structured job posting from a chat brief β full markdown post + skill-weighting bar chart. | |
| - π Schedule interviews β auto-generates a Google Meet link, builds an `.ics`, and emails both attendees via SMTP. | |
| - βοΈ Compose follow-up emails: the agent returns three tonal drafts (formal / casual / polite); pick one, give a recipient, and the email goes out via SMTP. | |
| ## Architecture | |
| ``` | |
| ββββββββββββββββ ββββββββββββββββββββββ βββββββββββββββββββ | |
| β Netlify βββββΆβ HF Spaces (Docker)βββββΆβ Gemini API β | |
| β Next.js β β FastAPI + ADK + β β (LLM + OCR) β | |
| β frontend β β MCP server β βββββββββββββββββββ | |
| ββββββββββββββββ ββββββββββββββββββββββ βββββββββββββββββββ | |
| βββββββββββββββΆβ Qdrant Cloud β | |
| β β (vector index) β | |
| β βββββββββββββββββββ | |
| β βββββββββββββββββββ | |
| βββββββββββββββΆβ Supabase β | |
| β β Storage (PDFs) β | |
| β βββββββββββββββββββ | |
| β βββββββββββββββββββ | |
| βββββββββββββββΆβ Gmail SMTP β | |
| β (app password) β | |
| βββββββββββββββββββ | |
| ``` | |
| ### Backend | |
| - **FastAPI** serves the chat SSE stream and proxies tool calls. | |
| - **Google ADK** agent (`gemini-2.5-pro`) orchestrates 10 MCP tools. | |
| - **FastMCP** exposes those tools over `/mcp-server/sse`: | |
| | Tool | Purpose | | |
| |---|---| | |
| | `ingest_resume_pdf` | Parse a PDF (pypdf β Gemini OCR fallback) and persist to SQLite + Qdrant | | |
| | `semantic_candidate_search` | Vector search via Qdrant Cloud | | |
| | `candidate_metadata_query` | Keyword search over local SQLite, role-aware filtering | | |
| | `compute_job_match_score` | Score a single candidate against a JD | | |
| | `get_policy_info` | Return company HR policies (donut + tabs UI) | | |
| | `manage_application_status` | Track candidate stages | | |
| | `manage_interview_records` | Schedule interviews + auto-email Google Meet invite | | |
| | `generate_job_posting` | Draft a job posting from natural-language fields | | |
| | `bulk_ingest_reference_resumes` | Bootstrap demo data | | |
| | `email_compose` | Draft 3 tone variants β send via SMTP | | |
| ### Frontend | |
| - **Next.js 14** (App Router) with a streaming chat UI. | |
| - **Crayon UI** (`@crayonai/react-ui`) for cards, callouts, charts (bar/pie/donut/radar), tabs, tags, buttons. | |
| - A small **chart auto-picker** chooses bar / donut / radar based on the shape of the data the backend returns, so visualisations adapt to the response. | |
| ## Local development | |
| ### Prerequisites | |
| - Python 3.11+ | |
| - Node.js 18+ | |
| - A Gemini API key β https://aistudio.google.com/apikey | |
| ### One-shot bring-up (Windows / PowerShell) | |
| ```powershell | |
| copy .env.example .env # then fill in GEMINI_API_KEY at minimum | |
| .\start-all.ps1 | |
| ``` | |
| This installs dependencies, starts FastAPI on `http://127.0.0.1:7860` and Next.js on `http://127.0.0.1:3000`. Use `.\stop-all.ps1` to shut both down. | |
| ### Manual | |
| ```bash | |
| # backend | |
| cd backend | |
| pip install -r requirements.txt | |
| uvicorn main:app --host 0.0.0.0 --port 7860 | |
| # frontend (in another shell) | |
| cd frontend | |
| npm install | |
| npm run dev | |
| ``` | |
| ## Configuration | |
| All runtime config is read from `.env`. See [`.env.example`](.env.example) for the full list with inline links to where each credential is generated. | |
| | Group | Vars | Required for | | |
| |---|---|---| | |
| | Gemini | `GEMINI_API_KEY`, `GEMINI_MODEL`, `GEMINI_EMBEDDING_MODEL` | LLM, embeddings, scanned-PDF OCR | | |
| | Qdrant | `QDRANT_URL`, `QDRANT_API_KEY`, `QDRANT_COLLECTION` | Semantic candidate search | | |
| | Object storage | `S3_ENDPOINT`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, `S3_BUCKET`, `S3_REGION`, optional `S3_PUBLIC_BASE_URL` | Persistent resume PDF storage (Supabase Storage / Backblaze / S3 / MinIO) | | |
| | SMTP | `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASSWORD`, `SMTP_FROM`, `SMTP_USE_TLS` | Auto-email interview invites + composed emails | | |
| | Misc | `BACKEND_URL`, `CALENDLY_EVENT_URL`, `THESYS_API_KEY` | Frontend β backend wiring (Netlify), optional integrations | | |
| ## Deployment (free tier) | |
| ``` | |
| GitHub repo β Netlify (frontend) βββΆ HF Space Docker (backend) | |
| ββββΆ Qdrant Cloud | |
| ββββΆ Supabase Storage | |
| ββββΆ Gmail SMTP | |
| ``` | |
| ### 1. Backend on Hugging Face Spaces (Docker) | |
| 1. Create a new Space β choose **Docker β Blank**. | |
| 2. The repo's root [`Dockerfile`](Dockerfile) is picked up automatically. | |
| 3. In **Settings β Variables and secrets**, add every key from `.env.example` (Gemini / Qdrant / S3 / SMTP). Set `CORS_ORIGINS=https://<your-netlify-site>.netlify.app`. | |
| 4. `git push` this repo to the Space remote β HF builds and exposes the API at `https://<user>-recruitment-copilot.hf.space`. | |
| ### 2. Frontend on Netlify | |
| 1. Import this repo in Netlify. | |
| 2. Set **Base directory** to `frontend`. | |
| 3. Add env var `BACKEND_URL=https://<user>-recruitment-copilot.hf.space`. | |
| 4. Deploy. | |
| ### 3. External services (all free, no card) | |
| - **Qdrant Cloud** β https://cloud.qdrant.io β 1 GB free cluster. | |
| - **Supabase Storage** β https://supabase.com β Free project β create private `resumes` bucket β Settings β Storage β S3 access keys. | |
| - **Gemini API** β https://aistudio.google.com/apikey. | |
| - **Gmail SMTP** β https://myaccount.google.com/apppasswords (requires 2-step verification). | |
| ## API surface | |
| | Endpoint | Purpose | | |
| |---|---| | |
| | `GET /health` | Backend liveness | | |
| | `GET /mcp-health` | List of registered MCP tools | | |
| | `GET /api/tooling/status` | Reports which optional integrations are configured | | |
| | `POST /api/upload?session_id=β¦` | Multipart PDF resume upload | | |
| | `POST /api/chat` | SSE stream β chat with the agent | | |
| | `GET /api/candidates/{external_id}` | Full candidate profile (markdown + card + chart) | | |
| | `POST /api/bootstrap/sync-reference-resumes` | Copy sample PDFs into the project storage dir | | |
| | `POST /api/bootstrap/reference-resumes` | Bulk-ingest the synced PDFs | | |
| | `GET /mcp-server/sse` | MCP SSE stream endpoint | | |
| | `POST /mcp-server/messages/?session_id=β¦` | MCP SSE message channel | | |
| ### SSE event contract (`/api/chat`) | |
| | Event | Payload | | |
| |---|---| | |
| | `status` | `{ message }` | | |
| | `token` | `{ delta }` (incremental text) | | |
| | `genui` | `{ summary, markdown?, cards?, chart?, table?, tabs? }` | | |
| | `done` | `{ message }` (final text) | | |
| | `error` | `{ message }` | | |
| ## Project layout | |
| ``` | |
| . | |
| βββ backend/ | |
| β βββ agent/ # Google ADK runtime + agent definition | |
| β βββ core/ # Settings, DB session, models, schemas, utils | |
| β βββ mcp_server/ # FastMCP server + 10 tool modules | |
| β β βββ tools/ | |
| β βββ services/ # Candidate / search / ingestion / storage / notifications | |
| β βββ scripts/ # Reference-resume sync utilities | |
| β βββ main.py # FastAPI app + chat SSE stream | |
| βββ frontend/ | |
| β βββ src/ | |
| β βββ app/api/ # Next.js API proxy routes (chat, upload, candidates) | |
| β βββ components/ # Chat UI + Crayon-powered renderer | |
| βββ Dockerfile # HF Spaces backend image | |
| βββ start-all.ps1 / stop-all.ps1 | |
| βββ .env.example | |
| βββ LICENSE | |
| βββ README.md | |
| ``` | |
| ## License | |
| MIT β see [LICENSE](LICENSE). | |