Intelligent AI model routing — one interface, the right model, every time.
RouteMind eliminates the decision fatigue of choosing between AI tools. Instead of manually switching between ChatGPT, Claude, Gemini, and others depending on your task, RouteMind analyses your query and automatically routes it to the most suitable model — then explains why.
- Intent Classification: Dispatches each query to the best-fit model based on its nature (e.g. Coding → GPT-4o, Research → Gemini, Document → Claude).
- Multi-Step Routing Pipeline: Real-time visual feedback for intent analysis → model comparison → model selection → response generation.
- Explainable AI Decisions: Confidence score, estimated cost, latency, and routing reason surfaced alongside every response.
- Adaptive Routing Policies: Toggle between Cost, Speed, Balanced, and Quality policies.
- Auto-Resizing Text Input: Textarea grows as you type (clamped 56px–200px), auto-focuses on load.
- File Attachments: Drag-and-drop or select documents, code files, and images (up to 20 MB). Validated file extensions: PDF, DOC/DOCX, TXT/MD, PNG/JPG/JPEG/WEBP, CSV, JSON, and common source-code extensions.
- Dynamic File Icons: Format-matched icons for attached files inside message bubbles.
- Typing Indicator: Step-by-step animated labels show which routing stage is active.
- Dark-first Theme: Glassmorphism surfaces, glowing accents, Framer Motion transitions.
- Theme Management: Light / Dark / System preference via
ThemeContext. - Global Notifications: Toast system for errors, file-validation warnings, and info messages.
- Accessible Modals: Focus trap + Escape-key dismiss on all modal overlays.
- FastAPI: Clean Python backend with health monitoring, CORS, and strict Security Headers (HSTS, Anti-Clickjacking).
- Session Memory: SQLite + SQLAlchemy database tracks conversations and persists message history.
- Long-Term Memory: Background extraction (every 10 messages) identifies durable facts and preferences, storing them in SQLite and prepending them to the system prompt.
- Context Compression: Automatic AI summarization reduces token usage for long conversations.
- Provider Adapter Pattern:
BaseProviderABC — adding a new LLM = one new file. - Rule-Based Router: Intent × Policy → model selection with automatic fallback.
- Extensible Classifier: Regex-heuristic
RuleBasedIntentClassifierwith confidence scoring.
| Layer | Choice |
|---|---|
| Frontend Framework | React 19 + Vite 8 |
| Backend Framework | FastAPI (Python 3.x) + Uvicorn |
| Database & ORM | SQLite + SQLAlchemy 2.0 |
| Styling | Tailwind CSS v4 |
| Routing | React Router v7 |
| Animations | Framer Motion |
| Markdown Rendering | react-markdown + react-syntax-highlighter + remark-gfm |
| Icons | Lucide React |
| Unit Testing | Vitest + React Testing Library + JSDOM |
| CI/CD | GitHub Actions (ci.yml) |
| Deployment Routing | Vercel SPA Rewrites (vercel.json) |
RouteMind/
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions CI workflow (lint → test → build)
├── backend/ # Python FastAPI Backend
│ ├── app/
│ │ ├── classifier/
│ │ │ └── intent_classifier.py # BaseIntentClassifier + RuleBasedIntentClassifier
│ │ ├── config.py # Pydantic Settings + dotenv loader
│ │ ├── database.py # SQLite engine and sessionmaker
│ │ ├── models.py # SQLAlchemy ChatSession, ChatMessage, and Memory models
│ │ ├── main.py # CORS, logging, security headers, routers
│ │ ├── providers/
│ │ │ ├── base.py # Abstract BaseProvider + exception hierarchy
│ │ │ ├── openai_provider.py # Live OpenAI SDK integration
│ │ │ ├── claude_provider.py # ⚠️ Placeholder — NotImplementedError
│ │ │ └── gemini_provider.py # ✅ Live Google GenAI integration
│ │ ├── routes/
│ │ │ ├── chat.py # POST /chat — validates, classifies, routes, calls provider
│ │ │ ├── health.py # GET / and GET /health
│ │ │ └── memories.py # GET, PUT, DELETE for Long-Term Memory
│ │ ├── schemas/
│ │ │ └── chat.py # ChatRequest + ChatResponse (nested: response/routing/metadata)
│ │ └── services/
│ │ ├── chat_session_service.py # CRUD operations for chat memory
│ │ ├── conversation_service.py # Fetches history + appends context summaries
│ │ ├── summary_service.py # LLM context compression
│ │ ├── memory_service.py # CRUD & exact-match deduplication for long-term memory
│ │ ├── memory_extractor_service.py # Background LLM logic to extract facts/preferences
│ │ ├── provider_manager.py # Lazy-loading provider registry + health cache
│ │ └── router.py # LLMRouter: intent × policy → RoutingDecision
│ ├── routemind.db # Local SQLite database (auto-generated)
│ ├── .env # Local environment variables (never commit secrets)
│ ├── requirements.txt # Python dependencies
│ └── tests/ # Pytest suite
│ ├── test_classifier.py
│ ├── test_router.py
│ ├── test_provider_manager.py
│ └── test_chat_endpoint.py
├── src/ # React Frontend
│ ├── components/
│ │ ├── ChatInput.jsx
│ │ ├── ChatMessage.jsx
│ │ ├── RoutingCard.jsx
│ │ ├── Sidebar.jsx
│ │ ├── SettingsModal.jsx
│ │ ├── TelemetryModal.jsx
│ │ ├── MemoryModal.jsx
│ │ ├── TypingIndicator.jsx
│ │ ├── Tooltip.jsx
│ │ ├── Navbar.jsx
│ │ ├── Footer.jsx
│ │ └── AuthenticationComingSoonModal.jsx
│ ├── context/
│ │ ├── ThemeContext.jsx
│ │ └── ToastContext.jsx
│ ├── data/
│ │ └── mockData.js
│ ├── pages/
│ │ ├── Chat.jsx
│ │ ├── Home.jsx
│ │ ├── Benefits.jsx
│ │ └── Documentation.jsx
│ ├── services/
│ │ ├── api.js # Fetch wrapper with AbortController timeout
│ │ └── chatService.js # POST /chat + GET /health mappings
│ ├── utils/
│ │ ├── mockRouter.js
│ │ ├── fileHelpers.jsx
│ │ └── animations.js
│ ├── test/
│ │ ├── mockRouter.test.js
│ │ └── setup.js
│ ├── App.jsx
│ ├── main.jsx
│ └── index.css
├── index.html
├── vercel.json
├── vite.config.js
├── eslint.config.js
├── package.json
├── AGENT_CONTEXT.md
└── README.md
Requires Node.js v18+ and Python v3.9+.
# Install dependencies
npm install # or: pnpm install
# Start dev server (http://localhost:5173)
npm run dev # or: pnpm dev
# Production build
npm run build # or: pnpm build
npm run preview # or: pnpm preview
# Lint + test
npm run lint # ESLint check
npm run test:run # Vitest single pass
npm run test # Vitest watch modecd backend
# Create and activate virtual environment
python -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt
# Run tests
python -m pytest tests/ -v
# Start API server (http://127.0.0.1:8000)
uvicorn app.main:app --reloadInteractive API docs available at http://127.0.0.1:8000/docs.
Create backend/.env with:
# Required for any real LLM calls
OPENAI_API_KEY=sk-...
# Required once Claude/Gemini providers are implemented
ANTHROPIC_API_KEY=sk-ant-...
GEMINI_API_KEY=AIza...
# Required for NVIDIA NIM integration
NVIDIA_NIM_API_KEY=nvapi-...
NVIDIA_NIM_BASE_URL="https://integrate.api.nvidia.com/v1"
# CORS — add your Vercel deployment URL here
CORS_ORIGINS=["http://localhost:5173","http://localhost:3000","https://your-app.vercel.app"]
ENVIRONMENT=developmentRequest:
{
"message": "Write a fast Rust HTTP server using actix-web",
"conversation_id": "conv_8f3a9e2d",
"routing_policy": "quality",
"attachments": ["server_design.pdf"],
"user_id": "usr_9x12bc8f",
"timestamp": "2026-06-26T07:00:00Z"
}routing_policy must be one of: balanced | speed | cost | quality
Response:
{
"response": {
"content": "Here is a minimal actix-web server...",
"conversation_id": "conv_8f3a9e2d",
"attachments": ["server_design.pdf"]
},
"routing": {
"intent": "coding",
"provider": "openai",
"selected_model": "gpt-4o",
"routing_policy": "quality",
"confidence": 99.0,
"reason": "Routed to GPT-4o for high-quality reasoning matching 'coding' intent under the 'quality' policy.",
"estimated_cost": 0.00165,
"processing_time_ms": 3250
},
"metadata": {
"request_id": "req_84d72f9a1",
"timestamp": "2026-06-26T07:00:04.123456Z",
"status": "success",
"api_version": "1.0.0"
}
}Returns service status and registered provider list.
| Intent | balanced / cost |
speed |
quality |
Preferred Order (Failover List) |
|---|---|---|---|---|
coding |
openai / gpt-4o-mini |
openai / gpt-4o-mini |
openai / gpt-4o |
openai → groq → gemini → nvidia |
writing |
claude / claude-3-5-sonnet |
claude / claude-3-5-haiku |
claude / claude-3-5-sonnet |
claude → gemini → openai → nvidia |
research |
gemini / gemini-1.5-flash |
gemini / gemini-1.5-flash |
gemini / gemini-1.5-pro |
gemini → openai → claude → nvidia |
document |
gemini / gemini-1.5-flash |
gemini / gemini-1.5-flash |
gemini / gemini-1.5-pro |
gemini → openai → claude → nvidia |
reasoning |
nvidia / meta/llama-3.1-405b-instruct |
nvidia / meta/llama-3.1-405b-instruct |
nvidia / meta/llama-3.1-405b-instruct |
nvidia → gemini → groq → openai |
analysis |
nvidia / meta/llama-3.1-405b-instruct |
nvidia / meta/llama-3.1-405b-instruct |
nvidia / meta/llama-3.1-405b-instruct |
nvidia → gemini → groq → openai |
planning |
nvidia / meta/llama-3.1-405b-instruct |
nvidia / meta/llama-3.1-405b-instruct |
nvidia / meta/llama-3.1-405b-instruct |
nvidia → gemini → groq → openai |
strategy |
nvidia / meta/llama-3.1-405b-instruct |
nvidia / meta/llama-3.1-405b-instruct |
nvidia / meta/llama-3.1-405b-instruct |
nvidia → gemini → groq → openai |
general |
gemini / gemini-1.5-flash |
gemini / gemini-1.5-flash |
gemini / gemini-1.5-pro |
gemini → nvidia → groq → openai |
⚠️ Reasoning-related intents (reasoning,analysis,planning,strategy) automatically override default policy models to always route to the premium high-capacity models (e.g.,meta/llama-3.1-405b-instructon NVIDIA NIM,gemini-1.5-proon Gemini, etc.) for complex logic evaluation.
If the selected provider is unavailable, RouteMind executes a 3-provider failover chain. The first healthy provider in the sequence is invoked:
- NVIDIA Primary:
nvidia→gemini→groq - Gemini Primary:
gemini→nvidia→groq - Groq Primary:
groq→nvidia→gemini
| # | Severity | File | Description |
|---|---|---|---|
| 1 | 🔴 High | claude_provider.py |
All methods raise NotImplementedError — no live Claude calls possible |
| 2 | 🔴 High | config.py |
ANTHROPIC_API_KEY not declared in Settings model |
| 3 | 🟡 Medium | routes/chat.py |
Uses list_registered_providers() instead of get_available_providers() — dead providers (Claude) treated as available at routing time |
| 4 | 🟡 Medium | config.py |
CORS_ORIGINS default missing localhost:5173 and production Vercel URL |
| 7 | 🟡 Medium | services/api.js |
15 s AbortController timeout too short for GPT-4o / Gemini Pro on long responses |
| 8 | 🟢 Low | intent_classifier.py |
Intent tie-breaking is non-deterministic (dict key order) |
| 9 | 🟢 Low | router.py |
balanced and cost policies resolve to identical models — no cost-weighted scoring |
| 10 | 🟢 Low | routes/chat.py |
Flat tokens × 0.000015 cost formula regardless of provider or model tier |
| 11 | 🟢 Low | ChatInput.jsx |
Helper text uses text-[11px] — below the 12 px accessibility floor |
| 12 | 🟢 Low | Tooltip.jsx |
Hover-only; not keyboard or screen-reader accessible |
| 13 | 🟢 Low | Chat.jsx |
handleNewChat in header is an inline lambda instead of calling the shared handler |
| 14 | 🟢 Low | chatService.js |
No SSE streaming — full response is buffered before rendering |
Every push and pull request to main triggers the GitHub Actions workflow (ci.yml):
- Lint — ESLint with React rules
- Test — Vitest unit tests (
pnpm test:run) - Build — Vite production build
- Frontend: Vercel.
vercel.jsonrewrites all routes toindex.html(standard SPA pattern). Push tomainauto-deploys. - Backend: deployed. Planned target: Render (FastAPI + Uvicorn).