Skip to content

Rajat-Shubhra/Interview-Assistant-Crisp-

Repository files navigation

Interview Assistant (Crisp)

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.

Project Overview

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.

Key Features

  • 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

Resume Parsing

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.

Getting Started

Prerequisites

  • Node.js (version 16 or higher)
  • npm or yarn package manager
  • Google AI Studio API Key for Gemini integration

Installation

  1. Clone the repository:

    git clone https://github.com/Rajat-Shubhra/Interview-Assistant-Crisp-.git
    cd Interview-Assistant-Crisp-
  2. Install dependencies:

    npm install
  3. Configure environment variables: Create a .env file 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.

  4. Start the development server:

    npm run dev

    The application will be available at http://localhost:5173

  5. Verify installation with a production build:

    npm run build

Usage

Basic Interview Flow

Here's a complete example of how to conduct an interview using the platform:

For Candidates (Interviewee View):

  1. 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
    };
  2. 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"
    };
  3. Start Interview:

    // Begin the interview session
    await dispatch(beginInterview({
      profileId: candidateProfile.id,
      configuration: {
        questionCount: 5,
        timeLimitMinutes: 30,
        difficulty: "medium"
      }
    }));
  4. Answer Questions:

    // Submit answers with timing tracking
    const handleAnswerSubmit = async (answer: string) => {
      await dispatch(submitAnswer({
        questionId: currentQuestion.id,
        answer: answer,
        elapsedSeconds: timer.elapsedSeconds
      }));
    };

For Interviewers (Interviewer View):

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.
  1. 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
    };
  2. 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
    };
  3. 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"
    };

Advanced Configuration

Custom Question Generation:

// 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);

Resume Parsing Options:

// Advanced resume parsing with custom role
const parseOptions = {
  role: "Senior Frontend Developer"
};

const result = await parseResumeFile(resumeFile, parseOptions);
// Returns: { profile, resumeMeta, rawText }

Data Persistence:

// 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);

Architecture Overview

Core Technologies

  • 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

Project Structure

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.

Environment Variables

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.

Development Commands

# Start development server
npm run dev

# Build for production  
npm run build

# Preview production build
npm run preview

# Run tests
npm test

Testing

The 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

Browser Compatibility

  • Chrome/Edge: Full support (recommended)
  • Firefox: Full support
  • Safari: Full support
  • Mobile browsers: Responsive design with touch support

Troubleshooting

Common Issues

  1. "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)
  2. "API key not configured":

    • Verify .env file exists in project root
    • Confirm VITE_GEMINI_API_KEY is set correctly
    • Restart development server after adding environment variables
  3. Build warnings about chunk size:

    • This is expected due to PDF.js library size
    • Use code splitting for production optimization

About

An app that automates technical screenings using the Gemini API for questions and feedback. Features a full interview flow and an interviewer dashboard.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages