D-viva-assistant-agent
- Next.js
- TypeScript
- AI SDK v6
- SQLite / better-sqlite3
- Tailwind CSS
- Zod
- Vitest
- Electron
A private desktop app for thesis viva preparation. It turns a student's own thesis into evidence-linked practice questions, scoring, and revision tasks while keeping the thesis file and practice history on the device.
At a glance
Role Sole builder — product design, architecture, database layer, LLM integration, validation and tests
Problem
Existing viva prep tools are either generic flashcard apps or require hand-crafting every question. The real bottleneck is grounding: an AI examiner is only useful if its questions trace back to what the thesis actually says, and scoring is only trustworthy if it cites the evidence it used.
Solution
I built a private desktop workflow where the thesis is ingested into evidence blocks, practice questions and scoring cite those blocks, and low-scoring answers feed a review queue. The app keeps files and history local unless the user opts into a provider.
Impact
Shipped local-first viva prep app · evidence-linked practice · privacy-first desktop use
My contribution
- Thesis ingest pipeline — PDF / MD / TXT → paragraph evidence blocks with a quality report; every downstream AI call is grounded to ingest output, not model priors
- AI study pack generation — thesis summary, key numbers, method Q&A, high-pressure Q&A, and literature cards; each item cites the evidence block it came from and passes a pre-persist validator
- Editable prep items, revalidation, review queue, and a training plan generator with a static fallback when no model key is configured
- Real-time AI examiner — draws questions from evidence blocks, scores responses on five dimensions (accuracy / depth / language / methodology / poise) with diagnosis, English rewrite, and follow-up
- STT practice loop — record answer → transcribe (browser Web Speech or Google Cloud STT) → score; low-scoring items feed the review repair board
- Provider-agnostic LLM layer — AI SDK v6 generateObject + Zod for structured scoring; supports Gemini / Claude / OpenAI; graceful no-key degradation (practice + transcripts still work)
- Electron + electron-builder macOS packaging, positioning the app as a private desktop tool rather than a hosted multi-user service
Technical evidence
- Local-first data model: SQLite (better-sqlite3, WAL, FTS5) for theses, evidence blocks, study packs, and session history; DB lives entirely on device
- Privacy-by-design: cloud AI is opt-in with explicit disclosure of what is sent to which provider; API keys in .env.local (gitignored), log-level redacted; recordings never synced
- Next.js App Router with server-only DB access (runtime=nodejs boundary, globalThis singleton, serverExternalPackages for better-sqlite3); AI calls gated behind env parse
- Tests use MockLlmClient by default; real model calls are gated by RUN_LIVE_AI=1 and only run against public sample theses
Grounding every generated item
An imported thesis (PDF / Markdown / text) is extracted into paragraph evidence blocks with a quality report. Every downstream item — summary, key numbers, method Q&A, high-pressure Q&A, literature cards, and training plan — is bound to an evidence block and passes a pre-persist validator. The judge and examiner rule only from bound evidence, never from model priors.
The examiner loop
A real-time examiner draws questions from evidence blocks and scores a response across five dimensions, with a diagnosis, an English rewrite, and a follow-up. You can type or paste an answer, or record one — the audio is transcribed (browser Web Speech or Google Cloud STT) and scored. Low-scoring items feed the review queue and repair board.
Local-first, cloud AI opt-in
The SQLite library, recordings, and the thesis file stay on the device — no account, no cloud sync. Cloud AI is an opt-in outbound call enabled only when a provider key is present, with an explicit disclosure of what gets sent to whom; with no key, the app degrades gracefully and practice plus transcripts still work.
The LLM layer is provider-agnostic (Gemini / Claude / OpenAI), and tests inject a mock client by default — real model calls are env-gated and only run against public sample theses. The shipped app stays positioned as a private desktop tool, not a hosted multi-user service.
Screenshots