Welcome to Research-AI! This is a full-stack, real-time chat application built using the powerful MERN stack (MongoDB, Express.js, React, Node.js) combined with modern tooling like Vite, TailwindCSS v4, and Server-Sent Events (SSE) for a seamless real-time experience.
- Project Overview
- Features
- Tech Stack
- Getting Started
- Environment Configuration
- Complete Project Workflow
- AI Integration & Services
- Frontend-Backend Integration
- UI Component Architecture
- API Endpoints
- Project Architecture & Directory Structure
Research-AI is designed to provide secure authentication alongside an interactive real-time chat interface. Users can seamlessly establish chat sessions, send/receive messages instantly using markdown, view their active chats, and securely manage their sessions.
- Real-time Chat: Powered by Server-Sent Events (SSE) for instantaneous messaging.
- AI-Powered Search: Integrates Tavily Search for real-time internet-backed responses.
- Smart Summarization: Uses Mistral to generate concise chat titles.
- Secure Auth: JWT-based authentication with HttpOnly cookies.
- Markdown Support: Rich text formatting with code syntax highlighting.
- Citations: AI responses include clickable source links for transparency.
- Email Verification: OAuth2-based email verification using Nodemailer.
Frontend (Client)
- React 19 (via Vite)
- Redux Toolkit (State Management & Data Fetching)
- Tailwind CSS v4 (Modern Styling Setup)
- React Router v7 (Routing & Application Flow)
- React Markdown (Rich text formatting in chat responses)
Backend (Server)
- Node.js & Express.js (Core API Architecture)
- MongoDB with Mongoose (NoSQL Database)
- JWT (JSON Web Tokens) (Authentication via persistent HTTP-only Cookies)
Create a .env file in the backend/ directory and populate it with the following:
# Database
MONGO_URI=your_mongodb_uri
# Authentication
JWT_SECRET=your_jwt_secret
# AI API Keys
GEMINI_API_KEY=your_gemini_api_key
MISTRAL_API_KEY=your_mistral_api_key
TAVILY_API_KEY=your_tavily_api_key
# Email Service (Google OAuth2)
GOOGLE_USER=your_email@gmail.com
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_REFRESH_TOKEN=your_google_refresh_token- Registration: Users easily create an account using
email,username, andpassword. The system robustly validates these details, hashes the password, and provisions the user inside the database. It also offers email verification endpoints. - Login: Upon registration verification, credentials can be formulated to securely login. The server validates credentials and issues a secure, HttpOnly JWT cookie ensuring safe future requests.
- Session Persistence (
get-me): Whenever the frontend finishes loading, it automatically fires theget-meendpoint. This validates the background cookie and restores the user session rapidly without the hassle of relogging.
- Connection: Upon successive login/verification, the application utilizes Server-Sent Events (SSE) to handle real-time streaming between the client and the centralized server.
- Fetching Chats: The React frontend initially connects to the centralized API (
/api/chat/) to resolve previous user conversations and populates the sidebar respectively. - Messaging in Real-Time:
- First, a user structurally writes a text or markdown-heavy message.
- A structured API request (
POST /api/chat/message) stores the message payload indefinitely within MongoDB. - Concurrently, Server-Sent Events (SSE) stream the live AI response data strictly to the applicable chat session allowing for instant visual representation.
- Chat Management: Users may load historical messages of particular threads via
/:chatId/messagesand are even provided capabilities to remove outdated discussions through thedeleteworkflow.
The backend architecture uses a modular approach to handle AI capabilities, splitting concerns across models, tools, agents, and services.
This module initializes our core AI and search instances using environment variables:
- Gemini (
gemini-2.5-flash-lite): Instantiated via@langchain/google-genai, acting as the primary conversational brain for complex reasoning and agentic tasks. - Mistral (
mistral-small-latest): Instantiated via@langchain/mistralai, utilized efficiently for generating short, descriptive chat titles. - Tavily: Instantiated via
@tavily/core, providing the real-time internet search capability.
internetSearch: Relies on the Tavily API to execute real-time web queries, retrieving up to 5 maximum results.- It formats the returned data into a stringified JSON array containing the Source, Title, URL, and Content, which is seamlessly sent to the frontend for rich UI component rendering.
searchInternetTool: Wraps theinternetSearchfunction into a formal Langchaintoolwith an explicit schema (requiring aquerystring).
searchAgent: A dynamic agent created usingcreateAgent, binding thegeminiModelwith thesearchInternetTool. This allows Gemini to autonomously decide when to query the internet for up-to-date information.
This service acts as the bridge orchestrating AI interactions:
generateResponse: InvokessearchAgent.streamwith a highly detailedSystem_Promptthat enforces source-backed, structured responses with inline citations (e.g.,[1]). It streams the AIMessage chunks directly back to the client.generateChatTitle: Passes the user's first message tomistralModelto generate a concise 2-4 word title.- Context Management:
buildContexttruncates chat history to the last 10 messages to maintain efficiency and stay within token limits. - Citation Parsing & Formatting:
parseCitationsandformatResponseextract URL footprints from the AI's response text and map them into structuredcitationsobjects for the frontend UI.
When a POST request to /message is fired, the AI interaction pipeline kicks in:
- The controller checks if a
chatIdwas provided. If missing (meaning it's a new conversation), it triggersgenerateChatTitleand persists a newchatModelentry. - Persistent Conversational Memory: The controller executes a database lookup inside
messageModelfetching chronological chat history tied to the activechatId. - This historical context is forwarded directly into
generateResponse(messages)resolving context seamlessly.
For the real-time agent to maintain long-term contextual awareness, the conversations are persisted relationally:
chat.model.js: Contains the root conversation instance referencing theUseralongside the AI-generatedtitle.message.model.js: Chronologically maps individual pieces of text to their parentchat. Crucially, it enforces a strictroleenum ("user"or"ai") and stores the completepartsarray to persist rich Generative UI blocks.- Inside
ai.service.js, the historical array frommessageModelis converted into Langchain's conceptual formats (HumanMessage&AIMessage).
To guarantee a reactive and secure user interface, the React frontend handles server communication via structured API services, hooks, and global state reducers.
- Both
auth.api.jsandchat.api.jsuse custom Axios instances with abaseURLpointing to the server. - Every axios request establishes
withCredentials: true, allowing the frontend to automatically transit the secureHttpOnlyJWT Authentication Cookie.
handleSendMessage: Dispatches user text tochat.api.jsusing a robust SSE chunk parser capable of reassembling fragmented JSON event packets over TCP.- Real-Time Streaming: Leverages Server-Sent Events (SSE) via the Fetch API to handle the streaming response from the AI, updating the
streamingPartsarray in real-time. handleGetChats&handleOpenChat: Fetch chat history and manage the active conversation state.
- Any resolved API network response triggers dispatched structures to local UI states within
authandchatslices. Loadedchatsmap dynamically onto Redux memory for zero-latency switches.
- Leverages a custom SSE parser to process mixed-content streams (text and dynamic UI tools). It constructs an immutable array of
partsthat instantly renders React components (like a Sources grid) when AI agents use tools, mimicking the rich experience of ChatGPT and Perplexity.
The frontend/src/features/chat module constructs an advanced interface combining complex React hooks with dynamic Markdown rendering.
- Central command component syncing
useChatcustom hooks with the Redux store. - Provides loading animations ("Thinking dots") and handles
isStreamingstate for real-time AI response rendering. - Manages scroll positions natively using a
ResizeObserverto instantly scroll into view without jitter when rich Generative UI tool components abruptly enter the DOM. - Isolates AI "Sources" into interactive citation bars.
AI responses are rendered via react-markdown with remarkGfm.
- Dynamic
<CodeBlock>: Interceptscodeoutputs, adding syntax headers and a "Copy" functionality. - Inline Web Citations: A regex-based mechanism resolves AI's internal response footnotes (e.g.,
[1]), binding them to dynamically clickable inline footnotes.
- Interactive
textareawith auto-resizing logic (up to120pxheight). - Intercepts physical keyboard
Enteractions and prevents API racing conditions by disabling inputs duringisLoadingstates.
Endpoints are completely categorized, safeguarded, logging-enabled (via Morgan), and highly cohesive. A complete list revolves around:
| Method | Endpoint | Description | Access | Payload/Parameters |
|---|---|---|---|---|
POST |
/register |
Validates inputs using Joi/Zod, hashes the password, creates a new user in MongoDB, and triggers a verification email. | Public | Body: { username, email, password } |
POST |
/login |
Authenticates user identity, compares password hash, and resolves with an HttpOnly JWT Cookie for secure session management. |
Public | Body: { email, password } |
GET |
/get-me |
Returns the currently logged-in user's profile details based on the valid JWT cookie. | Private | Headers: Cookie |
GET |
/verify-email |
Validates an email token and marks the user's account as verified in the database. | Public | Query: ?token=... |
| Method | Endpoint | Description | Access | Payload/Parameters |
|---|---|---|---|---|
GET |
/ |
Retrieves a list of all chat sessions associated with the authenticated user, sorted by recency. | Private | Headers: Cookie |
POST |
/message |
Core AI interaction endpoint. Processes user messages, streams structured AI responses (text and tools) via Server-Sent Events (SSE), persists the parts array history, and auto-generates chat titles. |
Private | Body: { message, chat? } |
GET |
/:chatId/messages |
Fetches the complete chronological message history for a specific chat session. | Private | Params: chatId |
DELETE |
/delete/:chatId |
Completely removes a chat session and all its associated messages from the database. | Private | Params: chatId |
(Note: Every Private scoped endpoint is strictly walled behind an authUser wrapper expecting validated JSON Web Tokens configured tightly in cookies!)
Research-AI/
β
βββ backend/ # Server-side environment & application logic
β βββ src/
β β βββ ai/ # AI model instances, tools, and agents
β β β βββ agents/ # Langchain Agents logic
β β β β βββ search.agent.js # Agent utilizing search tools
β β β βββ tools/ # Specialized AI tools (Search, etc.)
β β β β βββ internet.tool.js # Tavily Search implementation
β β β β βββ title.tool.js # Structured agent for generating chat titles
β β β βββ model.js # AI Models Initialization (Gemini, Mistral)
β β βββ config/ # Database and server configurations
β β β βββ config.js # Configuration setup
β β β βββ db.js # Mongoose connection setup (MongoDB)
β β βββ controllers/ # Business logic handlers for specific routes
β β β βββ auth.controller.js # Logic for user registration, login, and logout
β β β βββ chat.controller.js # Logic for handling chats and AI responses
β β βββ dao/ # Data Access Objects (DB query encapsulation)
β β β βββ chat.dao.js # Data access operations for Chat model
β β β βββ message.dao.js # Data access operations for Message model
β β β βββ user.dao.js # Data access operations for User model
β β βββ middlewares/ # Security and request interceptors
β β β βββ auth.middleware.js # Middleware to verify JWT tokens in cookies
β β βββ models/ # MongoDB schema definitions using Mongoose
β β β βββ chat.model.js # Schema for conversation metadata
β β β βββ message.model.js # Schema for individual chat messages
β β β βββ user.model.js # Schema for user profiles and credentials
β β βββ routes/ # API endpoint definitions mapping to controllers
β β β βββ auth.routes.js # Routes for auth-related actions
β β β βββ chat.routes.js # Routes for chat and message management
β β βββ services/ # Specialized logic and external integrations
β β β βββ ai.service.js # Core AI logic (Gemini & Mistral integration)
β β β βββ mail.service.js # Email dispatch logic for verification
β β βββ validators/ # Request body validation and sanitization
β β β βββ auth.validator.js # Joi/Zod validators for auth inputs
β β βββ app.js # Main Express application configuration
β βββ package.json # Backend dependencies and execution scripts
β βββ server.js # Entry point for the server
β βββ .env # Environment secrets (MongoDB, API Keys, JWT)
β
βββ frontend/ # Client-Side Application (React + Vite)
βββ public/ # Static assets accessible globally
β βββ vite.svg # Vite branding asset
βββ src/
β βββ APP/ # Global application-level logic & styling
β β βββ routes/
β β β βββ AppRoutes.jsx # Navigation routing (Public vs Protected)
β β βββ store/
β β β βββ App.store.js # Centralized Redux store setup
β β βββ App.jsx # Root UI Layout component
β β βββ index.css # Global CSS & Tailwind directives
β βββ features/ # Scalable feature-based directory pattern
β β βββ auth/ # Authentication & User Management
β β β βββ components/
β β β β βββ Protected.jsx # Authorization wrapper for routes
β β β βββ hooks/
β β β β βββ useAuth.js # Hook for calling registration/login
β β β βββ pages/
β β β β βββ Login.jsx # User Login page interface
β β β β βββ Register.jsx # Account creation page interface
β β β βββ services/
β β β β βββ auth.api.js # Axios endpoints for Auth API
β β β βββ slice/
β β β βββ auth.slice.js # Global Auth state (User, Status)
β β βββ chat/ # Interactive Assistant & Real-time Chat
β β βββ components/
β β β βββ ChatInput.jsx # Interactive message composition field
β β β βββ MarkdownComponents.jsx # Rich rendering for AI responses
β β β βββ Navbar.jsx # Application top navigation menu
β β β βββ Reuse.jsx # Collection of reusable UI elements
β β β βββ Sidebar.jsx # List of active conversations/history
β β βββ hooks/
β β β βββ useChat.js # logic for AI response & SSE flow
β β βββ pages/
β β β βββ DashBoard.jsx # The main primary chat dashboard
β β β βββ Landing.jsx # Project Overview & Welcome page
β β β βββ Profile.jsx # User identity & security settings
β β βββ services/
β β β βββ chat.api.js # Axios endpoints for Chat/History API
β β βββ shared/
β β β βββ global.js # Shared UI constants & helper functions
β β β βββ LogoIcon.jsx # Scalable logo component
β β βββ slices/
β β β βββ chat.slices.js # Global Chat state (Messages, Threads)
β β βββ styles/
β β βββ landing.css # Styles specifically for Landing page
β β βββ navbar.css # Styles specifically for Navbar
β βββ main.jsx # Main React mount point and entry script
βββ eslint.config.js # ESLint rules for code quality
βββ index.html # Root HTML template for the SPA
βββ package.json # Frontend dependencies (React, Redux, etc.)
βββ vite.config.js # Vite bundler configuration and proxying
βββ flow.md # Technical workflow specifications (e.g. logout flow)
βββ improve.md # Production deployment and optimization checklist
βββ Readme.md # Project documentation and architecture guide
Contributions are welcome! Please follow these steps:
- Fork the project.
- Create your feature branch (
git checkout -b feature/AmazingFeature). - Commit your changes (
git commit -m 'Add some AmazingFeature'). - Push to the branch (
git push origin feature/AmazingFeature). - Open a Pull Request.
Distributed under the MIT License. See LICENSE for more information.
Ghansham Jadhav - ghanshamjadhav204@gmail.com
Project Link: https://github.com/sham-jadhav03/Research-AI