---
title: Nexus Memory Backend
emoji: π§
colorFrom: indigo
colorTo: purple
sdk: docker
app_port: 7860
pinned: false
---
# Nexus Memory
> A local AI assistant that **remembers you**, answers questions from your **documents**, and runs **entirely on your machine** β no cloud, no subscriptions, no data leaving your device.
[](https://python.org)
[](https://fastapi.tiangolo.com)
[](https://react.dev)
[](https://langchain.com)
[](https://ollama.com)
[](https://trychroma.com)
[](LICENSE)
**[Features](#-features) β’ [Architecture](#-architecture) β’ [Setup](#-setup) β’ [Usage](#-usage) β’ [API](#-api-reference) β’ [Tech Stack](#-tech-stack)**
---
## What Is Nexus Memory?
Nexus Memory is a **production-inspired local AI assistant** built to demonstrate practical AI engineering skills. Unlike generic chatbots, Nexus Memory:
- **Remembers facts about you** across conversations using semantic memory extraction
- **Reads your documents** and answers questions using RAG (Retrieval-Augmented Generation)
- **Runs 100% locally** via Ollama β your data never leaves your machine
- **Streams responses** in real-time just like ChatGPT
- **Persists everything** in SQLite + ChromaDB for long-term use
Built in one day as a focused demonstration of modern AI engineering β clean architecture, practical tooling, and shipping ability.
---
## Features
### Conversational Chat
- ChatGPT-style streaming interface with real-time token rendering
- Markdown rendering with code blocks, tables, and formatting
- Multi-turn conversation with full history persistence
- Multiple chat sessions with sidebar navigation
- Copy message button on every bubble
- Typing indicator during response generation
### Persistent Memory System
- **Automatic memory extraction** β AI identifies and stores important facts from your conversation
- **Semantic memory retrieval** β finds relevant memories using vector similarity search
- **Memory panel** β view, add, and delete memories with category badges
- **Memory badges** on responses showing how many memories were used
- Categories: `technical`, `professional`, `preference`, `goal`, `general`
- Backed by SQLite (structured) + ChromaDB (semantic search)
### PDF / Document Chat (RAG)
- Upload **PDF**, **TXT**, and **Markdown** files
- Automatic text extraction and intelligent chunking
- Semantic embeddings via `nomic-embed-text`
- MMR (Maximum Marginal Relevance) retrieval for diverse, relevant results
- Source-aware answers with document chunk badges
- Multi-document support β query across multiple files simultaneously
### Local LLM Integration
- Powered by **Ollama** β runs llama3, mistral, and any installed model
- Live model selector dropdown β switch models mid-conversation
- No API keys, no rate limits, no cloud dependency
- Streaming responses via Server-Sent Events (SSE)
### Modern Dark UI
- Clean dark theme with indigo/purple accent colors
- Smooth Framer Motion animations throughout
- Responsive sidebar with collapsible panel
- Drag-and-drop file upload with progress tracking
- Memory side panel with live count badge
---
## Architecture
### System Overview
```text
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NEXUS MEMORY β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β FRONTEND (React + Vite) β β
β β β β
β β ββββββββββββ ββββββββββββββ ββββββββββββββββββββββββ β β
β β β Sidebar β β ChatWindow β β MemoryPanel β β β
β β β Sessions β β Messages β β Brain Icon Panel β β β
β β β Memory β β Streaming β β Add/Delete Memory β β β
β β β Tab β β Markdown β β β β β
β β ββββββββββββ ββββββββββββββ ββββββββββββββββββββββββ β β
β β β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β β βUploadSection β βModelSelector β β MessageBubbleβ β β
β β β Drag & Drop β β Live Models β β Badges+Copy β β β
β β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β β
β βββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ β
β β HTTP / SSE β
β βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β BACKEND (FastAPI + Python) β β
β β β β
β β POST /chat GET /chat/sessions β β
β β POST /upload GET /memory/{session_id} β β
β β POST /memory DELETE /memory/{id} β β
β β GET /health DELETE /documents/{id} β β
β ββββββββββββ¬βββββββββββββββββββββ¬βββββββββββββββββββββββββββ β
β β β β
β βΌ βΌ β
β ββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββ β
β β LANGCHAIN β β STORAGE LAYER β β
β β PIPELINE β β β β
β β β β βββββββββββββββ ββββββββββββββ β β
β β PromptTemplate β β β SQLite β β ChromaDB β β β
β β Memory Retrievalβ β β β β β β β
β β Doc Retrieval β β β Sessions β β Memory β β β
β β Context Build β β β Messages β β Vectors β β β
β β Response Stream β β β Memories β β β β β
β ββββββββββ¬ββββββββββ β β Documents β β Doc Chunks β β β
β β β βββββββββββββββ ββββββββββββββ β β
β βΌ ββββββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββ β
β β OLLAMA (Local) β β
β β β β
β β llama3 β β
β β nomic-embed-textβ β
β β mistral / phi3 β β
β ββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
### Chat Request Flow
```text
User Types Message
β
βΌ
useChat Hook (React)
βββ fetch POST /chat ββββββββββββββββββββββββββββββββββββββββββ
β
FastAPI /chat
β
ββββββββββββββββββββββββββββββββββββ€
β β
βΌ β
Retrieve Memories β
(ChromaDB semantic search) β
filter by session_id β
threshold > 0.3 similarity β
β β
βΌ β
Retrieve Document Chunks β
(ChromaDB MMR search) β
across all session documents β
β β
βΌ β
Build LangChain Prompt β
βββββββββββββββββββββββββββββββ β
β SYSTEM: memories + doc ctx β β
β HISTORY: last 6 messages β β
β HUMAN: user message β β
βββββββββββββββββββββββββββββββ β
β β
βΌ β
OllamaLLM.astream() β
yields tokens βββΊ SSE Stream βββΊ Browser β
β β
βΌ β
Store Assistant Message (SQLite) β
β β
βΌ β
Extract Memories (LLM pipeline) β
Store Facts (SQLite + ChromaDB) β
β β
βΌ β
Browser renders tokens in real-time β
Shows π§ memory badge + π docs badge
```
### RAG Document Pipeline
```text
User Uploads PDF/TXT/MD
β
βΌ
βββββββββββββββββββ
β File Saved β
β to uploads/ β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β Text Extraction β
β PyPDFLoader β
β TextLoader β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Intelligent Chunking β
β RecursiveCharacterTextSplitter β
β chunk_size=1000, overlap=200 β
β separators: ["\n\n","\n",". "," ",""] β
ββββββββββ¬βββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Vector Embeddings β
β nomic-embed-text via Ollama β
β 768-dimensional vectors β
ββββββββββ¬βββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β ChromaDB Storage β
β Unique collection per document β
β Persistent on disk β
β Metadata: source, page, chunk_index β
ββββββββββ¬βββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Query Time (MMR Retrieval) β
β fetch_k = 12 candidates β
β return k = 4 diverse results β
β lambda_mult = 0.7 (relevance bias) β
ββββββββββ¬βββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β LLM Context Injection β
β Formatted with source citations β
β Injected into system prompt β
βββββββββββββββββββββββββββββββββββββββββββ
```
### Memory System Pipeline
```text
Conversation Happens
β
βΌ
LLM Extracts Facts
ββββββββββββββββββββββββββββββββββββββββββββ
β Prompt: "Extract important personal β
β facts from this conversation..." β
β Returns: JSON array of facts β
ββββββββββββββββββββ¬ββββββββββββββββββββββββ
β
ββββββββββββ΄βββββββββββ
β β
βΌ βΌ
SQLite Storage ChromaDB Storage
ββββββββββββββββ ββββββββββββββββββββ
β memory_id β β Vector embedding β
β session_id β β of fact text β
β fact (text) β β β
β category β β Metadata: β
β confidence β β session_id β
β created_at β β category β
ββββββββββββββββ β memory_id β
ββββββββββββββββββββ
β
βΌ
Query Time: Semantic Search
ββββββββββββββββββββββββββββ
β similarity_search with β
β session_id filter β
β relevance threshold 0.3 β
ββββββββββββββββββββββββββββ
β
βΌ
Inject into System Prompt
"Relevant memories about user:
- User prefers Python
- User works at a startup
- User loves FastAPI"
```
---
## Tech Stack
| Layer | Technology | Purpose |
| ------------------ | ------------------------------ | ---------------------------- |
| **Frontend** | React 18 + Vite | UI framework + build tool |
| **Styling** | TailwindCSS v3 | Utility-first dark theme |
| **Animations** | Framer Motion | Smooth transitions |
| **Icons** | Lucide React | Consistent icon set |
| **Markdown** | React Markdown + remark-gfm | AI response rendering |
| **HTTP Client** | Axios + Fetch | API calls + SSE streaming |
| **Backend** | FastAPI | High-performance async API |
| **LLM Runtime** | Ollama | Local model inference |
| **AI Framework** | LangChain | Prompt chains + retrieval |
| **LLM** | llama3 / mistral | Language generation |
| **Embeddings** | nomic-embed-text | Semantic vector creation |
| **Vector DB** | ChromaDB | Semantic similarity search |
| **Relational DB** | SQLite | Session + memory persistence |
| **PDF Parsing** | PyPDF | Document text extraction |
| **Text Splitting** | RecursiveCharacterTextSplitter | Intelligent chunking |
---
## Requirements
### System Requirements
| Requirement | Minimum | Recommended |
| ----------- | ---------------------- | ----------- |
| OS | macOS 12+ / Ubuntu 20+ | macOS 14+ |
| RAM | 8 GB | 16 GB |
| Storage | 10 GB free | 20 GB free |
| Python | 3.11+ | 3.11.8 |
| Node.js | 18+ | 20+ |
### Software Prerequisites
```bash
# 1. Python 3.11+
python3 --version # must be 3.11.x or higher
# 2. Node.js 18+
node --version # must be v18.x or higher
npm --version # must be 9.x or higher
# 3. Ollama
# Download from https://ollama.com
ollama --version # must be installed
```
### Python Dependencies
```text
fastapi==0.111.0
uvicorn[standard]==0.30.1
python-multipart==0.0.9
langchain==0.2.16
langchain-community==0.2.16
langchain-chroma==0.1.4
langchain-ollama==0.1.3
chromadb==0.5.3
sentence-transformers==3.0.1
pypdf==4.2.0
sqlalchemy==2.0.31
pydantic==2.8.2
pydantic-settings==2.3.4
python-dotenv==1.0.1
aiofiles==23.2.1
httpx==0.27.0
```
### Frontend Dependencies
```text
react: ^18.3.1
react-dom: ^18.3.1
axios: ^1.7.2
react-markdown: ^9.0.1
framer-motion: ^11.2.12
react-dropzone: ^14.2.3
lucide-react: ^0.395.0
date-fns: ^3.6.0
remark-gfm: ^4.0.0
uuid: ^10.0.0
```
---
# Setup
## Step 1 β Clone the Repository
```bash
git clone https://github.com/yourusername/nexus-memory.git
cd nexus-memory
```
---
## Step 2 β Install and Start Ollama
```bash
# Download Ollama from https://ollama.com
# After installation, pull required models:
ollama pull llama3
ollama pull nomic-embed-text
# Verify models are available
ollama list
```
Expected output:
```bash
NAME ID SIZE MODIFIED
llama3:latest 365c0bd3c000 4.7 GB X days ago
nomic-embed-text:latest 0a109f422b47 274 MB X days ago
```
---
## Step 3 β Backend Setup
```bash
# Navigate to project root
cd nexus-memory
# Create virtual environment at ROOT level (important!)
python3 -m venv venv
# Activate virtual environment
source venv/bin/activate # macOS / Linux
# venv\Scripts\activate # Windows
# Install all dependencies
pip install --upgrade pip
pip install -r requirements.txt
# Pre-compile packages to prevent watchfiles issues
python -m compileall venv/lib/python3.11/site-packages/ -q
# Start the backend
cd backend
python run.py
```
Backend runs at: `http://localhost:8000`
API docs at: `http://localhost:8000/docs`
---
## Step 4 β Frontend Setup
```bash
# Open a NEW terminal tab
cd nexus-memory/frontend
# Install dependencies
npm install
# Start development server
npm run dev
```
Frontend runs at: `http://localhost:5173`
---
## Step 5 β Verify Everything is Running
```bash
# Check system health
curl -s http://localhost:8000/health | python -m json.tool
```
Expected response:
```json
{
"api": "healthy",
"ollama": {
"status": "healthy",
"models": ["nomic-embed-text:latest", "llama3:latest"],
"current_model": "llama3"
},
"model": "llama3"
}
```
Open `http://localhost:5173` β you should see the dark Nexus Memory interface.
---
# Project Structure
```text
nexus-memory/
β
βββ venv/ # Python virtual environment (root level)
β
βββ backend/
β βββ main.py # FastAPI app + lifespan + CORS
β βββ config.py # Settings + environment config
β βββ database.py # SQLAlchemy models + session
β βββ run.py # Uvicorn server with watch config
β β
β βββ routes/
β β βββ chat.py # POST /chat (streaming SSE)
β β βββ upload.py # POST /upload (document processing)
β β βββ memory.py # GET/POST/DELETE /memory
β β
β βββ rag/
β β βββ loader.py # PDF + TXT document loading
β β βββ chunker.py # RecursiveCharacterTextSplitter
β β βββ embeddings.py # ChromaDB store + load + delete
β β βββ retriever.py # MMR semantic retrieval
β β
β βββ memory/
β β βββ store.py # SQLite + ChromaDB memory storage
β β βββ extractor.py # LLM-based fact extraction
β β
β βββ services/
β β βββ llm.py # Ollama LLM + embeddings factory
β β
β βββ uploads/ # Uploaded document storage
β βββ chroma_db/ # ChromaDB vector persistence
β βββ nexus_memory.db # SQLite database
β
βββ frontend/
β βββ index.html
β βββ vite.config.js
β βββ tailwind.config.js
β βββ postcss.config.js
β βββ package.json
β β
β βββ src/
β βββ main.jsx # React entry point
β βββ App.jsx # Root layout + session state
β βββ index.css # Tailwind + custom styles
β β
β βββ components/
β β βββ ChatWindow.jsx # Main chat interface
β β βββ MessageBubble.jsx # User + AI message rendering
β β βββ Sidebar.jsx # Sessions + Memory tabs
β β βββ UploadSection.jsx # Drag-drop document upload
β β βββ MemoryPanel.jsx # Memory viewer + editor
β β βββ TypingIndicator.jsx # Animated typing dots
β β βββ ModelSelector.jsx # Ollama model picker (portal)
β β
β βββ hooks/
β β βββ useChat.js # SSE streaming hook
β β
β βββ services/
β βββ api.js # All API call functions
β
βββ screenshots/ # App screenshots
βββ requirements.txt # Python dependencies
βββ README.md # This file
```
---
# Usage Guide
## Basic Chat
Open `http://localhost:5173`
Click New Chat or type directly in the input box
Press Enter to send (`Shift+Enter` for new line)
Watch the AI stream its response in real-time
---
## Persistent Memory
The system automatically extracts and stores facts from your conversations:
```text
You: "My name is Alex and I prefer Python over JavaScript"
β Memory extracted: "User's name is Alex"
β Memory extracted: "User prefers Python over JavaScript"
β Stored in: SQLite + ChromaDB
Later...
You: "What language should I use for my next project?"
β AI retrieves memories β recommends Python with context
β Shows: π§ 2 memories badge
```
### Manually Add Memories
Click the π§ Brain icon in the top bar
Click Add Memory Manually
Enter fact + select category β Save
---
## PDF / Document Chat
Click the π Paperclip icon in the input bar
Drag & drop or click to select PDF, TXT, or MD file
Wait for `"X chunks ready"` confirmation
Ask questions about your document:
```text
You: "What is the quarterly revenue?"
β AI retrieves relevant chunks β answers from document
β Shows: π 3 chunks badge
```
---
## Combined Memory + Documents
```text
You: "Given my Python expertise, what do you think
about the tech stack in the uploaded document?"
β AI uses: memories (your Python background)
+ documents (the uploaded file context)
β Shows BOTH: π§ memories badge + π chunks badge
```
---
## Model Switching
Click the model selector (top right, shows current model)
Dropdown shows all installed Ollama models
Click any model to switch for the next message
---
# API Reference
## Chat
| Method | Endpoint | Description |
| ------ | ------------------------------ | -------------------------------- |
| POST | `/chat` | Send message, returns SSE stream |
| GET | `/chat/sessions` | List all chat sessions |
| GET | `/chat/sessions/{id}/messages` | Get session message history |
| DELETE | `/chat/sessions/{id}` | Delete session + messages |
### POST `/chat` Request Body
```json
{
"message": "What is my favorite language?",
"session_id": "uuid-here",
"model": "llama3",
"stream": true
}
```
### SSE Stream Events
```text
data: {"type": "metadata", "session_id": "...", "memories_used": 2, "docs_retrieved": 3}
data: {"type": "token", "content": "Based"}
data: {"type": "token", "content": " on"}
data: {"type": "done"}
```
## Documents
| Method | Endpoint | Description |
| ------ | ------------------------- | ------------------------- |
| POST | `/upload` | Upload + process document |
| GET | `/documents/{session_id}` | List session documents |
| DELETE | `/documents/{id}` | Delete document + vectors |
### POST `/upload` (multipart form)
```text
file:
session_id: "uuid-here"
```
---
## Memory
| Method | Endpoint | Description |
| ------ | ---------------------- | ------------------------- |
| GET | `/memory/{session_id}` | Get all session memories |
| GET | `/memory` | Get all memories (global) |
| POST | `/memory` | Add memory manually |
| DELETE | `/memory/{id}` | Delete specific memory |
### POST `/memory` Request Body
```json
{
"session_id": "uuid-here",
"fact": "User prefers dark mode editors",
"category": "preference"
}
```
---
## System
| Method | Endpoint | Description |
| ------ | --------- | ----------------------------- |
| GET | `/health` | System health + Ollama status |
| GET | `/docs` | Interactive Swagger UI |
---
# Quick Commands
```bash
# ββ Start All Services ββββββββββββββββββββββββββββββββββββββββββ
# Terminal 1: Ollama (if not running as background service)
ollama serve
# Terminal 2: Backend
cd nexus-memory/backend
source ../venv/bin/activate
python run.py
# Terminal 3: Frontend
cd nexus-memory/frontend
npm run dev
# ββ Useful Debug Commands ββββββββββββββββββββββββββββββββββββββββ
# Check health
curl -s http://localhost:8000/health | python -m json.tool
# Test chat (non-streaming)
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"message": "Hello!", "session_id": "test", "stream": false}'
# Add a memory manually
curl -X POST http://localhost:8000/memory \
-H "Content-Type: application/json" \
-d '{"session_id": "test", "fact": "I love Python", "category": "technical"}'
# View memories
curl http://localhost:8000/memory/test | python -m json.tool
# Check SQLite database
cd nexus-memory/backend
sqlite3 nexus_memory.db ".tables"
sqlite3 nexus_memory.db "SELECT fact, category FROM memory_entries;"
# Check ChromaDB collections
cd nexus-memory
source venv/bin/activate
python3 -c "
import chromadb
client = chromadb.PersistentClient(path='backend/chroma_db')
for col in client.list_collections():
print(f'{col.name}: {col.count()} vectors')
"
# ββ Reset / Clean Data βββββββββββββββββββββββββββββββββββββββββββ
# Delete all chat data (keeps code)
rm backend/nexus_memory.db
rm -rf backend/chroma_db/
rm -rf backend/uploads/*
# Full dependency reinstall
cd nexus-memory
rm -rf venv
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
---
### Key Learnings:
- RAG quality depends heavily on chunk size and overlap tuning
- Local LLM latency requires careful UX design (streaming is essential)
- Memory retrieval needs relevance thresholds to avoid noise
- Pydantic v1/v2 compatibility requires careful version pinning
- ChromaDB stacking contexts cause subtle UI z-index bugs
---
# License
```text
MIT License
Copyright (c) 2026 Nexus Memory
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
```
---
Built with β€οΈ using local AI β no cloud required
β¬ Back to Top