AI-powered agent that analyzes your email communications and researches a company’s website to generate an interview preparation report. Saves locally to output/prep_reports/ and can optionally create a Google Doc via Arcade.
- Analyze Gmail threads for a target company domain
- Scrape up to 5 key pages from the company website
- Generate a tailored prep report using OpenAI
- Save locally and/or to Google Docs via Arcade
interview_prep_agent/
├── agents/
│ ├── email_analyzer.py
│ ├── web_researcher.py
│ ├── prep_coach.py
│ └── discovery.py
├── models/
│ └── data_models.py
├── output/
│ └── prep_reports/ # .gitignored except .gitkeep
├── tools/
│ ├── gmail.py
│ ├── firecrawl.py
│ └── executor.py
├── utils/
│ ├── logging.py
│ └── validators.py
├── config.py
├── main.py
├── pyproject.toml
├── uv.lock
└── README.md
- Agents:
email_analyzer.py: Gmail via Arcade + LLM JSON extraction to classify interview‑related emails and contacts.web_researcher.py: Orchestrates discovery and scraping to get canonical company pages.discovery.py: Merges Firecrawl site mapping + Google search, then uses an LLM to pick the best URLs (about/team/careers).
- Tools:
gmail.py,firecrawl.py: Thin wrappers over Arcade toolkits with uniform execution + logging viaexecutor.py.
- Utils:
logging.py: Structured JSON logs withrun_id,step,tool,outcome,duration_ms(+extra).validators.py: URL/domain sanitation and normalization.
- Agent Loop:
- Explicit perceive → decide → act (tool) → reflect → next, with structured logs at each step.
- Python 3.13+
uvpackage manager (recommended) orpip
- Install dependencies
Using uv (recommended):
uv syncUsing pip:
python -m venv .venv
source .venv/bin/activate
pip install -r <(uv pip compile pyproject.toml)- Environment variables
Copy .env.example to .env and provide keys:
cp .env.example .envRequired variables loaded in config.py:
ARCADE_API_KEY– Arcade API key (for Gmail/Google Docs tool access)OPENAI_API_KEY– OpenAI key for AI report generation
Run the agent from the repo root:
uv run python main.py --company stripe.com --user-id [email protected]Common flags:
--debug– verbose logs--email-only– skip web scraping--fast-web– faster web discovery/scrape (fewer calls, no crawl fallback)--save-to-docs– create a Google Doc via Arcade--docs-only– only save to Google Docs (no local file)--output-dir PATH– change local output directory (default:output/prep_reports)
Examples:
uv run python main.py --company openai.com --user-id [email protected] --debug
uv run python main.py --company stripe.com --user-id [email protected] --save-to-docs- Quick run script:
bash scripts/demo.sh <company_domain> <user_email> [--debug] [--save-to-docs] - Examples:
bash scripts/demo.sh arcade.dev [email protected] --debugbash scripts/demo.sh stripe.com [email protected] --save-to-docs
- Optional: make it executable and run directly:
chmod +x scripts/demo.sh && ./scripts/demo.sh arcade.dev [email protected]
- Discovery combines Firecrawl site mapping and GoogleSearch to find canonical pages (about, team/leadership, careers).
- An LLM ranks and selects the best candidates, then we scrape via Firecrawl.ScrapeUrl (markdown).
- Debug mode and
--fast-webkeep calls minimal (1 map + 1 search; scrape up to 2 pages; no crawl fallback). Full mode maps + searches more broadly, and may use a tiny crawl fallback if needed. - 404s and minor parsing issues are skipped gracefully; URLs are sanitized and normalized to HTTPS.
- Local reports are written to
output/prep_reports/<company>_prep_<timestamp>.md. - When
--save-to-docsis set, a Google Doc is created via Arcade and the URL is printed.
- Archived, non-critical or experimental files are stored in
archive_unused/(git-ignored) so they don’t pollute the repo. output/contents are ignored by git, except for.gitkeepplaceholders.- Keep
uv.lockcommitted for deterministic installs.
- Import errors: ensure you run from the repository root and that
uv sync(orpip install) completed successfully. - Missing keys:
config.pyrequiresARCADE_API_KEYandOPENAI_API_KEY. - Google Docs: the first run will prompt Arcade authorization in your terminal; approve once and retry.