Go backend for Krishna Saarthi, a Bhagavad Gita-inspired philosophical guide powered by Sarvam AI.
- Go — HTTP server (
net/http) - Sarvam AI (
sarvam-105b) — LLM for response generation - Supermemory — Long-term memory per user across sessions
- MongoDB Atlas — Persists users, sessions, and messages
- Clerk — JWT-based authentication
- Pinecone — Vector database for Gita verse retrieval (RAG)
- Ollama (
nomic-embed-text) — Local embeddings for RAG queries (768 dimensions)
backend/
├── cmd/
│ ├── server/main.go # Entry point, route registration
│ └── ingest/main.go # One-time script to ingest Gita verses into Pinecone
├── constants/ # System prompt
├── data/
│ ├── verse.json # 701 Gita verses (Sanskrit + transliteration)
│ ├── translation.json # English translations (Swami Gambirananda)
│ └── chapters.json # 18 chapter summaries
├── internal/
│ ├── db/mongo.go # MongoDB connection
│ ├── handlers/
│ │ ├── chat.go # POST /chat handler
│ │ └── health.go # GET /health handler
│ ├── models/ # Request/response structs
│ ├── services/
│ │ ├── sarvam.go # Sarvam AI client
│ │ ├── supermemory.go # Supermemory client
│ │ ├── chat_store.go # MongoDB read/write logic
│ │ └── rag.go # Pinecone + Ollama RAG service
│ └── session/ # In-memory session store (legacy)
└── middlewares/
├── auth.go # Clerk JWT verification
└── cors_middleware.go # CORS headers
POST /chat
→ CORS middleware
→ Auth middleware (verify Clerk JWT, extract userID)
→ Search Supermemory for relevant long-term user context
→ Embed user message via Ollama (nomic-embed-text)
→ Query Pinecone for top 3 relevant Gita verses (RAG)
→ Load last 10 messages for session from MongoDB
→ Build prompt: system + memory context + verse context + history
→ Call Sarvam AI
→ Save user + assistant messages to MongoDB
→ Store exchange in Supermemory (async goroutine)
→ Return response
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /health |
No | Health check |
| POST | /chat |
Yes | Send a message |
| POST | /auth/sync |
Yes | Upsert user on first sign-in |
| GET | /sessions |
Yes | List all sessions for a user |
| GET | /sessions/{id}/messages |
Yes | Load messages for a session |
| Header | Required | Description |
|---|---|---|
X-Session-ID |
Yes | UUID per browser tab/session |
Authorization |
Yes | Bearer <clerk_jwt> |
Create a .env file in the project root:
SARVAM_API_KEY=
SUPERMEMORY_API_KEY=
CLERK_SECRET_KEY=sk_test_
MONGO_DB_URI=mongodb+srv://user:password@cluster.mongodb.net/krishna-saarthi
PINECONE_API_KEY=
PINECONE_INDEX_URL=https://bhagavad-gita-xxxx.svc.us-east-1-aws.pinecone.io
OLLAMA_URL=http://localhost:11434# Install dependencies
go mod tidy
# Start Ollama (required for RAG embeddings)
ollama serve
ollama pull nomic-embed-text
# Run the server
go run cmd/server/main.goServer starts on :8080.
The ingestion script embeds all 701 verses + 18 chapter summaries into Pinecone. This is a one-time setup:
# Copy data files to backend/data/
# Then run:
go run cmd/ingest/main.goThis ingests 719 vectors total (701 verses + 18 chapters) using nomic-embed-text (768 dimensions) via Ollama. Each verse is stored with its translation (Swami Gambirananda), transliteration, word meanings, chapter number, and verse reference (e.g. BG 2.47).
At query time, the user's message is embedded with the same model and the top 3 most semantically similar verses are retrieved and injected into the system prompt.
Krishna Saarthi uses a three-layer memory system:
| Layer | Storage | Scope | Purpose |
|---|---|---|---|
| Short-term | MongoDB | Per session (last 10 messages) | In-conversation context |
| Long-term | Supermemory | Per user (across all sessions) | User identity, patterns, history |
| Knowledge | Pinecone | Global (all users) | Verified Gita verses for RAG |
| Collection | Description |
|---|---|
users |
Created on first sign-in via /auth/sync |
sessions |
One per browser session, keyed by sessionId |
messages |
All chat messages with userId, sessionId, role, content |
- Each browser tab generates a unique
X-Session-ID(UUID) - The active session ID is persisted in
localStorageso refreshing restores the last conversation - Draft input is also persisted in
localStorageand restored on refresh - Past sessions are listed in the sidebar and fully reloadable
- Add the handler in
internal/handlers/ - Register it in
cmd/server/main.go - Wrap with
AuthMiddlewareif it requires authentication - Add any new request/response structs to
internal/models/