Skip to content

feat: Add Resume Parser to Personalize Ollama Cold Email Generation#86

Open
DivyanshiVats13 wants to merge 3 commits into
sharmavaibhav31:mainfrom
DivyanshiVats13:feat/resume-parser
Open

feat: Add Resume Parser to Personalize Ollama Cold Email Generation#86
DivyanshiVats13 wants to merge 3 commits into
sharmavaibhav31:mainfrom
DivyanshiVats13:feat/resume-parser

Conversation

@DivyanshiVats13
Copy link
Copy Markdown

Summary

This PR implements the resume parsing module mentioned in the project roadmap. The current email pipeline generates observation sentences about the company's product but has no knowledge of who is actually applying. Two different candidates applying to the same job get the exact same email.

This PR fixes that by adding an optional resume upload flow that extracts the candidate's skills, experience, and role — then passes that context to the Ollama prompt so the generated sentence connects the candidate's background to the company's product.


Problem (from the codebase)

Looking at the existing ollama_client.py:

generate_observation(product_description)

The function only takes product_description as input. There is no candidate information passed to the LLM at all. The system prompt tells Ollama to write about the company — but nothing about the person applying.

Result:

  • Every candidate gets the same generic observation sentence
  • Ollama has no way to personalize based on who is applying
  • The email feels like mass outreach rather than targeted outreach

Solution

Added a lightweight, regex-based resume parser that:

  1. Accepts PDF or plain text resume via POST /resume
  2. Extracts skills, years of experience, and recent job title
  3. Returns a structured candidate context
  4. This context is optionally passed to /generate
  5. Ollama receives both company product description AND candidate
    background — generating a personalized observation sentence

The existing /generate flow is completely unchanged when no resume
is provided — full backward compatibility maintained.


Files Changed

New Files

  • email-generator-service/resume_parser.py
    Lightweight regex-based parser. No heavy NLP dependencies.
    Extracts skills from a known list of 50+ tech keywords,
    experience using multiple regex patterns including casual phrasing,
    and job title using common engineering title patterns.

  • email-generator-service/test_resume_parser.py
    9 unit tests covering skill extraction, experience detection,
    role detection, edge cases (empty resume, minimal resume),
    and prompt snippet generation. All 9 passing.

  • email-generator-service/RESUME_PARSER_EXAMPLES.md
    Detailed before/after examples showing exactly how the
    Ollama-generated sentence changes when candidate context
    is provided.

Modified Files

  • email-generator-service/ollama_client.py
    Updated generate_observation() to accept optional
    candidate_context parameter. When provided, uses an enriched
    system prompt that connects candidate background to company
    product. When not provided, behavior is identical to before.

  • email-generator-service/generator.py
    Updated generate_email() to accept optional candidate_context
    parameter and pass it through to ollama_client.

  • email-generator-service/main.py
    Added POST /resume endpoint for resume upload and parsing.
    Added optional candidate_skills, candidate_role,
    candidate_experience fields to GenerateRequest model.

  • email-generator-service/requirements.txt
    Added pdfplumber>=0.11.0 and python-multipart>=0.0.9

  • README.md
    Updated project structure, marked roadmap item as complete,
    added pdfplumber to tech stack table.


Before / After

Before (without resume)

Ollama prompt: "In one sentence, write something specific about
this company's product: {product_description}"

Generated: "Your distributed caching layer's sub-millisecond
latency is genuinely impressive."

Only about the company. Nothing about the candidate.

After (with resume)

Ollama prompt: "Candidate background: Role: Senior Backend Engineer
| Experience: 5+ years | Skills: python, fastapi, docker.
In one sentence, write something specific about how this candidate's
background connects to this company's product: {product_description}"

Generated: "As a Senior Backend Engineer with 5 years building
FastAPI microservices, your distributed caching approach is exactly
the infrastructure challenge I have been solving in production."

Connects candidate directly to the company's product.


Test Results

pytest email-generator-service/test_resume_parser.py -v

test_skills_extracted_correctly PASSED
test_experience_extracted_correctly PASSED
test_role_extracted_correctly PASSED
test_minimal_resume_still_works PASSED
test_empty_resume_returns_empty_context PASSED
test_no_experience_returns_none PASSED
test_prompt_snippet_not_empty PASSED
test_prompt_snippet_empty_for_empty PASSED
test_candidate_context_is_empty_check PASSED

9 passed in 0.13s


Implementation Notes

Following the maintainer's guidance:

  • Parser is lightweight and deterministic — regex only, no spaCy
  • NLP layer is intentionally simple for first iteration
  • Resume uploads are optional — existing /generate unchanged
  • Prompt enrichment is concise — only role, experience, top 8 skills
  • Before/after examples included in RESUME_PARSER_EXAMPLES.md

Closes #69

- Add resume_parser.py to extract skills, experience and role from PDF/text resumes
- Update ollama_client.py to accept optional candidate context for personalized prompts
- Update generator.py to pass candidate context to Ollama
- Update main.py with /resume endpoint and optional resume fields in /generate
- Add test_resume_parser.py with 9 unit tests all passing
- Add RESUME_PARSER_EXAMPLES.md with before/after email examples
- Update requirements.txt with pdfplumber and python-multipart
- Update README.md with new files and mark roadmap item as complete
@vercel
Copy link
Copy Markdown

vercel Bot commented May 26, 2026

@DivyanshiVats13 is attempting to deploy a commit to the Vaibhav Sharma's projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feat: Add AI Powered Resume Parser to Personalize Cold Email Generation

1 participant