Spaces:
Runtime error
Runtime error
| # InterviewCoach β Project Brief | |
| > Silent real-time coaching during interviews. Runs 100% local on your Mac. | |
| --- | |
| ## What It Does | |
| When user is in an interview, the app listens to the interviewer's question via mic β transcribes it β classifies the question type β displays a compact coaching card with the framework to follow. You glance at it, then answer. No cloud. No latency. No trace. | |
| APp will add if the question is asked by interviewer or candidate and also tags if answer is answered by the candidate or interviewer. If there is a low cofidence, flags for user updates later. | |
| As a second part, there is another agent who goes through the transcripts and rates the interview by adding critical feedbacks highlighting areas for improvements. | |
| --- | |
| ## Architecture | |
| LangGraph agentic pipeline. Each node is a discrete async function. State flows through the graph. | |
| ``` | |
| AudioNode β TranscriptNode β ClassifierAgent β FrameworkNode β UINode | |
| β | |
| EvaluationAgent (post-session) | |
| ``` | |
| --- | |
| ## Stack | |
| - **Framework**: LangGraph + LangChain | |
| - **LLM**: Qwen2.5 7B Instruct via Ollama (Part 1) / fine-tuned Qwen2.5 3B via llama.cpp (Part 2) | |
| - **STT**: mlx-whisper (whisper-small-mlx) | |
| - **UI**: Gradio with custom dark-mode CSS | |
| - **Database**: SQLite (via `aiosqlite` for async) | |
| - **Runtime**: Python 3.11+, Apple Silicon M1 Pro | |
| --- | |
| ## Coding Rules | |
| - All nodes and DB calls must be `async`/`await` β no blocking I/O on the main thread | |
| - Use `aiosqlite` for all database operations | |
| - Use `asyncio.Queue` for audio chunk passing between nodes | |
| - LangGraph state must be a typed `TypedDict` | |
| - Each agent/node lives in its own file under `agents/` | |
| --- | |
| ## Agents | |
| ### ClassifierAgent | |
| - Input: transcribed question string | |
| - Output: `{type: str, steps: list[str]}` | |
| - Uses Qwen2.5 7B Instruct with structured output prompt | |
| - Must return valid framework type β fallback to "General" if uncertain | |
| ### EvaluationAgent | |
| - Input: `{question: str, answer: str, framework: str, steps: list[str]}` | |
| - Output: `{steps_covered: list[bool], score: int, feedback: str}` | |
| - Runs post-session, not real-time | |
| - One evaluation card per Q&A exchange | |
| --- | |
| ## Database (SQLite) | |
| File: `interviews.db` | |
| ```sql | |
| sessions (id, date, company, role, duration) | |
| exchanges (id, session_id, question, answer, framework_used, timestamp) | |
| evaluations (id, exchange_id, steps_covered_json, score, feedback) | |
| transcripts (id, session_id, raw_text, labelled_json) | |
| patterns (framework, times_shown, avg_score, most_missed_step) | |
| ``` | |
| - All DB access via `aiosqlite` | |
| - Init schema on app startup if tables don't exist | |
| - Never block the event loop with synchronous sqlite3 calls | |
| --- | |
| ## Gradio UI | |
| - Dark mode custom CSS β no default Gradio theme | |
| - Three tabs: **Live** (coaching cards) Β· **Session Log** (transcript) Β· **Evaluate** (post-interview report) | |
| - Coaching cards: colour-coded by framework type, step-by-step list | |
| - Use `gr.Blocks` not `gr.Interface` | |
| - UI updates via async generator / `queue=True` | |
| --- | |
| ## File Structure | |
| ``` | |
| interview-coach/ | |
| βββ AGENTS.md | |
| βββ app.py # Gradio entry point | |
| βββ graph.py # LangGraph pipeline definition | |
| βββ state.py # TypedDict state schema | |
| βββ agents/ | |
| β βββ classifier.py # ClassifierAgent | |
| β βββ evaluator.py # EvaluationAgent | |
| βββ nodes/ | |
| β βββ audio.py # Whisper capture node | |
| β βββ transcript.py # Speaker labelling node | |
| β βββ framework.py # Framework lookup node | |
| βββ db/ | |
| β βββ schema.py # Table definitions + init | |
| β βββ queries.py # Async CRUD functions | |
| βββ frameworks.yaml # Question types + steps | |
| βββ prompts.py # All LLM prompt templates | |
| βββ data/ | |
| β βββ train.jsonl # Fine-tuning dataset | |
| βββ requirements.txt | |
| ``` | |
| --- | |
| ## Models | |
| - Part 1: `ollama pull qwen2.5:7b` | |
| - Part 2: fine-tuned Qwen2.5 3B via `mlx-lm` LoRA, exported to GGUF for llama.cpp | |
| - Swap model in one place only: `config.py` β `MODEL_PATH` | |
| --- | |