An intelligent mock interview platform powered by Google Gemini AI that provides synchronized interviewer and interviewee views, automated resume parsing, dynamic question generation, and comprehensive scoring with actionable feedback.
The Interview Assistant (Crisp) is a modern React-based web application designed to streamline the technical interview process. It leverages Google's Gemini AI to create an intelligent interview experience that benefits both candidates and interviewers. The platform features dual-view interfaces, automatic resume processing, AI-generated questions tailored to candidate profiles, real-time answer evaluation, and comprehensive interview summaries.
- Dual-Interface Design: Separate, synchronized views for interviewees and interviewers
- Intelligent Resume Processing: Automatic parsing of PDF/DOCX resumes with profile extraction
- AI-Powered Question Generation: Dynamic interview questions tailored to candidate experience and role
- Real-Time Answer Evaluation: Structured scoring with detailed feedback using Google Gemini
- Comprehensive Interview Analytics: Live dashboard with progress tracking and candidate history
- Searchable Candidate Dashboard: Quickly filter recent candidates by name and sort them by recency or evaluation score
- Persistent Data Storage: Client-side storage for session continuity and candidate records
- Flexible Scoring System: Multi-level difficulty assessment (Easy, Medium, Hard)
- Timer Management: Configurable time limits per question with automatic submission
This project originally relied on a regex-based parser for extracting candidate details from resumes. The parser has now been replaced with a Gemini API-powered workflow, which delivers far better accuracy and resilience across diverse resume formats by delegating the extraction to Google's large language models.
- Node.js (version 16 or higher)
- npm or yarn package manager
- Google AI Studio API Key for Gemini integration
-
Clone the repository:
git clone https://github.com/Rajat-Shubhra/Interview-Assistant-Crisp-.git cd Interview-Assistant-Crisp- -
Install dependencies:
npm install
-
Configure environment variables: Create a
.envfile in the project root:VITE_GEMINI_API_KEY=your-gemini-api-key-here # Optional: Specify preferred Gemini model (defaults to 2.5 Flash Lite) # VITE_GEMINI_MODEL=gemini-2.5-flash-lite
Important: Get your API key from the Google AI Studio dashboard. The key is used client-side, so avoid committing it to version control.
-
Start the development server:
npm run dev
The application will be available at
http://localhost:5173 -
Verify installation with a production build:
npm run build
Here's a complete example of how to conduct an interview using the platform:
-
Upload Resume:
// The application automatically parses uploaded PDF/DOCX files // and extracts candidate information (name, email, phone) const handleResumeUpload = async (file: File) => { const result = await parseResumeFile(file); // Profile automatically populated with extracted data };
-
Complete Profile:
// Fill in any missing required fields const candidateProfile = { name: "John Doe", email: "john.doe@example.com", phone: "+1-555-123-4567", role: "Full Stack Engineer" };
-
Start Interview:
// Begin the interview session await dispatch(beginInterview({ profileId: candidateProfile.id, configuration: { questionCount: 5, timeLimitMinutes: 30, difficulty: "medium" } }));
-
Answer Questions:
// Submit answers with timing tracking const handleAnswerSubmit = async (answer: string) => { await dispatch(submitAnswer({ questionId: currentQuestion.id, answer: answer, elapsedSeconds: timer.elapsedSeconds })); };
The Recent Candidates panel includes instant search and sorting controls so you can pinpoint the right profile fast:
- Search: Type part of a candidate's name to filter the list in real time (case-insensitive).
- Sort by: Toggle between "Most Recent" and "Highest Score" to prioritize recency or top performers.
- Order: Switch between descending and ascending order for your chosen sort.
-
Monitor Progress:
// Real-time session monitoring const sessionProgress = { currentStage: "questioning", // resume-upload | profile-completion | ready-to-start | questioning | completed questionsCompleted: 3, totalQuestions: 5, candidateProfile: candidateProfile, chatTranscript: messages };
-
Review Answers:
// Access detailed answer analytics const answerDetails = { question: "Explain the difference between let, const, and var in JavaScript", candidateAnswer: "...", aiScore: 8.5, feedback: "Strong understanding of scope and hoisting concepts...", timeSpent: 120 // seconds };
-
Access Interview Summary:
// Comprehensive interview analysis const interviewSummary = { finalScore: 7.8, strengths: ["Strong technical knowledge", "Clear communication"], improvements: ["Could elaborate more on system design", "Practice algorithm optimization"], recommendation: "Move to next round" };
// Configure AI question generation
const interviewConfig = {
difficulty: "hard" as QuestionDifficulty,
questionCount: 8,
categories: ["algorithms", "system-design", "javascript"],
timeLimitPerQuestion: 300, // 5 minutes
role: "Senior Full Stack Engineer"
};
await generateInterviewQuestions(candidateProfile, interviewConfig);// Advanced resume parsing with custom role
const parseOptions = {
role: "Senior Frontend Developer"
};
const result = await parseResumeFile(resumeFile, parseOptions);
// Returns: { profile, resumeMeta, rawText }// The application automatically handles data persistence
// Candidate records are stored locally using IndexedDB
const candidateHistory = useAppSelector(selectCandidateRecords);
// Resume files are stored securely in browser storage
await persistResumeFile(profileId, resumeFile);- Frontend: React 18 with TypeScript and Vite
- State Management: Redux Toolkit with persistent storage
- UI Components: Ant Design for consistent styling
- File Processing: PDF.js for PDF parsing, Mammoth for DOCX
- AI Integration: Google Gemini API for question generation and evaluation
- Data Storage: IndexedDB via idb-keyval for client-side persistence
src/
├── features/
│ ├── interviewee/ # Candidate interface components
│ └── interviewer/ # Interviewer dashboard components
├── services/
│ ├── aiInterviewService.ts # Gemini AI integration
│ ├── resumeParser.ts # PDF/DOCX processing
│ └── resumeStorage.ts # File persistence
├── utils/
│ └── retry.ts # Shared HTTP retry/backoff helper
├── store/
│ ├── slices/ # Redux state management
│ └── thunks/ # Async actions
└── types/
└── interview.ts # TypeScript definitions
### Gemini API Resilience
- All Gemini-bound requests flow through `callGemini`, which now wraps outbound HTTP calls with the shared `fetchWithRetry` helper (`src/utils/retry.ts`).
- Each request gets up to **four attempts** with exponential backoff (500 ms → 1 s → 2 s) plus up to 200 ms of jitter, and retries are limited to transient statuses (`429`, `500`, `502`, `503`, `504`) or network errors.
- When a retry is scheduled, the helper logs the status/error and delay duration so you can monitor flakiness during development.
- The helper is reusable—import it anywhere additional network resilience is needed and customize `maxAttempts`, `retryStatuses`, or `onRetry` to hook into your own telemetry.
| Variable | Required | Description | Default |
|---|---|---|---|
VITE_GEMINI_API_KEY |
Yes | Google AI Studio API key for Gemini integration | - |
VITE_GEMINI_MODEL |
No | Preferred Gemini model identifier | gemini-2.5-flash-lite |
Security Note: API keys are used client-side. Consider implementing a backend proxy for production deployments to secure API access.
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Run tests
npm testThe project includes comprehensive tests covering core functionality:
# Run all tests
npm test
# Key test areas:
# - Resume parsing and profile extraction
# - Session state management
# - Candidate data persistence
# - AI service integration- Chrome/Edge: Full support (recommended)
- Firefox: Full support
- Safari: Full support
- Mobile browsers: Responsive design with touch support
-
"Unable to extract text from resume":
- Ensure the PDF/DOCX file is not password-protected
- Try re-saving the document in a different format
- Check file size (10MB limit)
-
"API key not configured":
- Verify
.envfile exists in project root - Confirm
VITE_GEMINI_API_KEYis set correctly - Restart development server after adding environment variables
- Verify
-
Build warnings about chunk size:
- This is expected due to PDF.js library size
- Use code splitting for production optimization