TutorLoom
기업·대학·교육기관을 위한 학습 플랫폼, 무료 오픈소스이며 엔터프라이즈 버전 제공
IntervU는 정부·캠퍼스·민간 직무 면접을 소리 내어 연습하고, 실제 답변을 기반으로 추가 질문과 피드백을 제공하는 서비스입니다
Spoken mock interviews for government, campus and private-sector roles, with follow-up questions and feedback based on what you actually said.
교육TypeScript · JavaScriptGitHub @PrachiYadav-16온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 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.