A chat-assistant website that helps Buddhist content creators make short videos for The Bodhisattva Challenge — a 365-day journey through Śāntideva's Bodhicharyavatara.
The creator picks a day; the app pulls that day's verses, plan, and classical commentary from a local clone of the source repo, gives a simple plain-language summary of the verse (in English or Hindi), suggests the video ideas that day's material can support, and generates either a ready-to-read script or a shot-by-shot video structure. Results can be regenerated, refined by chatting, and (for scripts) turned into narrated audio.
- Frontend: React (Vite) — guided chat UI.
- Backend: Django + Django REST Framework.
- LLM + TTS: Google Gemini (one API key for both text and audio).
- Source content: a local clone of the
bodhisattvacharyavatara-railsrepo.
frontend (React/Vite) ──HTTP──> backend (Django REST) ──reads──> rails repo (markdown)
│
└──> Gemini API (summary · script · structure · audio)
The backend reads the day-plan and per-verse commentary files directly from disk (no database for app data — generated content is ephemeral and flow state lives in the browser). It runs one Gemini call to decide which ideas a day supports, and fills editable prompt templates ("skills") to generate everything else.
- Pick a day (1–365).
- See the day — a Day / Chapter / Verses / Date strip plus today's verse text.
- Verse summary — choose English or हिन्दी Hindi for a few short, plain-language bullet points explaining the verse; optionally get the other language too.
- Pick a video idea (see below).
- Choose the output — 📝 Video script (spoken script) or 🎬 Video structure (a storyboard: timed beats with on-screen visuals + voiceover).
- Pick a duration — 30 / 45 / 60 / 90 seconds.
- Get the result, then ↻ Regenerate for a fresh take, or chat to refine it ("make the hook punchier", "shorten the opening"). Scripts can also be turned into narrated audio.
| Idea | What it does | When offered |
|---|---|---|
| Concept | Explains the core idea of the verse | always |
| Challenge / Practice | Frames today's practice as a doable dare | always |
| Creative | A secular, universal video about the lesson behind the verse — no scripture or Buddhist references, crisp one-liners, for everyone | always |
| Testimony | Shapes the creator's own notes into a first-person reflection | always |
| Story | Tells a story/parable from the source | when the material contains one |
| Extra info / fun fact | A surprising detail from the texts | when the material contains one |
make install # backend venv + deps, frontend npm install
make dev # runs backend (:8001) and frontend (:5173) together; Ctrl+C stops bothcd backend
python3 -m venv venv
venv/bin/pip install -r requirements.txt
cp .env.example .env # then edit .envSet in backend/.env:
RAILS_REPO_PATH— absolute path to your local clone ofbodhisattvacharyavatara-rails.GEMINI_API_KEY— your Google Gemini API key (summary, script, structure, audio).
venv/bin/python manage.py migrate # built-in tables only
venv/bin/python manage.py check_content # verify it can read the rails repo
venv/bin/python manage.py runserver 0.0.0.0:8001cd frontend
npm install
cp .env.example .env # VITE_API_BASE_URL defaults to http://localhost:8001
npm run dev # http://localhost:5173Open http://localhost:5173 and start with a day number (e.g. 5).
Without a
GEMINI_API_KEY, day loading still works and idea availability falls back to a keyword heuristic — but the verse summary, script, structure, and audio all require Gemini and return a clear "not configured" message.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/health/ |
status + whether Gemini is configured |
| GET | /api/days/<n>/ |
verses, chapter, date, verse text, available ideas |
| POST | /api/verse-summary/ |
{day, language} → {points} — language is english or hindi |
| POST | /api/script/ |
{day, ideaKey, durationSeconds, creatorNotes?, feedback?, previous?} → {script} |
| POST | /api/structure/ |
{day, ideaKey, durationSeconds, creatorNotes?, feedback?, previous?} → {structure} |
| POST | /api/audio/ |
{script, voice?} → {audioUrl} |
feedback + previous power the chat-to-refine step (revise the prior result);
omit them for a fresh generation.
Every generation is driven by an editable markdown template in
backend/assistant/prompts/ — tune tone, structure, and rules without touching
code (changes take effect on the next request, no restart needed):
| File | Role |
|---|---|
_shared.md |
Shared, source-faithful context + voice rules for scripts |
concept.md, practice.md, testimony.md, story.md, extra_info.md |
Per-idea script angles |
creative.md |
Self-contained Creative script (secular, no source references) |
verse_summary.md |
Simple plain-language verse summary (English/Hindi) |
structure.md |
Source-faithful video storyboard |
structure_creative.md |
Secular, universal storyboard for the Creative idea |
assistant.md |
Greeting / persona |
- Rate limiting — the Gemini-backed endpoints are throttled (default
20/minfor generation,60/minelsewhere; tune viaTHROTTLE_GENERATE/THROTTLE_ANONin.env) to protect the API budget. - Input caps —
creatorNotes,script, andfeedbackare length-capped. - Production guards — with
ENV=production, the app refuses to start ifDEBUGis on orDJANGO_SECRET_KEYis left at the insecure default. - Caching — day content and idea analysis are cached in memory; identical audio requests reuse the existing file. Verse summaries are cached in production and regenerated live in local dev.
See DEPLOY.md for EC2 (gunicorn + nginx).