Skip to content

shadkhan/InterviewOS

Repository files navigation

🎯 InterviewOS

Your AI-powered personal interview strategist β€” tailored to your resume, your target job, and your target company.

InterviewOS is a production-grade, multi-agent AI platform that helps job seekers prepare for interviews with company-specific research, resume-aligned answers, salary intelligence, and a structured 7-day prep plan. It is built on LangGraph.js, Next.js, NestJS, PostgreSQL + pgvector, and Redis + BullMQ.

License: MIT Node pnpm LangGraph Next.js Prisma


πŸ“š Table of Contents


✨ Features

  • πŸ“„ Resume Parsing β€” Extract skills, experience, and impact statements from raw resume text.
  • πŸ” Job Description Analysis β€” Identify hard skills, soft skills, signals, and disqualifiers.
  • 🏒 Company Research β€” Live web research with citations (no hallucinated facts).
  • πŸ’° Salary Insights β€” Range estimates with confidence levels and source URLs.
  • 🩺 Pain Point Detection β€” Likely company/team pain points the role is meant to solve.
  • ❓ Interview Question Bank β€” Behavioral, technical, and role-specific questions per company and seniority.
  • πŸŽ“ Answer Coach β€” STAR-structured sample answers grounded in your resume only.
  • πŸ—“οΈ 7-Day Prep Plan β€” Prioritized topics and a day-by-day study plan.
  • 🧡 Background Job Runs β€” Long-running multi-agent runs orchestrated via BullMQ with live progress.
  • πŸ“Š Per-Agent Debug Logs β€” Inspect each LangGraph node's status, duration, errors, and outputs.

🧠 Why InterviewOS β€” and Why Not Off-the-Shelf Agent Skills?

"The OpenAI Assistants API, Claude Skills, and similar high-level agent abstractions are powerful β€” but they were the wrong tool for this job."

I deliberately did not build InterviewOS on top of OpenAI Assistants/Agents SDK or Claude Skills (or similar managed agent runtimes). Here is why:

1. πŸ”’ Provider Lock-In Was a Non-Starter

Off-the-shelf agent skills tightly couple your application to one vendor's runtime, tool spec, and pricing tier. InterviewOS is multi-provider by design β€” OpenAI, Anthropic, Groq, and Google Gemini are interchangeable behind a single LLMProvider interface, with automatic fallback and retry. A single environment variable swaps providers; tomorrow's cheaper model is a one-line change.

2. 🧩 The Workflow Is a Graph, Not a Conversation

Managed "skills" frameworks model the world as a single agent + tools + memory. InterviewOS is a directed graph of ten specialized agents that share typed state, run in a deterministic order, and produce schema-validated outputs at every step. LangGraph.js fits this shape natively; assistant-style frameworks force you to fake it with prompts and hope.

3. 🧱 Strict Output Schemas Required Code-Level Control

Every agent output is a Zod-validated structure (ResumeProfile, JDAnalysis, CompanyResearchReport, …) that flows directly into Prisma. Generic "tool calling" is too loose β€” we need re-prompting, repair, and per-field confidence scores. Owning the loop lets us enforce the contract.

4. πŸͺ΅ Observability and Debuggability Are First-Class

Every node's start time, duration, status, error, prompt, and raw response are logged and surfaced in the UI's Agent Runs view. Hosted skills hide the runtime β€” when something fails at 3 AM, you need to see the actual prompt and the raw model response, not a black-box trace.

5. πŸ’Έ Cost Control and Free-Tier Friendly

Resume + company + JD analysis can easily fan out to 20+ LLM calls. We added a Gemini Flash free model path and a MockLLMProvider so contributors can develop and test without burning a single token. Hosted agent runtimes don't let you do this cleanly.

6. πŸ” Background Jobs, Retries, and Idempotency

Interview prep runs take minutes. They need a queue, retries, progress reporting, and the ability to resume. BullMQ + Redis + LangGraph gives that out of the box. Assistants APIs are request/response β€” you'd end up rebuilding a queue on top anyway.

7. πŸ§ͺ Testability

The LLMProvider and SearchProvider abstractions are mockable, so every node has a fast, deterministic unit test. Skills frameworks are hard to mock because the runtime is the framework.

TL;DR

Off-the-shelf agent skills optimize for demos. InterviewOS optimizes for production: typed state, schema-validated outputs, multi-provider failover, queueable runs, observable graphs, and zero vendor lock-in.


πŸ›οΈ Architecture

High-Level System Diagram

flowchart TB
    subgraph Client["πŸ–₯️ Frontend β€” Next.js 14 (App Router)"]
        UI[Dashboard<br/>Job Targets<br/>Agent Runs<br/>Reports]
    end

    subgraph API["βš™οΈ Backend API β€” NestJS"]
        AUTH[Auth Module]
        JT[Job Targets Module]
        AR[Agent Runs Module]
        REP[Reports Module]
        SET[Settings Module]
    end

    subgraph Queue["πŸ“¦ Job Queue"]
        BMQ[(BullMQ Worker)]
        RDS[(Redis)]
    end

    subgraph Agents["🧠 LangGraph.js Agent Layer"]
        WF[Interview Prep Workflow<br/>StateGraph]
        NODES[10 Agent Nodes]
        WF --> NODES
    end

    subgraph Providers["🌐 Provider Abstraction"]
        LLM[LLM Provider<br/>OpenAI Β· Anthropic Β· Groq Β· Gemini]
        SRCH[Search Provider<br/>Tavily Β· Exa Β· SerpAPI]
    end

    subgraph Data["πŸ’Ύ Data Layer"]
        PG[(PostgreSQL<br/>+ pgvector)]
        PRS[Prisma ORM]
    end

    UI -->|REST| API
    API -->|enqueue run| RDS
    RDS --> BMQ
    BMQ -->|invoke| WF
    NODES -->|generate| LLM
    NODES -->|research| SRCH
    NODES -->|persist| PRS
    PRS --> PG
    API -->|read| PRS
Loading

Component Layers

Frontend (Next.js)
        ↓
Backend API (NestJS)
        ↓
Agent Layer (LangGraph.js)
        ↓
Providers (LLM + Search)
        ↓
Database (PostgreSQL + pgvector)
        ↓
Queue (Redis + BullMQ)

πŸ€– LangGraph Agents

Why LangGraph.js?

We chose LangGraph.js over alternatives like LangChain Agents, OpenAI Assistants, AutoGen, and CrewAI because the interview-prep problem is fundamentally a graph-shaped, stateful, multi-step workflow β€” exactly what LangGraph was designed for.

Requirement LangGraph Capability
🧡 Multi-step deterministic flow First-class StateGraph with explicit nodes and edges
πŸ“¦ Shared typed state across agents Annotation-based state schema with reducers
πŸ”€ Conditional routing (e.g., skip salary if cached) addConditionalEdges
⏳ Long-running background jobs Pure JS β€” composes naturally with BullMQ workers
πŸ” Per-node retries and error isolation Each node is a function β€” wrappable with retry/backoff
πŸ‘οΈ Streaming progress to the UI Reducers + per-node hooks β†’ live progress + node statuses
πŸ‘€ Future human-in-the-loop review LangGraph supports interrupt/resume natively
πŸ§ͺ Testable in isolation Nodes are plain functions; mock providers in unit tests

Workflow Graph

flowchart LR
    START([▢️ START]) --> A[πŸͺͺ intake]
    A --> B[πŸ“„ resumeParser]
    B --> C[πŸ” jdAnalysis]
    C --> D[🏒 companyResearch]
    D --> E[πŸ’° salaryResearch]
    E --> F[🩺 painPoint]
    F --> G[❓ interviewQuestion]
    G --> H[πŸŽ“ answerCoach]
    H --> I[πŸ—“οΈ prepPlan]
    I --> J[βœ… finalize]
    J --> END([⏹️ END])
Loading

The 10 Agents

# Agent Responsibility
1 IntakeAgent Validate inputs, normalize the project
2 ResumeParserAgent Extract structured profile from resume text
3 JDAnalysisAgent Hard/soft skills, signals, disqualifiers
4 CompanyResearchAgent Live web research with citations
5 SalaryResearchAgent Salary range + confidence + sources
6 PainPointAgent Likely team/company pain points
7 InterviewQuestionAgent Tailored question bank
8 AnswerCoachAgent STAR answers grounded in user's resume
9 PrepPlanAgent Priority topics + 7-day plan
10 FinalizeAgent Aggregate, persist, report

Implementation Highlights

Each node is wrapped in createSafeWorkflowNode which adds:

  • ⏱️ Per-node timing and status reporting
  • πŸ›Ÿ Graceful failure (errors do not crash the run)
  • πŸ“Š Live progress percentage (10% β†’ 100%) streamed back to BullMQ
  • πŸͺ΅ Structured logging of inputs, outputs, and errors

🧭 User Flows

Flow 1 β€” Create a Job Target & Run Agents

sequenceDiagram
    actor U as πŸ‘€ User
    participant W as πŸ–₯️ Web (Next.js)
    participant A as βš™οΈ API (NestJS)
    participant DB as πŸ’Ύ Postgres
    participant Q as πŸ“¦ BullMQ
    participant G as 🧠 LangGraph Workflow
    participant L as 🌐 LLM/Search Providers

    U->>W: Paste resume + JD + target company
    W->>A: POST /job-targets
    A->>DB: Create JobTarget (status=pending)
    A->>Q: enqueue("interview-prep", jobTargetId)
    A-->>W: 201 { jobTargetId }
    W-->>U: Redirect β†’ /agent-runs/[id]

    Q->>G: invoke(InterviewPrepState)
    loop For each of 10 agents
        G->>L: prompt + (optional) web search
        L-->>G: structured response
        G->>DB: persist node output
        G->>A: progress + node status
        A-->>W: SSE / poll β†’ live UI update
    end
    G->>DB: status=completed
    W-->>U: Final report rendered
Loading

Flow 2 β€” Review the Final Report

flowchart LR
    U[πŸ‘€ User] --> D[πŸ“Š Dashboard]
    D --> JT[πŸ“ Job Target page]
    JT --> R1[πŸ“„ Resume Match]
    JT --> R2[🏒 Company Report]
    JT --> R3[πŸ’° Salary Insight]
    JT --> R4[❓ Question Bank]
    JT --> R5[πŸŽ“ Answer Guides]
    JT --> R6[πŸ—“οΈ 7-Day Prep Plan]
    JT --> AR[πŸ§ͺ Agent Run Debug View]
    AR --> NL[πŸͺ΅ Per-node logs<br/>prompts Β· responses Β· errors]
Loading

Flow 3 β€” Configure LLM Providers

flowchart LR
    U[πŸ‘€ User] --> S[βš™οΈ Settings page]
    S --> K1[πŸ”‘ OpenAI key]
    S --> K2[πŸ”‘ Anthropic key]
    S --> K3[πŸ”‘ Groq key]
    S --> K4[πŸ”‘ Gemini key β€” free tier]
    S --> SP[πŸ” Tavily / Exa / SerpAPI]
    S --> SAVE[πŸ’Ύ Persist in app_settings]
    SAVE --> RUN[▢️ Subsequent runs use new providers]
Loading

πŸ—‚οΈ Project Structure

InterviewOS/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ web/              # Next.js 14 frontend (App Router + Tailwind)
β”‚   └── api/              # NestJS backend (auth, job-targets, agent-runs, reports, settings)
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ agents/           # LangGraph.js workflow + nodes + providers + prompts
β”‚   β”‚   └── src/
β”‚   β”‚       β”œβ”€β”€ nodes/        # The 10 agent implementations
β”‚   β”‚       β”œβ”€β”€ workflows/    # StateGraph definition
β”‚   β”‚       β”œβ”€β”€ state/        # Typed shared state + reducers
β”‚   β”‚       β”œβ”€β”€ providers/    # LLM + Search abstractions
β”‚   β”‚       β”œβ”€β”€ prompts/      # Prompt loader
β”‚   β”‚       └── queue/        # BullMQ worker glue
β”‚   β”œβ”€β”€ database/         # Prisma schema + client
β”‚   └── shared/           # Zod schemas + shared types
β”œβ”€β”€ prompts/
β”‚   β”œβ”€β”€ agents/           # Per-agent prompts (versioned, file-based)
β”‚   └── system/           # System-level prompt fragments
β”œβ”€β”€ docker/               # Postgres init scripts
β”œβ”€β”€ scripts/              # Dev scripts (e.g. create-test-user)
β”œβ”€β”€ docker-compose.yml    # Postgres (pgvector) + Redis
β”œβ”€β”€ pnpm-workspace.yaml
└── package.json

πŸš€ Getting Started

Prerequisites

  • 🟒 Node.js β‰₯ 20
  • πŸ“¦ pnpm β‰₯ 9
  • 🐳 Docker + Docker Compose (for Postgres and Redis)
  • πŸ”‘ At least one LLM provider key (Gemini Flash has a free tier)

1. Clone & Install

git clone https://github.com/<your-org>/InterviewOS.git
cd InterviewOS
pnpm install

2. Start Infrastructure

docker compose up -d         # Postgres (pgvector) + Redis

3. Configure Environment

Copy .env.example files in apps/api, apps/web, and packages/database to .env and fill in:

DATABASE_URL=postgresql://interviewos:interviewos@localhost:5432/interviewos
REDIS_URL=redis://localhost:6379

OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GROQ_API_KEY=gsk_...
GEMINI_API_KEY=...

TAVILY_API_KEY=tvly-...

4. Migrate the Database

pnpm --filter @interviewos/database prisma migrate dev
pnpm tsx scripts/create-test-user.ts

5. Run Everything

pnpm dev   # runs web + api + agents in parallel

βš™οΈ Configuration

LLM and search provider keys can be set either via .env (for development) or via the in-app Settings page (persisted in app_settings). Settings page entries override env vars at runtime.

Supported providers out of the box:

Type Providers
🧠 LLM OpenAI · Anthropic · Groq · Google Gemini (Flash free tier) · Mock
πŸ”Ž Search Tavily Β· Exa Β· SerpAPI Β· Mock

A FallbackLLMProvider and RetryingLLMProvider are composed automatically β€” if the primary provider fails or rate-limits, the next one is tried with exponential backoff.


πŸ§ͺ Testing

pnpm test                                    # all packages
pnpm --filter @interviewos/agents test       # agent unit tests

Every agent node ships with a unit test that uses MockLLMProvider and MockSearchProvider, so the entire workflow can run end-to-end with zero API calls and zero cost.


πŸ›‘οΈ Agent Safety Rules

These are enforced by prompts, schemas, and tests across every agent:

  • 🚫 Never invent company facts.
  • 🚫 Never invent salary data.
  • πŸ“š Use citations for all research-based claims.
  • 🧾 Clearly separate facts, estimates, and assumptions.
  • πŸ“„ Resume-based answers must use only user-provided resume details.
  • ❌ Never promise interview success.
  • ❌ Never provide discriminatory advice.
  • πŸ” Do not store unnecessary sensitive information.
  • βœ… Every agent output must follow a Zod schema.
  • 🌐 Every external research output must include source URLs.
  • ⚠️ If confidence is low, mark it as low confidence.

🀝 Contribution Guidelines

We welcome contributions! πŸŽ‰

🧭 Ground Rules

  1. Be respectful. This project follows a standard contributor code of conduct β€” be kind, be helpful.
  2. Open an issue first for anything larger than a small fix. It saves wasted work.
  3. Keep PRs focused. One concern per PR. Small, reviewable diffs > sprawling rewrites.

πŸ› οΈ Development Workflow

  1. Fork the repo and create a feature branch:
    git checkout -b feat/your-feature
  2. Install + bootstrap with pnpm install and docker compose up -d.
  3. Run the full pipeline locally before opening a PR:
    pnpm typecheck
    pnpm lint
    pnpm test
    pnpm build
  4. Write a test for any new node, provider, or schema. New agent nodes must include at least one unit test using mock providers.
  5. Update prompts in /prompts β€” never hard-code prompts inside .ts files.
  6. Update the Zod schema in packages/shared if you change an agent's output shape.

πŸ“ Code Style

  • 🟦 TypeScript strict mode, no any.
  • πŸͺ΅ Structured logging only β€” no stray console.log.
  • πŸ”Œ Provider interfaces stay abstract β€” never import openai/anthropic SDKs directly inside a node.
  • πŸ§ͺ Dependency injection β€” nodes receive their providers as parameters, not via global imports.
  • 🌱 No hard-coded API keys. Ever. Use .env and app_settings.
  • 🧹 Prefer small, focused commits with conventional-commit-style messages (feat:, fix:, chore:, docs:).

🧩 Adding a New Agent Node

  1. Create the prompt in prompts/agents/<your-agent>.md.
  2. Create the Zod schema in packages/shared/src/schemas/.
  3. Implement the node in packages/agents/src/nodes/<your-agent>.node.ts.
  4. Register it in packages/agents/src/nodes/index.ts and add it to the workflow graph in packages/agents/src/workflows/interview-prep.workflow.ts.
  5. Write a unit test in packages/agents/src/nodes/__tests__/.
  6. Update the Prisma schema if the output needs to be persisted.
  7. Update this README's agent table. ✍️

🚦 Pull Request Checklist

  • pnpm typecheck passes
  • pnpm test passes
  • New behavior is covered by tests
  • Prompts live in /prompts, schemas in packages/shared
  • No new vendor SDK imports outside packages/agents/src/providers
  • Docs/README updated where relevant
  • PR description explains the why, not just the what

πŸ› Reporting Bugs

Please include:

  • Reproduction steps
  • Expected vs. actual behavior
  • The affected agent run ID (so we can pull node-level logs)
  • Provider used (OpenAI / Anthropic / Groq / Gemini / Mock)

πŸ’‘ Feature Requests

Open a GitHub issue tagged enhancement and describe the user problem first, the proposed solution second.


πŸ“œ License

MIT Β© 2026 Shadab


Built with ❀️ for every job seeker who deserves a personal interview coach β€” not a generic chatbot.

About

LanGraph Multi Agents with Stop, Retry, Debug, Orchestration. Utilized Use of Job Seeker Canditate to prepare for Interviews with Agents. These Agents will automate the interview preparation for candidate by evaluating and mapping JD, Pain Points, Interview Questions Answer, Mock Interview

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages