Skip to content

Repository files navigation

Kalapatha API Stateful RAG Narrative Engine

The AI backend powering Kalapatha an interactive storytelling system where every player choice reshapes the world's memory.

· Python 3.11 · FastAPI · ChromaDB · Groq (Llama 3.3 70B) · XTTS v2 · Whisper

Frontend repo: kalapatha-ui →


What This Is

A production-structured FastAPI backend that orchestrates five AI systems simultaneously a large language model for narrative generation, a 3-layer RAG memory engine with a custom retrieval algorithm, local speech-to-text, voice-cloned text-to-speech, and AI image generation into a coherent real-time interactive fiction experience.

The core research contribution is Narrative Relevance Score (NRS): a custom retrieval algorithm that extends standard RAG with narrative-specific signals, producing measurably more coherent long-form story generation than cosine similarity alone.


The Research Contribution NRS

Standard RAG retrieves documents by cosine similarity to the current query. For narrative generation this is insufficient: a beat where the player betrayed an ally is narratively more important than a beat where they observed the weather, even if both are semantically close to the current query.

NRS adds two narrative-specific signals on top of cosine similarity:

NRS(d, q) = α · sim(d, q) + β · |Δc(d)| + γ · r(d, t)
Term Meaning
sim(d, q) Cosine similarity standard dense retrieval
|Δc(d)| Absolute consequence delta how pivotal was this beat? Betrayals and sacrifices score high; routine description scores low
r(d, t) Recency weight exponential decay exp(-λ · (t - beat_num)) so distant pivotal beats can still outrank recent mundane ones

Default weights α=0.55, β=0.30, γ=0.15 were tuned empirically. The system supports 4 ablation conditions for quantitative comparison in the research paper:

Condition α β γ Description
BASELINE 1.00 0.00 0.00 Vanilla RAG cosine only
NRS_NO_REC 0.60 0.40 0.00 NRS without recency term
NRS_NO_CON 0.70 0.00 0.30 NRS without consequence term
NRS_FULL 0.55 0.30 0.15 Proposed system

System Architecture

┌─────────────────────────────────────────────────────────────┐
│                    FastAPI Application                       │
│                                                             │
│  ┌─────────────────┐   ┌─────────────────────────────────┐ │
│  │ Narrative Engine │   │       RAG Engine (3-Layer)      │ │
│  │                 │   │                                 │ │
│  │ Groq            │   │ L1: World Lore (genre bible)    │ │
│  │ Llama 3.3 70B   │◄──│ L2: Session Memory  NRS-ranked │ │
│  │ ~400 tok/sec    │   │ L3: Cross-Session World Memory  │ │
│  │                 │   │                                 │ │
│  │ 15 beats/story  │   │ ChromaDB · all-MiniLM-L6-v2    │ │
│  └─────────────────┘   └─────────────────────────────────┘ │
│                                                             │
│  ┌──────────────┐ ┌─────────────────┐ ┌─────────────────┐  │
│  │     STT      │ │       TTS       │ │     Images      │  │
│  │ Whisper base │ │   XTTS v2       │ │ HF FLUX.1-      │  │
│  │ local, no    │ │ voice cloning   │ │ schnell         │  │
│  │ API needed   │ │ SSE streaming   │ │ location-cached │  │
│  └──────────────┘ └─────────────────┘ └─────────────────┘  │
└─────────────────────────────────────────────────────────────┘

Project Structure

kalapatha-api/
├── main.py                     ← App init, CORS, lifespan, session routes
├── image_router.py             ← HF FLUX.1-schnell image generation
├── requirements.txt
├── test_backend.py             ← Integration test suite (47/51 passing)
│
├── models/
│   └── schemas.py              ← Pydantic models: Beat, Session, Ending, etc.
│
├── narrative/
│   ├── engine.py               ← Core generation loop, beat processing, JSON parsing
│   ├── prompts.py              ← System + user prompt builders per genre
│   └── genre_configs.py        ← Per-genre tone, visual palette, ending types
│
├── rag/
│   ├── nrs.py                  ← NRS formula, ablation weights, ScoredBeat ⭐
│   ├── engine.py               ← 3-layer context retrieval orchestrator
│   ├── session_memory.py       ← Per-session ChromaDB vector store
│   ├── cross_session.py        ← World memory  persists across all players
│   └── lore_store.py           ← Static genre lore seeding
│
├── stt/
│   ├── whisper_engine.py       ← Local Whisper transcription
│   ├── audio_validator.py      ← Format + duration validation
│   ├── voice_preprocessor.py  ← Normalise voice samples for XTTS cloning
│   └── router.py               ← STT API routes
│
├── tts/
│   ├── xtts_engine.py          ← XTTS v2 synthesis + sentence streaming
│   ├── voice_manager.py        ← Voice manifest + sample management
│   ├── audio_cache.py          ← WAV cache  same text = instant replay
│   └── router.py               ← TTS API routes + SSE stream endpoint
│
└── eval/
    ├── harness.py              ← Automated 50-story generation + NRS logging
    └── test_nrs.py             ← NRS unit tests  all formula assertions

API Reference

Session

Method Route Description
POST /session/start Start session, returns opening beat
POST /session/beat Submit player input, get next beat
GET /session/{id}/state Full session state
GET /session/{id}/ending Structured ending (after beat 15)
POST /session/{id}/finalize Promote session events to world memory

Speech

Method Route Description
POST /stt/transcribe Transcribe audio blob via Whisper
POST /stt/transcribe-and-advance Voice → story beat in one round-trip
POST /tts/synthesise Synthesise text → WAV (cached)
GET /tts/stream/{session_id}/{beat} SSE stream sentence-by-sentence audio

Other

Method Route Description
POST /image/generate Generate scene image via FLUX
GET /world/{genre}/stats Cross-session world statistics
GET /health Engine readiness status

Setup

Requirements: Python 3.11+, Groq API key (free), HF token (free)

git clone https://github.com/vendotha/kalapatha-api
cd kalapatha-api
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt

Create .env:

GROQ_API_KEY=your_groq_key
HF_TOKEN=your_hf_token
WHISPER_MODEL=base
USE_GPU=false
CHROMA_DB_PATH=./db/chroma
VOICE_MANIFEST_PATH=../voice_samples/processed/voice_manifest.json
uvicorn main:app --reload --port 8000

To enable voice narration: Record 10 voice clips (5–15s each) into voice_samples/raw/, then:

python voice_preprocessor.py \
  --input ../voice_samples/raw \
  --output ../voice_samples/processed

Restart XTTS loads automatically when the manifest is found.


Test Results

47 / 51 passing (92%)

✅ Health + all engines           5/5
✅ All 6 genres + visual config   7/7
✅ NRS formula assertions         8/8  ← all 6 math checks pass
✅ Full narrative session        10/10  ← real story, end-to-end
✅ RAG memory (all 3 layers)      7/7  ← character + location tracking
✅ STT (Whisper)                  3/3
✅ TTS status                     3/3

⚠ 4 expected non-failures:
  Ending test stops at beat 8/15  test doesn't run a full story
  TTS engine disabled  voice samples not recorded in CI

Research Paper

Title: Consequence-Weighted Retrieval Augmented Generation for Coherent Emergent Narrative in Interactive Storytelling Systems

Target: AIIDE 2025 · EMNLP 2025 Workshop on Narrative Understanding

Paper Link: NRS →


Built by Buvananand Vendotha

About

The backend of the kalapatha game which serves to the website and mobile application contains rag , model and all other logics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages