CovGen – LLM-Powered Cover Letter Generator
A production-quality Python CLI tool that revolutionizes the cover letter writing process through intelligent automation. CovGen fetches job descriptions from URLs or local files, intelligently extracts company and contact information using sophisticated regex patterns and frequency analysis, combines this with your CV context, and generates personalized cover letter content via configurable LLM providers (OpenAI, Together.ai, OpenRouter). The generated content is then rendered through Jinja2-templated LaTeX and compiled into publication-quality PDFs. Features include smart paragraph splitting, LaTeX character escaping, job description snapshots for traceability, and extensive CLI customization options.
3 (OpenAI, Together, OpenRouter)
LLM Providers
PDF + LaTeX + Snapshot
Output Formats
Pydantic v2 + .env
Config System
Typer + Rich
CLI Framework
Tech Stack
13 technologies used
System Components
6 interconnected services
The architecture consists of these cooperating services, each with distinct responsibilities:
CLI Interface
frontendTyper-powered command-line interface with rich terminal output. Supports the `generate` command with extensive flags for customization including role, company, tone, temperature, sender/recipient details, and output options.
Pipeline Orchestrator
backendCore orchestration module (480+ lines) coordinating the entire generation flow: job fetching, company extraction, CV loading, LLM generation, post-processing, template rendering, and PDF compilation.
LLM Abstraction Layer
backendUnified multi-provider wrapper supporting OpenAI, Together.ai, and OpenRouter APIs. Handles provider-specific authentication, model selection, and response parsing with configurable temperature.
Job Fetcher
backendIntelligent job description loader supporting both URLs and local files. Uses BeautifulSoup for HTML parsing, extracts metadata, strips scripts/styles, and normalizes whitespace.
LaTeX Renderer
backendJinja2-based template engine producing professional letter layouts. Features conditional recipient logic, custom opening/closing phrases, microtype polish, and XeTeX font support. Compiles to PDF via xelatex/pdflatex.
Configuration System
infrastructurePydantic v2 BaseSettings with custom lenient environment sources. Supports .env files, environment variables, JSON lists, and pipe-separated values. Validates API keys match selected provider.
Data Flow
10 steps from input to output
How data flows through the system from client request to final response:
User invokes `covergen generate <url>` with optional flags
Fetches job description from URL or reads local file
Extracts company name, contact info using regex + frequency analysis
Loads user's CV text from configured path
Sends structured prompt with CV + job context to selected LLM
Returns generated cover letter body content
Sanitizes output: removes duplicates, splits paragraphs, escapes LaTeX chars
Renders Jinja2 template with generated content and metadata
Compiles .tex to .pdf using xelatex engine
Saves .pdf, .tex source, and .job.txt snapshot
Code Examples
4 ready-to-use snippets
Get started quickly with these practical code examples:
Basic Generation
Generate a cover letter from a job posting URL
# Generate cover letter from a job posting URL
covergen generate "https://careers.example.com/job/12345"
# Output:
# ✓ Fetched job description (2,847 chars)
# ✓ Extracted company: Example Corp
# ✓ Generated letter via OpenAI (gpt-4-turbo)
# ✓ Compiled PDF: output/software-engineer-example-corp-2024-01-15.pdfAdvanced CLI Options
Full customization with role, tone, and recipient overrides
covergen generate ./job-posting.html \
--role "Senior Backend Engineer" \
--company "TechCorp" \
--tone "enthusiastic yet professional" \
--instructions "Emphasize distributed systems experience" \
--sender-name "Sandeep Hirani" \
--sender-address "123 Main St" \
--sender-address "Ames, IA 50010" \
--recipient-name "Jane Smith" \
--recipient-company "TechCorp Engineering" \
--output-stem "techcorp-backend-senior"Environment Configuration
Sample .env file with multi-provider setup
# LLM Provider Configuration
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4-turbo
# Alternative providers (uncomment to use)
# LLM_PROVIDER=together
# TOGETHER_API_KEY=...
# TOGETHER_MODEL=meta-llama/Llama-3.1-70B-Instruct
# LLM_PROVIDER=openrouter
# OPENROUTER_API_KEY=...
# OPENROUTER_MODEL=anthropic/claude-3.5-sonnet
# Generation settings
LLM_TEMPERATURE=0.2
DEFAULT_TONE=professional and warm
# Sender defaults (pipe-separated for multi-line)
DEFAULT_SENDER_NAME=Sandeep Hirani
DEFAULT_SENDER_ADDRESS=123 Main St|Ames, IA 50010Prompt Engineering
System prompt ensuring grounded, professional output
You are an expert cover letter writer. Generate ONLY the body
paragraphs (2-3 paragraphs) for a cover letter.
CRITICAL CONSTRAINTS:
- Ground ALL claims in the provided CV - NO fabricated achievements
- Include quantified metrics from actual experience
- Match tone to job requirements (default: professional, warm)
- Avoid clichés like "I am writing to express my interest"
- Output valid LaTeX content (escape special characters)
CV CONTEXT:
{cv_text}
JOB DESCRIPTION:
{job_description}
Generate 2-3 focused paragraphs connecting CV experience to job needs.Infrastructure
Production-ready deployment stack
Battle-tested infrastructure components for reliable operations:
Multi-Provider LLM Layer
gatewayUnified abstraction over OpenAI, Together.ai, and OpenRouter APIs. Per-provider model configuration with shared fallback. Handles authentication, rate limiting, and response normalization.
Configuration Management
storagePydantic v2 BaseSettings with custom lenient parsers for environment variables. Supports .env files, JSON lists, pipe-separated values, and path expansion. Validates provider-API key alignment.
Document Processing Pipeline
deploymentEnd-to-end document pipeline: HTML parsing with BeautifulSoup, Jinja2 template rendering, LaTeX compilation via xelatex subprocess, and artifact management (PDF, source, snapshots).
CLI & Developer Experience
monitoringTyper-powered CLI with Rich terminal formatting. Comprehensive help text, flag validation, and informative error messages. Package installable via pip with entry point.
Key Features
- Multi-provider LLM architecture supporting OpenAI (GPT-4), Together.ai (Llama 3.1), and OpenRouter (Claude 3.5 Sonnet)
- Intelligent company name extraction using regex patterns, frequency analysis, and 45+ stopword filtering
- Smart contact/hiring manager detection from job posting metadata and content
- Advanced prompt engineering with grounding constraints preventing fabricated achievements
- Post-processing pipeline: duplicate removal, paragraph splitting, LaTeX character escaping
- Jinja2-templated LaTeX with conditional logic for named contacts vs company-only recipients
- Job description snapshots (.job.txt) archiving original postings for audit trails
- Lenient environment configuration tolerating both JSON and pipe-separated list formats
- Granular CLI overrides for role, company, tone, temperature, and sender/recipient details
Challenges Solved
- Extracting structured company and contact data from highly variable job posting formats across different websites
- Designing a unified abstraction layer across three LLM providers with different API interfaces and response formats
- Ensuring generated content is grounded in actual CV experience without hallucinated achievements or metrics
- Building robust LaTeX post-processing that handles edge cases like single-paragraph responses and special characters
Outcomes & Impact
- One-command generation: `covergen generate <url>` produces complete, professional cover letter in seconds
- Generated letters consistently achieve professional quality with quantified, CV-grounded achievements
- Modular architecture enabling easy addition of new LLM providers via simple adapter pattern
- Real-world validated: Successfully generated cover letters for companies like CVS Health, SingleStore, and GitWit