Inspiration
Most course material is passive. Slides, PDFs and lecture videos explain a topic once and never check whether a student understood it. We wanted to build a study partner that works from a student's own material, talks back, and keeps track of what they still get wrong.
What it does
JacAcademy turns your lecture notes into a tutor you can talk to: a video lesson that draws and quizzes you, a podcast you can join, and a feed for the walk to class.
Video tutor. Students upload course material (PDF, Word, PowerPoint, text, CSV, Excel, images, web links or YouTube videos). A Tavus video tutor teaches from that material, draws on a shared board while it explains, and asks short quizzes during the call.
Podcast. Two hosts, Maya and Leo, run a live podcast about any topic the student picks, in English or Sinhala. Students can paste their own notes so the hosts stay on their material.
Practice feed. Memes, flashcards and quick quizzes made from each document.
Review. Questions a student misses go into a flashcard deck scheduled with FSRS spaced repetition.
Recaps, mock exams and notes for each lesson.
Progress. A topic heatmap, daily streaks, XP, a daily goal and nine badges.
Family sharing. A view only progress page for a parent or mentor, plus a summary email every Monday. It shows streaks, XP, subjects, accuracy and weak topics, and never shows notes, materials or lesson recordings.
How we built it
The whole app is written in Jac, on both the server and the client.
Server. Jac stores each student's subjects, documents, lessons, cards and activity as a graph attached to their account. Model calls go through byLLM, with Gemini as the default model, so outputs come back as typed objects.
Client. React through Jac's client mode, built with Vite and styled with Tailwind CSS and Radix UI components.
Video and board. Tavus conversational video runs on Daily. During a call the tutor uses tools to draw on a tldraw board and to start quizzes.
Podcast audio. Gemini text to speech.
Feed and board content. Any OpenAI compatible model endpoint.
Reading uploads. pypdf for PDFs, python docx for Word files, trafilatura for web pages, and YouTube transcripts for videos.
Weekly email. A scheduled Jac job sends the parent summary through Resend every Monday at 08:00 UTC.
Spaced repetition. The review deck uses the FSRS 6 scheduler. Each card has a stability \( S \), measured in days. The chance of recalling it \( t \) days after the last review is
$$ R(t, S) = \frac{1}{\left(1 + F \cdot \frac{t}{S}\right)^{w}} $$
Here \( w \) is the learned decay parameter (0.1542 by default), and \( F \) is set so that \( R = 0.9 \) when \( t = S \). With the default 90% target retention, a card comes back about \( S \) days after it was last reviewed. Each rating updates \( S \): a correct answer makes it larger, and a miss makes it smaller.
XP. A lesson gives 20 XP. Each quiz answer gives 5 XP, or 10 if it is correct. Students set a daily goal of 30, 50, 100 or 150 XP.
Challenges we ran into
Getting local files to Tavus. The tutor runs on Tavus's servers and can't read files on a laptop. Our dev script serves uploads locally and opens a Cloudflare quick tunnel, so uploaded files get a public link during development.
Keeping the board readable. The tutor draws while it talks, and drawings overlapped. We wrote a layout step that measures text, fits each batch of drawings into free space and keeps arrows attached to the right shapes.
Reliable feed content. Generated feed items are checked by a validation step, which has its own tests, before a student sees them.
Call length. Video minutes add up quickly. Calls have a configurable time limit (600 seconds by default), and a test mode lets us develop without using real minutes.
Dependency conflicts. Our pinned openai version conflicts with the litellm release that byLLM depends on. The README documents a workaround.
Sign in during development. The dev script picks the first free port out of 8000, 8002 and 8004, runs the API on the next port, and points Google sign in at the matching callback.
What we learned
How to model an app as a graph in Jac, with the same language running the server and the client. How typed model calls through byLLM make generated lessons, recaps and quizzes easier to depend on. How to connect a live video tutor to app features through tool calls during the call. How FSRS schedules reviews from stability and retention.
Built With
- byllm
- daily
- fsrs
- gemini
- google-oauth
- jac
- jac-scale
- jaseci
- javascript
- litellm
- openai-compatible-api
- pypdf
- python
- python-docx
- radix-ui
- react
- shadcn-ui
- tailwindcss
- tavus
- tldraw
- trafilatura
- vite
Log in or sign up for Devpost to join the conversation.