Skip to content

Latest commit

 

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Unsold AI

AI that turns questions into grounded answers—streamed live, saved forever, and built for faster resolution.

Node.js Express React MongoDB Socket.IO

Unsold AI is an AI augmentation layer that helps teams resolve issues faster by combining: live web grounding, token streaming, and persistent chat context. For operations-minded workflows, this can reduce:

  • MTTD/MTTR by accelerating “find the right info” and “draft the next action”
  • time spent on manual research through automated query rewriting + source surfacing
  • resolution friction via follow-up suggestions and searchable chat history

Features

  • 🔐 Auth with email verification (JWT in cookie + verification tokens)
  • 💬 Streaming AI chat with Socket.IO token-by-token updates
  • 🔎 Smarter answers with grounded web research
    • LLM decides when to search
    • rewritten search queries
    • multi-profile search (web/GitHub/StackOverflow/docs/YouTube)
  • 📚 Persistent conversation memory (MongoDB)
  • 🧾 Chat search & retrieval
  • 📈 Confidence estimation + follow-up suggestions
  • 🧩 Source cards and Mermaid diagram rendering for richer responses
  • 🎛️ Enterprise-friendly structure: modular services, routes, models, and middleware

Architecture Overview

High-level diagram

flowchart LR
  U[User] -->|Browser| FE[Frontend: React/Vite]
  FE -->|REST /api/auth| BE[Backend: Express API]
  FE -->|REST /api/chats| BE
  BE -->|Socket events| FE
  BE -->|Persist| DB[(MongoDB)]
  BE -->|LLM calls| LLM[Mistral via LangChain]
  BE -->|Web grounding| TAVILY[Tavily Search]
  BE -->|Email delivery| EMAIL[Gmail via Nodemailer]
Loading

Key design decisions

  1. Streaming over Socket.IO
    The backend streams LLM output tokens and emits:

    • chat:stream_started
    • chat:stream_token
    • chat:stream_complete
    • chat:stream_error
  2. Grounding only when needed
    shouldUseSearch() uses an LLM classification step to decide whether live web search is helpful for the latest user message. If enabled:

    • the query is rewritten for higher signal
    • Tavily results are scored/ranked
    • the answer is generated using these sources
  3. Local CORS configuration (dev-first)
    For development, both Express and Socket.IO are configured to accept connections from http://localhost:5173. Production deployments should externalize these origins.

  4. Persistent chat models
    Chats and messages are stored in MongoDB with a schema designed for:

    • per-user chat listing
    • ordered message retrieval
    • search across titles + message content
  5. HTTP cookie token auth
    Authentication uses a JWT cookie (token). Middleware verifies it and attaches the decoded payload to req.user.

Tech Stack

Area Technology
Frontend React 19, Vite, Redux Toolkit, TailwindCSS, Axios, Socket.IO client
Backend Node.js (ESM), Express, Socket.IO, Mongoose, MongoDB
AI & Search LangChain (Mistral chat model), Tavily (multi-profile search), LLM-based query rewrite/decision
Email Nodemailer (Gmail SMTP)
Rendering ReactMarkdown + GFM, Syntax highlighting, Mermaid

Quick Start / Local Development

Prerequisites

  • Node.js (recommended 18+)
  • MongoDB running locally (or accessible remotely)
  • A Gmail app password (for email verification)
  • API keys:
    • MISTRAL_API_KEY
    • TAVILY_API_KEY

Setup steps

  1. Install Backend dependencies

    cd Backend
    npm install
  2. Create Backend environment variables

    Create Backend/.env with the variables listed in Environment Variables.

  3. Install Frontend dependencies

    cd ../Frontend
    npm install
  4. Run MongoDB

    Start your MongoDB server (default MONGODB_URI is configured via env).

  5. Start Backend

    cd ../Backend
    npm run dev

    Backend listens on PORT (default 3000).

  6. Start Frontend

    In a new terminal:

    cd ../Frontend
    npm run dev

    Frontend runs on Vite dev server (default 5173).

  7. Seed data

    There is no separate seed job. Data is created automatically when you:

    • register (creates a user)
    • log in (sets auth cookie)
    • send chat messages (creates chat + message records)

Validate with a quick flow

  • POST http://localhost:3000/api/auth/register
  • POST http://localhost:3000/api/auth/login
  • POST http://localhost:3000/api/chats/message (with auth cookie)

Environment Variables

Variable Where Purpose
PORT Backend/.env Backend HTTP + Socket.IO port (default: 3000)
MONGODB_URI Backend/.env MongoDB connection string
JWT_SECRET Backend/.env JWT signing + verification for auth and email verification tokens
MISTRAL_API_KEY Backend/.env Mistral API key used by LangChain for chat + streaming
TAVILY_API_KEY Backend/.env Tavily API key used for web grounding/search
GOOGLE_USER Backend/.env Gmail username/from address
GOOGLE_APP_PASSWORD Backend/.env Gmail app password used for SMTP auth

Project Structure

This repo contains two apps: Backend and Frontend.

Directory What it contains
Backend/ Express API, Socket.IO streaming, Mongoose models, AI/search/email services
Frontend/ React/Vite UI, Redux state, REST + Socket.IO clients

Key Backend files:

Path Role
Backend/server.js Server bootstrap, DB connection, Socket.IO init
Backend/src/app.js Express middleware + route mounting
Backend/src/routes/auth.routes.js /api/auth/* endpoints
Backend/src/routes/chat.routes.js /api/chats/* endpoints
Backend/src/controllers/auth.controllers.js Auth + email verification logic
Backend/src/controllers/chat.controller.js Chat creation + streaming pipeline
Backend/src/services/ai.service.js Search decision, query rewrite, grounded/direct response streaming
Backend/src/services/internet.service.js Tavily multi-profile search + scoring
Backend/src/services/mail.service.js Gmail delivery (verification emails)
Backend/src/models/* User, Chat, Message schemas
Backend/src/sockets/server.socket.js Socket.IO initialization + emit helper

Key Frontend files:

Path Role
Frontend/src/main.jsx React bootstrap + router + Redux provider
Frontend/src/features/auth/* Login/registration + protected routing
Frontend/src/features/chat/* Chat UI + Redux slice + hooks
Frontend/src/features/chat/service/chat.socket.js Socket.IO client connection
Frontend/src/features/chat/service/chat.api.js REST client for chat endpoints

API Documentation

There is no Swagger/OpenAPI artifact currently committed in this repository. API behavior is documented by route handlers below.

Base URLs

  • REST: http://localhost:3000/api
  • Socket.IO: http://localhost:3000
  • Frontend dev origin: http://localhost:5173

Endpoints

Method Endpoint Auth Description
POST /api/auth/register Public Create user (sends verification email)
POST /api/auth/login Public Validate credentials and set token cookie
GET /api/auth/verify-email?token=... Public Verify email using token
POST /api/auth/resend-verification Public Resend verification email
GET /api/auth/get-me Private Get current user details
POST /api/chats/message Private Send a message, create/reuse chat, and stream AI response
GET /api/chats/list Private List user chats
GET /api/chats/messages/:chatId Private Get messages for a chat
GET /api/chats/search?q=... Private Search across chat titles and message content
DELETE /api/chats/delete/:chatId Private Delete a chat and its messages

Socket.IO events (streaming)

Event Direction Payload (shape)
chat:stream_started Server → Client { chatId, title }
chat:stream_token Server → Client { chatId, token }
chat:stream_complete Server → Client { chatId, message }
chat:stream_error Server → Client { chatId, error }

Example: send a chat message

  1. Ensure you’re authenticated (cookie-based JWT from /api/auth/login).
  2. Call:
curl -X POST "http://localhost:3000/api/chats/message" \
  -H "Content-Type: application/json" \
  --cookie "token=YOUR_JWT_COOKIE" \
  -d '{"message":"What is Unsold AI?","chat":null,"socketId":"OPTIONAL_SOCKET_ID"}'

The backend will emit streaming updates over Socket.IO; the frontend uses the socketId (client socket id) to target the right connection.

Demo / Screenshots

Screenshots help validate the streaming experience, sources panel, and conversation search.

  • Login & registration UI: TBD
  • Dashboard (chat + sidebar): TBD
  • Streaming response (token-by-token): TBD
  • Source slider + confidence + rewritten query chips: TBD
  • Conversation search overlay: TBD

Roadmap / Upcoming Features

  • Rate limiting and abuse protection for AI/search endpoints
  • CSRF-hardening for cookie auth (and production cookie flags: httpOnly, secure, sameSite)
  • Refresh tokens / session management (optional)
  • Pagination for chat list and messages
  • Backpressure controls for streaming and token generation
  • Optional persistence of per-message citations + stronger provenance metadata
  • API docs via OpenAPI/Swagger generation
  • Observability:
    • structured logs around AI/search decisions
    • request tracing across REST + Socket.IO
  • Containerization (Docker) and deployment manifests (K8s) for repeatable enterprise rollout

Contributing

Contributions are welcome. Suggested workflow:

  1. Open an issue describing the desired change (bug, feature, or docs).
  2. Create a feature branch.
  3. Keep changes focused (one responsibility per PR).
  4. Add/update documentation when behavior changes (especially API contracts and env vars).

Local development checks

  • Backend: npm run dev
  • Frontend: npm run dev

License

Backend/package.json specifies the project license as ISC.

Contact / Support

For issues, questions, or enterprise support:

  • Create a GitHub issue (preferred)
  • Or contact: ishanbhardwaj177@gmail.com

About

AI-powered search engine inspired by Perplexity that generates citation-backed answers using a RAG pipeline, real-time web search, and LLMs. Built with React, Redux, Node.js, and streaming AI responses.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages