How rithesh24/ai-hiring-council works
1. Overall shape
This repo is a two-tier application: a FastAPI/Python backend that runs the hiring analysis pipeline, and a Next.js/TypeScript frontend that presents both a hiring dashboard and a live debate UI. The backend owns all candidate processing, LLM calls, persistence, and WebSocket event emission; the frontend is a thin real-time consumer of API and socket events.
2. Primary data flow
The core flow is: resume + job description upload → text extraction/parsing → external evidence gathering → multi-agent evaluation → debate rounds → moderator synthesis → database write → frontend display. The analysis is not a single model call; it is a staged orchestration pipeline with explicit handoff points between services, agents, and the moderator.
3. Backend API boundary
backend/api/routes exposes the system through REST endpoints for candidate analysis, dashboard history, debate state, and health checks, plus a WebSocket route for live updates. This is the main external boundary for the frontend. The API layer is intentionally thin and delegates work to services/orchestrators rather than embedding business logic.
4. Candidate ingestion and evidence collection
backend/services/resume_jd_parser.py, portfolio_scraper.py, and github_analyzer.py handle the input and evidence side. The pipeline extracts structured text from uploaded resume files, parses the job description, and scans for external links. The Evidence Agent runs before the debate and gathers GitHub/portfolio context that is shared with all other agents, so later judgments are evidence-informed rather than isolated text-only reasoning.
5. Agent layer
backend/agents contains six specialist evaluators plus a common base class. The agents are separated by hiring lens: technical, experience, culture, risk, growth, and problem solving. Each agent produces a score, strengths, concerns, and reasoning in Round 1 without seeing the others. The Risk Agent is intentionally inverted, where a higher score means lower risk, which affects how synthesis must interpret its output.
6. Debate orchestration
backend/orchestrator is the control plane for the multi-round council. council_graph.py, debate_rounds.py, moderator.py, and state_manager.py coordinate the sequence: independent evaluation, debate exchanges, reflection, and final synthesis. This layer also enforces hard behavioral constraints such as capped score revision and prevention of self-replies, so the model outputs are not followed blindly.
7. LLM and model routing
backend/core/groq_client.py and model_router.py isolate the LLM provider integration. The system uses Groq-hosted models for inference and performs sequential execution to avoid rate-limit collisions. Error handling includes retries/backoff and JSON parsing cleanup, which matters because the agents and moderator exchange structured outputs rather than free-form chat only.
8. Real-time streaming path
backend/services/ws_manager.py broadcasts analysis events over WebSocket as the debate progresses. These events include round starts, individual agent speaking turns, round completion, and final decision completion. The frontend subscribes to these events to animate the 3D council chamber, update the chat feed, and drive round progress indicators in near real time.
9. Persistence layer
database/db.py, models.py, and crud.py define a SQLite-backed audit trail for all candidate analyses. The stored record supports the dashboard’s history table, detail drawer, and summary statistics. This persistence boundary is important because it separates transient live debate state from the durable hiring history used for review later.
10. Frontend architecture
The frontend is a single-page App Router Next.js app with two main experiences: a hiring dashboard and a live debate view. frontend/components/dashboard handles upload, summary cards, history, and detail inspection; frontend/components/debate renders the 3D council chamber, live chat, and decision banner. Hooks like useCandidateAnalysis and useDebateSocket bridge the UI to the backend REST/WebSocket surfaces.
11. Cross-cutting utilities and runtime assumptions
backend/utils centralizes logging, text cleanup, and file handling, while the repo’s scripts package startup and model download steps. The stack is materially shaped by FastAPI + async SQLAlchemy/aiosqlite on the backend and React Three Fiber/Three.js on the frontend, because the system must support both asynchronous analysis and animated, event-driven visualization.
12. How to draw the architecture diagram
The most important boxes are: Frontend UI, FastAPI API/WebSocket layer, candidate parsing/evidence services, agent ensemble, debate orchestrator/moderator, Groq LLM API, SQLite database, and external sources like GitHub and portfolio sites. The key arrows are: upload request into analysis pipeline, evidence enrichment before agent evaluation, orchestrated agent-to-agent debate, live socket events to the UI, and final results persisted to the database.
Main entry points: candidate_analysis.py Analysis service · council_graph.py Council orchestrator · ws_manager.py WS manager · LiveDebate.tsx Debate UI
Components 18
Backend
FastAPI app, pipeline orchestration, model access, and persistence.
- FastAPI API · Main backend entrypoint exposing REST routes and WebSocket endpoints.
backend/main.py - Candidate routes · Endpoints for starting analyses and reading candidate-focused responses.
backend/api/routes/candidate_routes.py - Dashboard routes · Endpoints for history, summaries, and dashboard data retrieval.
backend/api/routes/dashboard_routes.py - Debate routes · Endpoints for debate state and live council interaction.
backend/api/routes/debate_routes.py - WebSocket routes · Live event stream endpoint consumed by the frontend.
backend/api/routes/ws_routes.py - Analysis service · Coordinates resume parsing, evidence gathering, debate orchestration, and persistence.
backend/services/candidate_analysis.py - Parsing service · Extracts structured text from resumes and parses job descriptions.
backend/services/resume_jd_parser.py - Evidence service · Collects GitHub and portfolio context before agent evaluation.
backend/services/github_analyzer.py - WS manager · Broadcasts round, agent, and completion events to connected clients.
backend/services/ws_manager.py - Agent ensemble · Independent hiring lenses that score the candidate before and during debate.
backend/agents/base_agent.py - Council orchestrator · Coordinates round sequencing, reflection, constraints, and final synthesis.
backend/orchestrator/council_graph.py - Model router · Routes structured prompts to Groq-hosted models and handles retries/parsing cleanup.
backend/core/model_router.py
Frontend
Next.js UI for dashboard and live debate views.
- Next.js app · App Router frontend that hosts the dashboard and live debate experience.
frontend/app/page.tsx - Dashboard UI · Upload, history, stats, and detail inspection for past analyses.
frontend/components/dashboard/Dashboard.tsx - Debate UI · 3D council chamber, chat, progress, and final decision display.
frontend/components/debate/LiveDebate.tsx - Analysis hook · Runs candidate analysis requests and manages dashboard-side loading state.
frontend/hooks/useCandidateAnalysis.ts - Socket hook · Subscribes the UI to debate events from the backend WebSocket stream.
frontend/hooks/useDebateSocket.ts
Data
Durable SQLite storage for candidate analyses and history.
- SQLite store · Durable audit trail for candidate analyses and dashboard history.
database/db.py
Connections 21
- Next.js app → Dashboard UI: renders · The app hosts the dashboard experience.
- Next.js app → Debate UI: renders · The app hosts the live debate experience.
- Dashboard UI → Analysis hook: requests analysis · Dashboard interactions trigger analysis requests through the hook.
- Debate UI → Socket hook: subscribes · Debate view listens for real-time council updates.
- Analysis hook → Candidate routes: calls · Client submits analysis and fetches candidate data via REST.
- Socket hook → WebSocket routes: connects · Client attaches to the backend WebSocket event stream.
- Candidate routes → Analysis service: delegates · Route layer hands work to the analysis pipeline.
- Dashboard routes → SQLite store: reads · Dashboard endpoints query stored analysis history and summaries.
- Debate routes → Council orchestrator: controls · Debate endpoints expose the live council state.
- WebSocket routes → WS manager: uses · WebSocket endpoints are backed by the broadcast manager.
- Analysis service → Parsing service: ingests · Pipeline begins by extracting resume and job text.
- Analysis service → Evidence service: enriches · Pipeline gathers external evidence before evaluation.
- Analysis service → Agent ensemble: evaluates · Specialist agents produce scores and reasoning.
- Analysis service → Council orchestrator: orchestrates · Council workflow is coordinated by the debate control plane.
- Analysis service → SQLite store: persists · Final analysis results are written to SQLite.
- Council orchestrator → Model router: calls · Rounds and moderation invoke Groq-backed model execution.
- Agent ensemble → Model router: uses · Agents depend on the shared model routing layer.
- Council orchestrator → WS manager: emits events · Council milestones are streamed to connected clients.
- Evidence service → Model router: analyzes · Evidence gathering may use model-assisted reasoning.
- WS manager → Debate UI: streams · Live events update the 3D council and chat in the UI.
- Analysis service → WS manager: publishes · Pipeline progress is broadcast as analysis runs.