upstackpilot0710 /
inbox-ai-agent
AI-powered email assistant built with Streamlit that generates smart replies, classifies messages, and automates inbox workflows using LLMs.
Loading repository data…
vigneshwar-lokoji / repository
AI-powered email assistant — monitors Gmail in real-time, classifies emails (job/personal/bank/spam), drafts context-aware replies, tracks job applications in Google Sheets, and manages everything through Telegram. Built with LangGraph + Gemini 2.5 Flash + Gmail Pub/Sub
An AI-powered email assistant that monitors your Gmail inbox in real-time, classifies emails, drafts context-aware replies, and manages your job search pipeline — all controlled through Telegram.
Built with LangGraph (multi-agent orchestration), Gemini 2.5 Flash (LLM), Google Sheets (tracker), and Telegram Bot API.
Gmail Inbox
│
▼ (Pub/Sub push)
┌─────────────┐
│ main.py │ ← Entry point: Pub/Sub listener + Telegram poller + background loops
└──────┬──────┘
│
▼
┌──────────────────┐ ┌─────────────────┐
│ orchestrator.py │────▶│ ai_nodes.py │ Gemini 2.5 Flash (Vertex AI / API)
│ (Phase A + B) │ │ 6 LLM agents │
└──────┬───────────┘ └─────────────────┘
│
├──▶ Google Sheets (job tracker + profile)
├──▶ Gmail API (send replies, save drafts, apply labels)
├──▶ SQLite (pending decisions, reminders, sent replies)
└──▶ Telegram Bot (notifications + approval buttons)
Phase A (non-blocking): New email arrives → classify → extract data → update sheet → send Telegram notification. All emails processed in batch without waiting for user input.
Phase B (async): User taps a button on Telegram → agent drafts reply / sends / saves draft / ignores. Each email is handled independently.
| Agent | Purpose |
|---|---|
| Super Triage | Classify email category (job/personal/bank/advertisement/spam) |
| Job Triage | Determine if job-related email needs action |
| Thread Resolver | Match to existing tracker row or create new entry |
| Data Extractor | Pull structured fields (company, stage, action type, priority) |
| Drafter | Write context-aware reply using profile + calendar data |
| Critic | Review draft against tone/content rules, request rewrites |
| General Triage | For non-job emails: needs_reply / needs_attention / spam |
| General Drafter | Draft replies for personal/business/study emails |
| Command | What it does |
|---|---|
reminders | Show pending action items with priority |
clear reminders | Dismiss all reminders at once |
followup | Check for stale threads (sent but no reply) |
dashboard / stats | Job search pipeline and rejection analysis |
response time / speed | Your email response speed stats |
brief / morning | Daily summary (reminders + weekly analytics) |
profile | View your profile data from Google Sheet |
help | List all commands |
When a new email arrives that needs your attention:
[Show Email] ← View the full email
[Draft a Reply for me] ← AI writes a reply
[Write My Own] ← Type your own reply (with optional refine loop)
[Ignore] ← Dismiss
After AI drafts a reply:
[Approve & Send] [Edit] [Write My Own] [Hold as Draft] [Reject]
git clone https://github.com/yourusername/inbox-agent.git
cd inbox-agent
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Vertex AI User, Pub/Sub Subscriber, Pub/Sub Publisherservice_account.json in the project rootcredentials.jsonpython auth.py
This opens a browser for Gmail authorization and creates token.json.
Important: Publish your OAuth app to Production (APIs & Services → OAuth consent screen → Publish) to prevent token expiration every 7 days.
gmail-pushgmail-push-sub (Pull type)gmail-api-push@system.gserviceaccount.com the Publisher role on the topicpython setup_profile.py
/newbot → follow promptscurl https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates
Look for "chat":{"id": YOUR_CHAT_ID} in the response.
cp .env.example .env
Edit .env with your values:
TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
TELEGRAM_CHAT_ID=123456789
GOOGLE_CLOUD_PROJECT_ID=my-project-123
USER_TIMEZONE=America/New_York
USER_FIRST_NAME=John
Option A: Vertex AI (recommended)
Vertex AI User roleUSE_VERTEX_AI = True in ai_nodes.pyOption B: Gemini API Key (simpler, no GCP needed for LLM)
GEMINI_API_KEY=your-key to .envUSE_VERTEX_AI = False in ai_nodes.pypython main.py
This starts:
inbox-agent/
├── main.py # Entry point — Telegram + Pub/Sub + background loops
├── orchestrator.py # Phase A (classify) + Phase B (execute) logic
├── ai_nodes.py # LLM agent functions (triage, extract, draft, critic)
├── prompts.py # All LLM system prompts
├── graph.py # LangGraph workflow definition
├── state.py # Agent state schema
├── db.py # SQLite layer (pending decisions, reminders, follow-ups)
├── gmail_service.py # Gmail API helpers (fetch, send, label, draft)
├── gmail_watch.py # Pub/Sub watch registration
├── calendar_service.py # Google Calendar integration
├── action_nodes.py # Google Sheets operations + dashboard stats
├── bot_listener.py # Telegram button/command handler
├── auth.py # OAuth flow for Gmail
├── setup_profile.py # One-time Profile tab creator
├── server.py # FastAPI server (alternative to polling)
├── test_bot.py # Quick Telegram connectivity test
├── visualize.py # LangGraph ASCII visualization
├── requirements.txt # Python dependencies
├── .env.example # Environment variable template
└── .gitignore
Edit SUPER_TRIAGE_PROMPT in prompts.py to add new categories. Then add routing logic in orchestrator.py (run_phase_a) and a Gmail label in _gmail_label_for().
In ai_nodes.py, change the model parameter in ChatGoogleGenerativeAI. The agent uses two instances: llm_json (structured output) and llm_text (free text).
Edit DRAFTER_PROMPT in prompts.py. The drafter receives the user's profile data and calendar availability as context.
The extractor agent populates columns based on EXTRACTOR_PROMPT in prompts.py. Add new fields there, and update sheet_operator_node in action_nodes.py to write them.
In main.py, modify brief_hour in _morning_brief_loop(). The timezone is set via USER_TIMEZONE env var.
For 24/7 operation, deploy to a cloud VM (e2-micro is sufficient):
# Start with nohup
nohup python3 -u main.py >> logs/agent.log 2>&1 &
# Or use systemd for auto-restart
New job email arrives
│
▼
Super Triage → "job" category
│
▼
Job Triage → is it about YOUR application? (not a digest)
│
▼
Thread Resolver → match to existing sheet row or create new
│
▼
Data Extractor → company, stage, action type, priority
│
▼
Sheet Operator → update Google Sheets tracker
│
├── Action Type: "Reply" → Notify on Telegram
├── Action Type: "Task" → Add to reminders
└── Action Type: "None" / Rejected → Log silently
Selected from shared topics, language and repository description—not editorial ratings.
upstackpilot0710 /
AI-powered email assistant built with Streamlit that generates smart replies, classifies messages, and automates inbox workflows using LLMs.