An AI-powered career mentor platform where users step into realistic, real-time role-play scenarios from different professions — and get an AI mentor that runs the scene, then hands back a structured debrief of the skills they showed.
Live app: kg-pedia.vercel.app
Instead of static career quizzes or articles, KGPedia drops the user into a live, on-the-job situation — a production outage, a classroom disruption, a client meeting gone wrong — and has them talk it through with an AI mentor in real time over a WebSocket connection. At the end of the session, the AI generates a structured debrief (key moments, skills demonstrated, career-fit reflection) that the user can save to a personal "Career Insights Portfolio."
| Profession | Scenario | Duration |
|---|---|---|
| Software Engineer | Production Outage — Real-Time Triage | 20–25 min |
| High School Teacher | Classroom Disruption — Student Escalation | 20–25 min |
| Financial Analyst | Delivering Bad News to a Client | 20–25 min |
| Supply Chain Manager | Supplier Disruption — Executive Escalation | 20–25 min |
| Marketing Manager | Social Media Crisis — Brand Damage Control | 20–25 min |
| Human Resources Manager | Workplace Complaint — Investigation & Mediation | 20–25 min |
- Live, streaming conversation over a single WebSocket endpoint — no polling, no page reloads.
- Personalized onboarding — an intake step captures experience level, background, and career goals, and the AI's opening message is generated to match (first-timer vs. returning user, exploration vs. full scenario mode).
- Context across sessions — returning users get a natural recap of their last session for the same profession, sourced from a cached summary or Firestore.
- Dual-model orchestration — GPT-4o-mini runs as a lightweight function-calling "router" that detects intents like save this to my portfolio or end the session, while GPT-4o handles the actual in-character streaming response. Gemini is wired in as an automatic fallback if the OpenAI key is missing or fails.
- Structured end-of-session debrief — GPT-4o (JSON mode) turns the conversation into a summary: key moments, skills identified, and a career-fit reflection.
- Career Insights Portfolio — debriefs and skills can be saved per-user and revisited later.
- Natural session ending — a session ends when the user says something like "that's it for today" or "I've gotta go," not just via a button.
- Graceful degradation — if Firebase credentials aren't configured, sessions and summaries fall back to in-memory storage automatically, so the app still runs for local development.
Browser (React) ──WebSocket──▶ /ws/chat ──▶ FastAPI backend
──REST───────▶ /api/session, /api/professions, /api/history
Backend flow per chat turn:
user message ─▶ GPT-4o-mini router (function-calling: save_portfolio_item / end_session)
─▶ GPT-4o generator (streams the in-character mentor response)
Persistence: Firestore (sessions, summaries, portfolio) → in-memory fallback if unconfigured
- Backend — FastAPI (Python 3.11), a single
/ws/chatWebSocket handlinginitialize/chat/endmessage types, plus REST routes for session lifecycle, the profession list, and chat history. - Frontend — React 19 + TypeScript + Vite, Zustand for state, Tailwind CSS v4, Firebase Auth for login.
- Persistence — Firebase/Firestore, with an automatic in-memory fallback store when credentials aren't set.
- Deployment — backend on Render (Docker), frontend on Vercel. Configs for Azure App Service and a manual AWS EC2 + Nginx setup also exist in the repo but are currently disabled in favor of Render + Vercel.
Backend: FastAPI, Uvicorn, websockets, OpenAI Python SDK (async, streaming), Google Gemini SDK, Firebase Admin SDK, Pydantic
Frontend: React 19, TypeScript, Vite, Tailwind CSS v4, Zustand, React Router, Firebase Web SDK, lucide-react
KGPedia/
├── profchat-backend/
│ ├── main.py # FastAPI app + WebSocket chat endpoint
│ ├── config/settings.py # Env-driven config
│ ├── routers/ # /api/session, /api/professions
│ ├── services/ # Session, chat, and summary logic
│ ├── models/ # Pydantic request/response schemas
│ ├── utils/
│ │ ├── llm/orchestrator.py # Router + generator LLM orchestration
│ │ ├── llm/tools.py # Function-calling tool definitions
│ │ ├── prompts/ # Per-profession scenario prompt builder
│ │ └── firebase_utils.py # Firestore access + in-memory fallback
│ ├── Dockerfile
│ └── requirements.txt
├── profchat-frontend/
│ ├── src/
│ │ ├── pages/ # Dashboard, Chat, Summary
│ │ ├── components/ # Auth/Intake modals, chat UI
│ │ ├── hooks/ # useAuth, useChat, useChatHistory
│ │ ├── services/ # WebSocket + session API clients
│ │ └── store/ # Zustand chat store
│ └── package.json
├── infra/ # Nginx config + EC2 setup script (reference only)
├── .github/workflows/ # CI + deploy workflows
└── render.yaml # Render deployment config
cd profchat-backend
pip install -r requirements.txt
cp .env.example .env # fill in OPENAI_API_KEY at minimum
uvicorn main:app --reload --port 8000Firebase and Gemini keys are optional for local development — without them, sessions persist in-memory and Gemini simply isn't used as a fallback.
cd profchat-frontend
npm install
cp .env.example .env # point VITE_API_URL / VITE_WS_URL at your local backend
npm run devBackend (profchat-backend/.env)
| Variable | Required | Notes |
|---|---|---|
OPENAI_API_KEY |
Yes | Powers the router, generator, and summary models |
GEMINI_API_KEY |
No | Used only as an automatic fallback if OpenAI fails |
FIREBASE_CREDENTIALS_JSON |
No | Service account JSON, single line; omit to use in-memory storage |
FIREBASE_DATABASE_URL |
No | Only needed alongside Firebase credentials |
LLM_MAIN_MODEL |
No | Default gpt-4o |
LLM_MODEL |
No | Default gpt-4o-mini (router) |
GEMINI_GENERATOR_MODEL |
No | Default gemini-2.5-flash |
CORS_ORIGINS |
No | Comma-separated allowed frontend origins |
Frontend (profchat-frontend/.env)
| Variable | Notes |
|---|---|
VITE_API_URL |
Backend REST base URL |
VITE_WS_URL |
Backend WebSocket URL (/ws/chat) |
VITE_FIREBASE_* |
Firebase Web SDK config (API key, auth domain, project ID, etc.) |
- Current: backend auto-deploys to Render via
render.yaml(Docker); frontend auto-deploys to Vercel on push tomain. - Also included, currently disabled: an Azure App Service workflow and a manual AWS EC2 + Docker + Nginx setup (
infra/setup-ec2.sh,infra/nginx.conf) — kept as reference in case the deployment target changes.
GitHub Actions (ci.yml) runs on every push:
- Frontend: TypeScript check, ESLint, and a production build smoke test.
- Backend: Ruff lint and a Docker build verification.