Skip to content

Angus-Sun/Did-I-Cook

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Did-I-Cook?

A real-time, AI-judged debate app where two players debate a topic on video and an AI (Gemini) scores them with evidence-backed reasoning using a RAG pipeline (OpenSearch + embeddings). The project includes a Next.js frontend, a Spring Boot backend (API + signaling), and Python worker scripts to chunk/embed and index evidence into OpenSearch. BIG THANKS to Kaelyn Cho for her amazing artwork she's provided for this project <:


Table of contents


Tech Stack

  • Frontend: Next.js (App Router), React, Tailwind CSS, Framer Motion, react-confetti
  • Backend: Spring Boot (Java 21), REST controllers, WebRTC signaling
  • RAG worker: Python, FastAPI, HuggingFace SentenceTransformers (all-MiniLM-*), OpenSearch (k-NN)
  • LLM: Google Gemini (via REST) with prompt → JSON parsing

Local development

Prereqs: Node.js, Java 21 + Maven, Python 3.11+, OpenSearch (or remote), Git

  1. Frontend (apps/web)

  2. Backend API (apps/api)

    • cd apps/api
    • mvn spring-boot:run
    • Config via src/main/resources/application.properties (or environment vars)
  3. Worker / RAG (apps/worker)

    • python -m venv .venv
    • .venv\Scripts\activate (. ./venv/bin/activate on mac/linux)
    • pip install -r requirements.txt
    • uvicorn semantic_search_api:app --reload --port 8000
    • Use scripts in apps/worker/scripts/ to chunk, embed, and index to OpenSearch

Environment variables (examples):

# Gemini
GEMINI_API_KEY=<primary>
GEMINI_API_KEY2=<fallback>
# OpenSearch (for worker/fastapi)
OPENSEARCH_URL=http://localhost:9200
OPENSEARCH_USER=admin
OPENSEARCH_PASS=admin

Notes:

  • The app will POST to /api/debates/:id/results to trigger scoring and RAG evidence retrieval.
  • Use the RAG scripts to populate an OpenSearch index before relying on key-evidence output.

RAG pipeline

  • Chunk documents (PDFs, text) with chunk_and_embed.py or index_chunks.py.
  • Embed using SentenceTransformers and store k-NN vectors in OpenSearch.
  • apps/worker/semantic_search_api.py exposes /search used by the API to gather evidence chunks for prompts.

Local RAG setup (step-by-step)

If you want to run the full RAG pipeline locally (OpenSearch + worker + Java API → Gemini), follow these steps:

  1. Start OpenSearch (example using Docker):
# run a single-node OpenSearch for local testing
docker run -d --name opensearch -p 9200:9200 -e "discovery.type=single-node" opensearchproject/opensearch:latest
  1. Prepare the Python worker environment and install deps:
cd apps/worker
python -m venv .venv
.venv\Scripts\activate    # Windows
# or: source .venv/bin/activate  # macOS / Linux
pip install -r requirements.txt
  1. Index your content (populate the OpenSearch index):
# from the repo root
python apps/worker/scripts/index_chunks.py
  1. Run the worker FastAPI semantic-search service (keeps running):
# from the repo root (uses the module path)
python -m uvicorn apps.worker.scripts.semantic_search_api:app --reload --host 127.0.0.1 --port 8000
  1. Verify the /search endpoint returns chunks:
curl -s -X POST "http://localhost:8000/search" -H "Content-Type: application/json" -d '{"query":"climate change","top_k":3}' | jq
  1. Start the Java API and ensure it can reach the worker on http://localhost:8000 (the GeminiService posts to /search). Set Gemini keys and any needed OpenSearch env vars:
OPENSEARCH_URL=http://localhost:9200
GEMINI_API_KEY=<your_key_here>
GEMINI_API_KEY2=<optional_fallback>

Notes:

  • Re-run index_chunks.py whenever you add or update source documents to refresh the evidence index.
  • If your worker binds to 127.0.0.1/localhost, the Java API must run on the same machine or be able to reach that host; bind to 0.0.0.0 if you need external access.
  • Keep secrets out of client-side code — the Gemini call should remain server-side (the Java API or worker).

Gemini & prompt notes

  • Gemini is invoked from apps/api/src/main/java/com/didicook/api/service/GeminiService.java.
  • Important behaviors implemented:
    • Attempts fallback API keys (GEMINI_API_KEY, GEMINI_API_KEY2..GEMINI_API_KEY5).
    • Transcript builder maps numeric speakers to real player1Name / player2Name when provided.
    • Sends an explicit JSON schema instruction (no sample payload embedded in final prod prompt) to avoid sample bias.

Tips:

  • If you see parsing errors in the backend response, the returned text may include extra content — we try to extract the first top-level JSON object.
  • For debugging, add a temporary log of the final prompt before sending (avoid logging secrets in production).

UX & features

  • In-call judging: users remain on the call while AI scores (results appear as a themed overlay)
  • Animated judging state: an "AI is judging..." modal with subtle animations (framer-motion)
  • Results page: flippable CookbookCard style cards (front/back), lined-paper background aesthetic
  • Confetti shows only for the viewer when they are the winner (visitor-specific)
  • Tie handling displays "It's a tie!" with no confetti
  • Dev conveniences: sample-mode used during development earlier; currently the app fetches live results by default

About

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published