
RootsAI
Cognitive diagnostic engine that finds where learning actually broke down.

Overview • How It Works • Architecture • Quick Start • API Reference
Repository: https://github.com/bokaif/RootsAI
Overview
When a student struggles with a topic in Class 9, the real problem is often something from Class 7 or 8 that was never fully understood. Most learning tools don't go looking for that. RootsAI does.
The system takes a student's problem, maps it onto an authored curriculum graph, traverses prerequisites to build a "Concept MRI," diagnoses knowledge gaps through targeted quizzes, and guides the student through a gamified remediation path — ending with a Feynman-style verification where the student teaches the concept back to the AI.
Core principles:
- The graph is the source of truth, not the LLM. Every AI output is validated against the real curriculum graph. The LLM maps problems to existing nodes — it never invents curriculum.
- Deterministic where it matters. Same problem → same concept map → same prerequisite tree → same quiz. Reproducible diagnostics, every time.
- Mastery is earned, not assumed. Students prove understanding by re-answering missed questions and explaining concepts back (Feynman technique).
How It Works
Student submits problem (text or photo)
│
▼
┌─────────┐ Zod-validated against
│ Map │───▶ real graph slugs
└────┬────┘ (hallucinated slugs rejected)
│
▼
┌──────────┐ Deterministic BFS
│ Traverse │───▶ prerequisite subtree
└────┬─────┘ ("Concept MRI")
│
▼
┌────────┐ Authored questions verbatim,
│ Quiz │────▶ or generate-once + cache
└────┬───┘ in Firestore
│
▼
┌──────────┐ Duolingo-style serpentine path,
│ Learn │───▶ foundational-first ordering,
└────┬─────┘ sequential unlock
│
▼
┌──────────┐ Student teaches concept back
│ Verify │───▶ to the AI (Feynman technique)
└──────────┘
Two modes
- Legacy (demo): Hardcoded NCTB Class 9 Physics graph — mechanics vertical with 19 authored nodes and hand-written quiz questions.
- Classroom: Teachers upload materials → AI extracts a concept graph → students run diagnostics against that graph. Works with any subject.
Features
Diagnostic Engine
- GraphRAG mapping: LLM routes problems to existing curriculum nodes with Zod hard-validation — no hallucinated concepts.
- Concept MRI: Deterministic BFS traversal builds the same prerequisite tree for the same root, every time.
- Hybrid quizzes: Authored questions used verbatim; unauthored nodes get AI-generated questions cached in Firestore.
- Adaptive remediation: All gaps recorded and ordered foundational-first. Lesson plans are deterministically structured from the graph.
Learning Path
- Serpentine path: Duolingo-style winding path of medallion nodes with strict sequential unlock.
- Earned mastery: Each gap node reuses the exact MCQ the student missed (options shuffled). Answer correctly → mastered.
- Feynman verification: Students teach the concept back to the AI via voice or text+photo before moving on.
- Gamification: Progress bar, XP system (+10/mastered), celebration animations (reduced-motion guarded).
Classroom System
- Teacher workflows: Create classrooms, upload materials (PDF/syllabus/notes/textbook), manage students.
- Dynamic graph extraction: AI extracts concept dependency graphs from uploaded materials for any subject.
- RAG-powered tutoring: LangGraph agent retrieves from teacher's knowledge base — never fabricates content.
- Analytics: Teacher dashboard with student progress and engagement tracking.
Additional
- Multimodal input: Students can photograph problems (camera/upload) — image is sent alongside text to the diagnostic engine.
- Voice transcription: Audio input transcribed via Gemini for Feynman verification.
- Real-time chat: Contextual AI tutor grounded in classroom materials with citation support.
- Role-based access: Firebase Auth with student/teacher roles and onboarding flow.
Architecture
| Layer | Stack | Responsibilities |
|---|---|---|
| Frontend | Next.js 16, React 18, Chakra UI, Tailwind | Role-based app shell, diagnostic flow, serpentine learning path |
| Diagnostic Engine | Custom pipeline (map → traverse → quiz) | Problem mapping, prerequisite traversal, quiz resolution |
| Tutor Agent | LangGraph + LangChain | Stateful multi-tool agent: RAG retrieval, mastery check, grounded response |
| Curriculum Graph | Authored graph + Neo4j (optional) | Source-of-truth concept dependencies, BFS traversal |
| RAG Pipeline | LangChain TextSplitters + Gemini Embeddings | Chunk materials, embed, store in Supabase pgvector, HNSW cosine search |
| LLM Provider | Gemini (primary) + fallback chain | Structured JSON generation with retry + model-chain fallback |
| Auth / Data | Firebase Auth + Firestore | Identity, roles, diagnoses, classrooms, quiz cache, progress |
| File Storage | Supabase Storage | Problem photos, Feynman verification uploads |
Project Structure
roots-ai/
├── src/
│ ├── app/
│ │ ├── (auth)/ # Auth pages (signin, signup, onboarding, logout)
│ │ ├── api/
│ │ │ ├── diagnoses/ # Diagnostic CRUD, quiz, plan, chat, feynman, progress
│ │ │ ├── classrooms/ # Classroom CRUD, materials, graph extraction, analytics
│ │ │ ├── curriculum/seed/ # Graph seeding endpoint
│ │ │ ├── auth/ # Token refresh, expo web success
│ │ │ ├── transcribe/ # Audio transcription
│ │ │ ├── upload/ # File upload
│ │ │ └── profile/ # User profile
│ │ ├── docs/ # Project documentation pages
│ │ ├── settings/ # Settings page
│ │ ├── roots-ai.tsx # Main app shell (screen router)
│ │ └── globals.css # Global styles + animations
│ ├── components/
│ │ ├── roots/
│ │ │ ├── screens/ # ScanScreen, QuizScreen, GraphScreen, LearnScreen,
│ │ │ │ # VerifyScreen, DashboardScreen, SettingsScreen, etc.
│ │ │ ├── learn/serpentine.jsx # Serpentine learning path primitives
│ │ │ ├── Composer.jsx # Message composer with voice/image
│ │ │ ├── ChatPanel.jsx # Contextual AI chat panel
│ │ │ ├── Sidebar.jsx # Navigation sidebar
│ │ │ └── primitives.jsx # Card, Button, Accordion components
│ │ └── docs/ # Documentation components
│ ├── lib/
│ │ ├── engine/ # Core diagnostic engine
│ │ │ ├── index.ts # runDiagnosis() orchestrator
│ │ │ ├── map.ts # Problem → node mapper (GraphRAG + Zod validation)
│ │ │ ├── traverse.ts # Deterministic BFS prerequisite traversal
│ │ │ └── quiz.ts # Hybrid quiz resolver (authored + cached generation)
│ │ ├── curriculum/ # Curriculum graph system
│ │ │ ├── graph.ts # Authored NCTB Physics graph (19 nodes, mechanics vertical)
│ │ │ ├── store.ts # GraphStore abstraction (Dynamic, InMemory, Neo4j)
│ │ │ ├── types.ts # ConceptNode, Classroom, DiagnosisResult types
│ │ │ ├── neo4j.ts # Neo4j driver + config
│ │ │ ├── seed.ts # Graph seeding logic
│ │ │ └── extract.ts # AI concept extraction from materials
│ │ ├── agents/tutor.ts # LangGraph tutor agent (RAG + mastery + grounded chat)
│ │ ├── rag/index.ts # RAG pipeline (chunk, embed, store, retrieve)
│ │ ├── gemini.ts # Gemini API client with retry + model-chain fallback
│ │ ├── firebase.ts # Firebase client SDK
│ │ ├── firebase-admin.ts # Firebase Admin SDK
│ │ └── auth.ts # Auth utilities
│ └── utils/ # React hooks (useAuth, useProfile, useUpload, etc.)
├── .env.example # Environment variable template
├── package.json
├── next.config.mjs
├── tailwind.config.js
└── tsconfig.json
Quick Start
Prerequisites
- Node.js
>= 18 - pnpm
>= 8 - Firebase project (Auth + Firestore)
- Gemini API key
IMPORTANT
The app requires Firebase Auth and Firestore configured. Gemini API key is required for all AI features.
1. Clone and install
git clone https://github.com/bokaif/RootsAI.git
cd RootsAI
pnpm install
2. Configure environment
cp .env.example .env.local
Fill in values (see Environment Variables below).
3. Run
pnpm dev
App runs at http://localhost:4000.
4. First-run checklist
- Sign up and pick a role (student or teacher).
- As a student: type or photograph a physics problem → run diagnosis → take quiz → follow learning path → verify with Feynman.
- As a teacher: create a classroom → upload materials → view student analytics.
Environment Variables
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_FIREBASE_API_KEY | Yes | Firebase client API key |
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN | Yes | Firebase auth domain |
NEXT_PUBLIC_FIREBASE_PROJECT_ID | Yes | Firebase project ID |
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET | Yes | Firebase storage bucket |
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID | Yes | Firebase messaging sender ID |
NEXT_PUBLIC_FIREBASE_APP_ID | Yes | Firebase app ID |
AUTH_SECRET | Yes | Auth session secret |
GEMINI_API_KEY | Yes | Gemini API key for all AI features |
SUPABASE_URL | Yes | Supabase project URL (for file storage + RAG vectors) |
SUPABASE_SERVICE_ROLE_KEY | Yes | Supabase service role key |
SUPABASE_STORAGE_BUCKET | Optional | Storage bucket name (default: uploads) |
NEO4J_URI | Optional | Neo4j/Aura URI (falls back to in-memory graph if unset) |
NEO4J_USERNAME | Optional | Neo4j username |
NEO4J_PASSWORD | Optional | Neo4j password |
SEED_SECRET | Optional | Shared secret for POST /api/curriculum/seed |
API Reference
Diagnoses
| Method | Route | Purpose |
|---|---|---|
POST | /api/diagnoses | Create new diagnosis from problem text/image |
GET | /api/diagnoses/[id] | Get diagnosis details |
GET | /api/diagnoses/[id]/quiz | Get quiz questions for diagnosis |
POST | /api/diagnoses/[id]/evaluate | Submit quiz answers, compute gaps |
POST | /api/diagnoses/[id]/plan | Generate adaptive lesson plan |
POST | /api/diagnoses/[id]/chat | Contextual AI chat within diagnosis |
POST | /api/diagnoses/[id]/feynman | Submit Feynman verification (voice/text+photo) |
GET/POST | /api/diagnoses/[id]/progress | Get/update learning path progress |
GET | /api/diagnoses/[id]/hint | Get hint for current concept |
GET | /api/diagnoses/[id]/learn | Get learning content |
Classrooms
| Method | Route | Purpose |
|---|---|---|
POST | /api/classrooms | Create classroom (teacher) |
GET | /api/classrooms/[id] | Get classroom details |
POST | /api/classrooms/[id]/join | Join classroom (student) |
POST | /api/classrooms/join | Join by classroom code |
POST | /api/classrooms/[id]/materials | Upload material |
DELETE | /api/classrooms/[id]/materials/[materialId] | Delete material |
POST | /api/classrooms/[id]/extract | Extract concept graph from materials |
GET | /api/classrooms/[id]/graph | Get classroom concept graph |
GET | /api/classrooms/[id]/analytics | Teacher analytics |
Other
| Method | Route | Purpose |
|---|---|---|
POST | /api/transcribe | Transcribe audio to text |
POST | /api/upload | Upload file to Supabase Storage |
GET/PUT | /api/profile | User profile |
POST | /api/curriculum/seed | Seed Neo4j from authored graph (requires SEED_SECRET) |
Technical Notes
- Graph validation is hard, not soft. The mapper returns a node slug; Zod validates it against real slugs. A hallucinated slug throws
OutOfScopeError, never passes through. - Gemini model chain:
gemini-2.5-flash→gemini-2.0-flash→gemini-flash-latest, with per-model retry on transient errors (429/5xx). - Quiz caching: Generated questions are cached in Firestore
quiz_cachecollection keyed by node ID. After first generation, a node's quiz is deterministic. - Learning path ordering: Friction nodes ordered by graph
depthDESC (foundational-first), tie-broken by node ID — same invariant used across quiz ordering, lesson plans, and learning path. - Serpentine geometry is measurement-free: parity-based left/right lanes with percentage-based SVG connectors. No ResizeObserver needed.
- Neo4j is optional. Without
NEO4J_URI, the engine uses the in-memory authored graph. Both paths produce identical traversals for the same root.
TIP
For the demo, the authored NCTB Physics graph covers the mechanics vertical (measurement → motion → force → work/power/energy, including conservation of energy). Other chapters are scaffolded as stubs.
The Infinity AI BuildFest
Built for The Infinity AI BuildFest organized by CloudCamp Bangladesh. The idea: when a student struggles with a Class 9 topic, the real gap is often something from Class 7 or 8 that was never fully understood. RootsAI goes looking for that root cause.
Team
- @bokaif (Badruddoza Kaif)
- @MrDuck04 (Abror Mahir)
- @mdnaimur0 (Md. Naimur Rahman)
- @Moraladnan (Md. Adnan Arefin Ratul)