TutorLoom
The learning platform for companies, colleges and training institutes. Free and open source, with an Enterprise edition.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Live site:https://ai-voice-interviewer-lyart.vercel.app
Spoken mock interviews for government and private-sector roles. You talk with an AI interviewer that asks one question at a time, waits while you think and follows up on what you actually said. Afterwards you get rubric-based feedback on each answer.
| Part | Where |
|---|---|
| Interview catalog (tracks, roles, formats, styles) | lib/interview/catalog.ts — add a role or field by adding data here |
| Interviewer instructions and Vapi assistant config | lib/interview/prompt.ts |
| Live call state machine (pure, unit-tested) | lib/interview/session.ts |
| Vapi SDK wiring, mic checks, pause/mute/skip/end | lib/hooks/useVapiInterview.ts |
| Rubrics and the 1–5 scale | lib/interview/rubrics.ts |
| Overall score calculation | lib/interview/scoring.ts |
| Device accounts (PBKDF2-hashed passwords) | lib/auth.ts |
| Browser storage for profiles, sessions and reports | lib/storage.ts |
| Server routes | app/api/parse-document, app/api/plan, app/api/evaluate, app/api/status |
Voice. The browser runs the call with the Vapi Web SDK (@vapi-ai/web 2.7) using a transient assistant built per interview. Turn-taking uses Vapi's smart endpointing for English and transcription endpointing for Hindi, requires two spoken words before the interviewer stops talking, and nudges once after 25 seconds of silence. Pause mutes your mic and the interviewer; skip, repeat and wrap-up send control messages. The call's hard limit is set from the interview length (Vapi's default is 10 minutes).
Feedback. After the call, the transcript is sent to /api/evaluate, which asks an OpenAI-compatible model to rate each answer 1–5 against the rubric for that interview type, with evidence from your words. IntervU computes the overall score itself as the average rating mapped to 0–100, and shows no overall score when fewer than three answers were rated. Feedback covers the words only: tone, pace, confidence and body language are not measured.
Data. With Supabase configured, accounts use Supabase Auth (email confirmation, email password reset) and interviews are stored in two tables protected by Row Level Security, so each user can only read their own rows (supabase/schema.sql). The app is local-first: pages read from a browser cache, and lib/cloud.ts mirrors every change to the database with debounced, retried writes, then fills the cache on sign-in. Without Supabase, everything stays in each browser's localStorage. See /privacy in the app.
Requirements: Node.js 20.9 or later (tested on 22), npm.
git clone https://github.com/PrachiYadav-16/AI-voice-interviewer.git
cd AI-voice-interviewer
npm ci
cp .env.example .env.local # then fill in the values below
npm run dev # http://localhost:3000
| Variable | Needed for | Where to get it |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Accounts and database | Supabase → Project Settings → API Keys (or the project home page) |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Accounts and database | Same page → Publishable key (sb_publishable_...). Never use the secret / service_role key. |
NEXT_PUBLIC_VAPI_PUBLIC_KEY | Live interviews | Vapi dashboard → API Keys → Public key. Restrict it to your domains. Never use the private key here. |
LLM_API_KEY | Feedback reports, personalised question plans | An OpenAI API key, or a key for any OpenAI-compatible provider |
LLM_BASE_URL | Optional | Defaults to https://api.openai.com/v1 |
LLM_MODEL | Optional | Defaults to gpt-4.1-mini; must support JSON response format |
NEXT_PUBLIC_VAPI_LLM_MODEL | Optional | Interviewer model, default gpt-4.1 |
NEXT_PUBLIC_VAPI_VOICE_ID | Optional | ElevenLabs voice ID, default 21m00Tcm4TlvDq8ikWAM |
Without NEXT_PUBLIC_VAPI_PUBLIC_KEY the app runs but interviews can't start (the UI says so). Without LLM_API_KEY interviews run and transcripts are saved, but reports and plans show a "not configured" message. Vapi usage is billed to the Vapi account, including the speech, model and voice providers it calls.
Microphone access needs HTTPS in production (localhost is allowed in development).
supabase/schema.sql, and click Run. This creates the profiles and sessions tables, Row Level Security policies, and the delete_my_account function.http://localhost:3000 while developing) and add http://localhost:3000/** plus your deployed domain with /** to Redirect URLs. Confirmation and password-reset emails link back here..env.local and restart npm run dev.Supabase's built-in email sender is rate-limited and meant for testing. For real users, add your own SMTP provider under Authentication → Emails → SMTP Settings.
With Supabase set, the AI routes (/api/evaluate, /api/plan, /api/parse-document) also require a signed-in user, which stops other people from spending your AI credits.
npm run dev # development server
npm run build # production build
npm start # serve the production build
npm test # unit and API tests (Vitest)
npm run typecheck # TypeScript
npm run lint # ESLint, zero warnings allowed
npm run check # all three
Browser smoke test (optional): npm i -D playwright && npx playwright install chromium, start the app, then node tests/e2e/smoke.mjs. It uses a fake microphone and does not test a real conversation.
Vercel works out of the box:
/api/evaluate may take up to 90 seconds, so use a plan whose function timeout allows that.Any host that runs next start on Node 20.9+ also works.
.doc files and scanned PDFs can't be read; paste the text instead.npm audit reports a moderate advisory in sprintf-js, reached only through mammoth's command-line argument parser, which IntervU never calls. The suggested fix downgrades mammoth to a 2015 release, so it hasn't been applied.LLM_API_KEY) are only read on the server. /api/status exposes booleans, never values.app/page.tsx. It has been removed from the code but remains in git history, so rotate that key in the Vapi dashboard.