🔗 Live Demo (chat widget) · Portfolio · LinkedIn
This is a FastAPI-based backend that powers the Digital Twin AI Assistant for Ramveer Singh's personal portfolio.
Built using the OpenAI Agents SDK, this project utilizes a Multi-Agent Orchestration Architecture to intelligently route queries, read external documents (like Resumes and GitHub profiles), and securely save contact information into a local SQLite database—all while fully supporting real-time Server-Sent Events (SSE) streaming!
flowchart TD
User([User Request]) --> API[FastAPI /api/chat Endpoint]
API --> Orchestrator[Orchestrator Stream]
Orchestrator --> ScopeAgent{Scope Agent}
ScopeAgent -- "Unrelated Query" --> Reject([Graceful Rejection])
ScopeAgent -- "Career / Experience Query" --> DomainExpert(Domain Expert)
ScopeAgent -- "Wants to Connect / Hire" --> DBWriter(DB Writer)
DomainExpert --> PDFTool[[pdf_reader tool]]
DomainExpert --> WebTool[[webscraper tool]]
PDFTool -.-> Drive[(Google Drive Resume)]
WebTool -.-> Web[(LinkedIn/GitHub)]
DBWriter --> WriteTool[[writetodb tool]]
WriteTool -.-> SQLite[(local.db Visitors Table)]
DomainExpert -- "Direct Tool Use" --> WriteTool
DomainExpert --> SSE([SSE Token Stream to UI])
DBWriter --> SSE
Reject --> SSE
The backend utilizes three specialized AI agents working in tandem:
-
Scope Agent (The Router)
- Acts as the first line of defense.
- Evaluates if the user's query is relevant to Ramveer's professional life, education, or skills.
- Rejects completely unrelated queries (e.g., cooking recipes).
- Seamlessly hands off relevant queries to the Domain Expert or DB Writer.
-
Domain Expert
- The core knowledge base representing Ramveer.
- Has access to specialized Python tools:
pdf_reader: Dynamically scrapes and reads Ramveer's Resume from Google Drive.webscraper: Capable of pulling text from web links like LinkedIn or GitHub.
- Can dynamically answer questions based purely on the factual data retrieved from these tools, preventing hallucinations.
-
DB Writer
- Triggers when a user wants to connect, collaborate, or hire Ramveer.
- Asks for the user's email address and invokes the
writetodbtool. - Saves the contact email into the local SQLite
visitorstable (local.db) so Ramveer can reach out later.
- Real-Time Streaming: Uses an asynchronous Python generator (
Runner.run_streamed) to pipe OpenAI tokens directly to the frontend as they generate. - Mid-Stream Handoffs: Custom orchestrator logic gracefully intercepts agent-to-agent transfers mid-stream without breaking the HTTP connection.
- FastAPI Endpoint: Exposes a clean
POST /api/chatendpoint compatible with Vercel AI SDK and custom React hooks. - SQLite Lead Capture: Safely stores visitor emails locally.
- Python 3.12+
pip/venv- OpenAI API Key
- Clone the repository and navigate to the project directory.
- Create and activate a virtual environment in the
backendfolder:cd backend python -m venv venv source venv/bin/activate
- Install the dependencies:
pip install -r requirements.txt
- Create a
.envfile in thebackend/directory (see.env.exampleif applicable) and configure your keys:OPENAI_API_KEY=sk-... LIBSQL_URL="file:./local.db" USER_NAME="Ramveer Singh" ALLOWED_SCRAPE_DOMAINS='{"resume": "https://drive.google.com/...", "github": "..."}'
Use the provided bash script to start the Uvicorn server:
sh start.shThe API will be available at http://0.0.0.0:8000.
Send a POST request to /api/chat:
curl -X POST http://localhost:8000/api/chat \
-H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "Tell me about Ramveer"}]}' \
--no-bufferThe local SQLite database will be automatically created in the root of your project as local.db.
To view captured emails, run:
sqlite3 local.db "SELECT * FROM visitors;"Built by Ramveer Singh · LinkedIn · GitHub