The AI Customer Support Agent is a sophisticated email automation system built on a modular, pluggable architecture. The system monitors Gmail inboxes, classifies incoming emails, and generates context-aware responses using Retrieval-Augmented Generation (RAG) with support for multiple LLM and Vector Database providers.
The system implements the Factory Pattern for both LLM and Vector Database providers, allowing seamless switching between different providers without code changes.
Each service has a clearly defined responsibility following SOLID principles, making the system maintainable and testable.
- Services Layer: Business logic and provider management
- API Layer: REST endpoints for dashboard
- Web Layer: Frontend rendering
- CLI Layer: Command-line interface for agent and ingestion
graph TB
subgraph "Entry Points"
CLI[run.py - CLI]
Flask[create_app - Flask App]
end
subgraph "Web Layer"
WebBP[Web Blueprint<br/>Landing, Dashboard]
APIBP[API Blueprint<br/>REST Endpoints]
AuthBP[Auth Blueprint<br/>OAuth Flow]
end
subgraph "Frontend JavaScript"
AuthJS[auth.js<br/>Session \u0026 Redirects]
DashboardJS[dashboard.js<br/>Data Fetching]
ChartsJS[charts.js<br/>ApexCharts]
end
subgraph "Service Layer"
Agent[AgentService]
Gmail[GmailService]
Ingestion[IngestionService]
Vector Store[VectorStoreService]
Database[DatabaseService]
end
subgraph "Provider Factories"
LLMFactory[LLMFactory]
VectorDBFactory[VectorDBFactory]
end
subgraph "LLM Providers"
Gemini[GeminiProvider]
Claude[ClaudeProvider]
end
subgraph "Vector DB Providers"
Pinecone[PineconeProvider]
Future[Future Providers...]
end
subgraph "External Services"
GmailAPI[Gmail API]
end
CLI --> Agent
Flask --> WebBP
Flask --> APIBP
Flask --> AuthBP
WebBP --> AuthJS
APIBP --> DashboardJS
APIBP --> ChartsJS
AuthBP --> Gmail
APIBP --> Database
APIBP --> VectorStore
APIBP --> Ingestion
Agent --> Gmail
Agent --> VectorStore
Agent --> Database
Agent --> LLMFactory
Ingestion --> VectorStore
VectorStore --> VectorDBFactory
LLMFactory --> Gemini
LLMFactory --> Claude
VectorDBFactory --> Pinecone
VectorDBFactory --> Future
Gmail --> GmailAPI
Purpose: Orchestrates the email processing workflow
Responsibilities:
- Fetch unread emails from Gmail
- Classify emails using LLM (Customer Support Inquiry vs Other)
- Retrieve relevant context from Vector DB (RAG)
- Generate responses using LLM with fallback support
- Send threaded email replies
- Log all activities to database
Key Dependencies: GmailService, VectorStoreService, LLMFactory, DatabaseService
File: app/services/agent_service.py
Purpose: Unified interface to Gmail operations
Responsibilities:
- Delegates to specialized sub-services:
GmailAuthService- OAuth authenticationGmailEmailReader- Fetch and parse emailsGmailEmailComposer- Compose reply messagesGmailEmailSender- Send emails via APIGmailEmailModifier- Mark as read, modify labelsGmailUserService- Get user profile info
Pattern: Facade Pattern (maintains backward compatibility while using SRP-compliant internal services)
File: app/services/gmail_service.py
Purpose: Unified interface to vector database operations
Responsibilities:
- Initialize provider via
VectorDBFactory - Add documents with embeddings
- Perform similarity search
- Get index statistics
- List and paginate documents
Multi-Provider Support: YES (via VectorDBFactory)
File: app/services/vector_store_service.py
Purpose: Process PDF documents and ingest into vector database
Responsibilities:
- Handle PDF uploads via web interface (
/api/upload) - Extract text from PDFs using PyPDFLoader
- Split documents into chunks (RecursiveCharacterTextSplitter)
- Filter empty chunks and validate content
- Generate embeddings and store in vector DB
Integration: Web Upload → PDF Processing → Vector DB
File: app/services/ingestion_service.py
Purpose: SQLite database for activity logging
Responsibilities:
- Store email processing logs (timestamp, sender, subject, status, category)
- Provide statistics (total, responded, ignored)
- Support multi-user filtering (agent_email)
Storage: email_logs.db (SQLite)
File: app/services/database_service.py
Purpose: Manage multiple LLM providers with automatic fallback
Supported Providers:
- Primary: Google Gemini (
gemini-pro) - Fallback: Anthropic Claude (
claude-3-sonnet)
Features:
- Automatic quota error detection (HTTP 429)
- Exponential backoff retry logic
- Seamless provider switching on failure
- Provider status monitoring
Registry Pattern: New providers can be registered dynamically
File: app/services/llm_providers/factory.py
Purpose: Manage multiple Vector DB providers
Supported Providers:
- Primary: Pinecone (Serverless)
- Future: Extensible for Weaviate, ChromaDB, etc.
Features:
- Provider abstraction via base interface
- Fallback support (configurable)
- Index management (get or create)
- Document operations (add, search, list, delete)
Registry Pattern: New providers register via register_provider()
File: app/services/vector_db_providers/factory.py
See: Multi-Vector DB Architecture
app/
├── __init__.py # Flask app factory
├── config/
│ └── __init__.py # Configuration management
├── api/
│ ├── __init__.py # API Blueprint
│ └── routes.py # REST endpoints (/api/metrics/*, /api/upload)
├── web/
│ ├── __init__.py # Web Blueprint
│ └── routes.py # Web pages (/, /dashboard, /knowledge-base)
├── auth/
│ ├── __init__.py # Auth Blueprint
│ └── routes.py # OAuth routes (/auth/gmail/*, /auth/demo/*)
├── services/
│ ├── agent_service.py # Email processing orchestration
│ ├── gmail_service.py # Gmail facade
│ ├── gmail/ # Gmail sub-services (SRP)
│ │ ├── auth_service.py
│ │ ├── email_reader.py
│ │ ├── email_composer.py
│ │ ├── email_sender.py
│ │ ├── email_modifier.py
│ │ └── user_service.py
│ ├── llm_providers/ # LLM abstraction
│ │ ├── base.py # LLMProvider interface
│ │ ├── factory.py # LLMFactory with fallback
│ │ ├── gemini_provider.py
│ │ └── claude_provider.py
│ ├── vector_db_providers/ # Vector DB abstraction
│ │ ├── base.py # VectorDBProvider interface
│ │ ├── factory.py # VectorDBFactory
│ │ ├── pinecone_provider.py
│ │ ├── pinecone_index_manager.py
│ │ └── pinecone_document_manager.py
│ ├── vector_store_service.py # Vector DB facade
│ ├── ingestion_service.py # PDF ingestion
│ └── database_service.py # SQLite logging
├── utils/
│ ├── logger.py # Logging setup
│ └── prompt_loader.py # Load prompts from files
├── templates/ # Jinja2 templates
│ ├── landing.html # Landing page (unauthenticated)
│ ├── dashboard.html # Dashboard (authenticated)
│ ├── knowledge_base.html # Knowledge base viewer
│ ├── recent_activity.html # Activity logs
│ └── how-it-works.html # How it works page
└── static/ # Static assets
├── css/
│ ├── design-system.css # Design tokens
│ ├── base/base.css # Base styles
│ ├── components.css # Reusable components
│ └── pages/ # Page-specific styles
├── js/
│ ├── auth.js # Auth flow & redirects
│ ├── dashboard.js # Dashboard data fetching
│ ├── charts.js # ApexCharts integration
│ └── date-range-manager.js # Date range selection
└── images/ # Static images
sequenceDiagram
participant Agent as AgentService
participant Gmail as GmailService
participant LLM as LLMFactory
participant Vector as VectorStoreService
participant DB as DatabaseService
Agent->>Gmail: get_unread_emails(after_timestamp)
Gmail-->>Agent: List of emails
loop For each email
Agent->>LLM: classify_email(email.body)
LLM-->>Agent: Classification result
alt Is Customer Support Inquiry
Agent->>Vector: similarity_search(email.body)
Vector-->>Agent: Relevant context
Agent->>LLM: generate_response(email, context)
alt Primary LLM succeeds
LLM-->>Agent: Response
else Primary fails (quota)
LLM->>LLM: Switch to fallback (Claude)
LLM-->>Agent: Response from fallback
end
Agent->>Gmail: send_reply(to, subject, body, thread_id)
Gmail-->>Agent: Success
Agent->>Gmail: mark_as_read(msg_id)
Agent->>DB: log_email(sender, subject, "RESPONDED")
else Not Support Inquiry
Agent->>DB: log_email(sender, subject, "IGNORED")
end
end
sequenceDiagram
participant User
participant Browser
participant API as API Routes
participant Ingestion as IngestionService
participant Vector as VectorStoreService
participant VDB as VectorDBFactory
participant Pinecone
User->>Browser: Upload PDF via Dashboard
Browser->>API: POST /api/upload (multipart/form-data)
API->>API: Save to temp file
API->>Ingestion: process_pdf(temp_path, filename)
Ingestion->>Ingestion: Load PDF (PyPDFLoader)
Ingestion->>Ingestion: Split into chunks
Ingestion->>Ingestion: Filter empty chunks
Ingestion->>Vector: add_documents(chunks)
Vector->>VDB: add_documents(chunks, index_name)
VDB->>VDB: Generate embeddings (via provider)
VDB->>Pinecone: Upsert vectors
Pinecone-->>VDB: Success
VDB-->>Vector: Success response
Vector-->>Ingestion: Num chunks added
Ingestion-->>API: num_chunks
API->>API: Cleanup temp file
API-->>Browser: 200 Success: Ingested X chunks
Browser->>User: ✅ Success message displayed
Why: Allows adding new LLM or Vector DB providers without modifying existing code. Supports runtime provider selection and fallback.
Why: Maintains backward compatibility while achieving Single Responsibility Principle internally. Each sub-service (auth, reader, sender, etc.) has one clear purpose.
Why: Separates business logic from presentation. Services can be tested independently and reused across different interfaces (CLI, API, Web).
Why: LLMProvider and VectorDBProvider base classes define contracts. New providers just need to implement the interface.
Why: All environment variables and settings in Config class. Single source of truth, easy to modify.
All configuration is environment-based via .env file:
# LLM Providers
GOOGLE_API_KEY=... # Primary LLM
ANTHROPIC_API_KEY=... # Fallback LLM
LLM_PRIMARY_PROVIDER=gemini # Primary provider
LLM_FALLBACK_PROVIDERS=claude # Comma-separated fallbacks
# Vector DB Providers
VECTOR_DB_TYPE=pinecone # Primary vector DB
PINECONE_API_KEY=...
PINECONE_INDEX_NAME=...
PINECONE_ENV=...
# Gmail
GMAIL_CREDENTIALS_FILE=credentials.json
GMAIL_TOKEN_FILE=token.json
# Web Application
SECRET_KEY=... # Flask session secret
# RAG Settings
CHUNK_SIZE=1000
CHUNK_OVERLAP=150- High-Level Design (HLD) - Detailed architecture diagrams
- Sequence Diagrams - Detailed interaction flows
- Multi-LLM Architecture - LLM provider system
- Multi-Vector DB Architecture - Vector database provider system