Team: Matt Gresham (PyMite6941)
&
Mackenzie (SeaMeetsSky38Times)
Demo
About the Project
Inspiration: Mackenzie
suggested the idea — and once we started, we both got completely swept
up in it. We wanted to build something that integrates with the tools
people actually use every day, not just a toy demo. Google Calendar and
Gmail are where real scheduling lives, so that became the target.
What it does: Connects
to your Google Calendar and Gmail through OAuth 2.0 and lets you manage
your entire schedule in plain English. Ask it to add an event, query
your week, turn an email into a todo, or build an optimized time-block
plan from a task list. A 4-agent CrewAI pipeline handles every request:
Intent Analyzer → Schedule Data Retriever → Schedule Processor →
Response Verifier. The Streamlit Web UI ships with a full calendar grid,
persistent AI chat sidebar, todo list, settings page (choose from 5 AI
providers: OpenAI, Groq, Gemini, Mistral, Ollama), and a built-in
portfolio metrics page with live Google account status.
How it was built:
Python core with CrewAI 1.1 managing the agent pipeline.
streamlit-calendar renders the month/week/day event grid.
Google Calendar v3 and Gmail v1 for data, authenticated via OAuth 2.0
with automatic token caching and refresh in
backend/auth/add_google_oauth.py. Config in TOML; events
and todos in JSON. A run.py launcher with
questionary lets you pick CLI or Streamlit on startup.
Challenges: Google
OAuth across two developers and two runtime modes (CLI vs. Streamlit)
was the biggest friction point — token refresh had to be airtight,
because a stale credential mid-pipeline breaks the entire crew. Keeping
the CLI and Streamlit interface in feature parity as things changed was
also non-trivial.
What we learned:
The full Google API OAuth flow end-to-end — consent screen, scopes,
credential caching with pickle, and automatic refresh. Also learned how
to structure CrewAI projects so each agent stays tightly scoped; overly
broad agent goals produce unpredictable results mid-pipeline.
What's next: Recurring
event support, conflict detection that reasons about travel time, and a
push notification layer so the assistant can proactively flag overloaded
days.
Agent Pipeline
Calendar AI Assistant — CrewAI Pipeline
══════════════════════════════════════════
User request (natural language)
e.g. "Schedule a meeting with Mackenzie Thursday at 3 PM"
│
▼
┌─────────────────────────────────────────┐
│ 1. Intent Analyzer │
│ Identifies: calendar event / todo / │
│ reminder / schedule question │
│ Extracts: dates, times, titles, │
│ people, context │
└──────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 2. Schedule Data Retriever │
│ Pulls relevant events from │
│ Google Calendar API │
│ Checks todos.json for conflicts │
└──────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 3. Schedule Processor │
│ Creates / modifies event │
│ Generates todo list item │
│ Answers schedule question │
│ Builds optimized time-block plan │
└──────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 4. Response Verifier │
│ QA: accuracy, completeness, │
│ consistency — catches errors │
│ before response reaches user │
└──────────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Streamlit UI · or · CLI │
│ Verified response returned to user │
└─────────────────────────────────────────┘
Storage: calendar_events.json · todos.json · configs.toml · secrets.toml
Auth: Google OAuth 2.0 — Calendar v3 + Gmail v1
Providers: OpenAI · Groq · Gemini · Mistral · Ollama (switchable in Settings)
Token caching and refresh handled by add_google_oauth.py — works identically in CLI and Streamlit modes.
Dev Notes
Tech Stack
Python + CrewAI (agent pipeline), Google Calendar API + Gmail API (data), Streamlit (Web UI), CLI (rich terminal). Config/secrets in TOML; event/todo state in JSON.
Hardest Part
Google OAuth across two developers and two runtime modes (CLI vs. Web UI). The token refresh logic had to be airtight — a stale token mid-pipeline breaks the whole crew. Also keeping CLI and Streamlit page feature parity as things changed.
What I'd Do Differently
Abstract the Google API calls into a single data layer early on instead of letting both the CLI and Web UI talk to the API directly. Would have made adding features much cleaner and avoided several sync bugs.