Skip to content

Repository files navigation

Resume Intake Agent

Local LLM resume pipeline. Resumes are read from a Google Drive folder or a local path / Drive file id via CLI.

Module map

Step Action Module
1 Download resume, extract CandidateProfile (pypdf / vision) graph.pyllm.py
2 Duplicate check by email graph.pymemory.py
3 Summarize + fit assessment (agentic branch) graph.pyllm.pytelegram_tools.py
4 Log to Google Sheets (approved / rejected + reason) graph.pygoogle_tools.py
5 Find calendar slot (14:00 or 16:00 weekdays, 1 hour each) graph.pygoogle_tools.py
6 Telegram approval (LangGraph interrupt) graph.pytelegram_tools.pymemory.py
7 Create Google Calendar event graph.pygoogle_tools.py
8 Draft Gmail invite (local Qwen, never auto-send) graph.pyllm.pygoogle_tools.py
9 Update sheet (interview scheduled) graph.pygoogle_tools.py + memory.py
10 SQLite memory + Telegram chatbot Q&A memory.py + telegram_tools.py

All LLM calls go through llm.call_llm only.

Environment (.env)

Key Purpose
DRIVE_FOLDER_ID Drive folder watched for new resumes
GOOGLE_SA_KEY Path to service account JSON
SHEET_ID Google Sheet id for candidate ledger
CALENDAR_ID Calendar id for free/busy and events
TELEGRAM_BOT_TOKEN BotFather token
TELEGRAM_CHAT_ID Target chat/group id
MODEL_NAME Ollama text model (Qwen)
VISION_MODEL Ollama vision model (llama3.2-vision)
INTERVIEWER_NAME Shown in calendar/email
INTERVIEWER_EMAIL Organizer email
TIMEZONE Required for correct slot times — IANA name matching your Google Calendar (e.g. Asia/Tehran, Europe/Amsterdam)
POLL_INTERVAL Drive poll seconds (default 60)
MEMORY_DB SQLite path (default ./data/memory.db)
OLLAMA_KEEP_ALIVE Keep model loaded between calls (default 30m)

Share the Drive folder, Sheet, and Calendar with the service account email (Calendar needs Make changes to events).

Calendar events are created without attendee invites by default — service accounts cannot send invites on personal Gmail without Google Workspace domain-wide delegation. Candidate contact info is stored in the event description; the Gmail draft step covers the actual invite.

Optional: set CALENDAR_USE_ATTENDEES=true only if you have Workspace domain-wide delegation configured.

Setup

pip install -r requirements.txt
ollama pull qwen2.5:7b
ollama pull llama3.2-vision

Place your service account JSON at ./secrets/service-account.json (or set GOOGLE_SA_KEY).

Run

# Watch the Drive folder (default)
python main.py

# Verbose logging — each pipeline step is logged as STEP 1..9
python main.py -v

# Process one Drive file id or local path
python main.py 1abcDriveFileIdHere -v
python main.py C:\path\to\resume.pdf -v

# Console-only (no Telegram bot thread)
python main.py --no-bot C:\path\to\resume.pdf -v

Each resume logs steps like STEP 1: read_resume, STEP 2: dup_check, … through STEP 9.

Text-native PDFs use Qwen for structured extraction; scanned/image PDFs and image files use llama3.2-vision first, then Qwen for JSON.

Telegram

  • Fit summaries are posted automatically.
  • After slot-finding, the bot asks Schedule {name} for {slot}? with Yes/No buttons (or reply yes / no).
  • Free-text questions (who did we add today?, reschedule Jane Doe) use memory + Sheet data via call_llm.

Sheet columns

email | name | current_role | years_experience | skills | status | reason | slot | event_id | processed_at

Status values: rejected (with reason), approved, declined, interview scheduled.

About

Resume intake agent: extracts candidate profiles from PDFs via Ollama, screens fit, schedules interviews on Google Calendar, and emails invites

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages