# Project export: Talkode

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: UC Berkeley AI Hackathon 2026
- Tagline: The software engineering OA, redefined with voice.
- Devpost: https://devpost.com/software/talkode
- GitHub: https://github.com/srimans573/talkode
- Video: https://www.youtube.com/embed/rx9TrGPFkEA?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 4 GitHub contributor(s) — Tanrocode (10 commits), srimans572 (8 commits), Claude Opus 4.8 (6 commits), rishit2121 (3 commits)

## Devpost submission (written by the team)

### Inspiration

Traditional coding interviews were built for a world where engineers wrote every line of code themselves. Modern-day engineers work alongside AI. The skills that matter most are problem decomposition, communication, system design, and the ability to guide and validate AI-generated code. Yet the technical assessment industry, dominated by platforms such as HackerRank and CodeSignal, remains largely unchanged. These assessments continue to emphasize data structures and algorithm exercises that can often be optimized through extensive practice, memorization, and pattern recognition. As a result, these evaluations capture only a narrow slice of the skills that drive success in modern software engineering. This limitation becomes especially problematic for hiring teams reviewing thousands of applicants per role. A single numerical score or pass/fail threshold reveals little about a candidate's ability to collaborate, navigate unfamiliar codebases, communicate technical decisions, or solve the kinds of open-ended problems they will encounter on the job. What We Built We built Talkode - the voice-first online assessment for software engineering roles. Talkode gives hiring teams a holistic view of how candidates think, communicate, and solve real engineering problems, as they would at the job. Instead of answering isolated algorithm questions, candidates work through realistic technical scenarios while speaking naturally with an AI agent. The platform generates custom codebases and role-specific challenges tailored to a company's tech stack and hiring requirements. Throughout the assessment, Talkode evaluates the following, for example: Problem decomposition and reasoning Technical communication and collaboration System design decision-making Codebase navigation and debugging Code quality, validation, and tradeoff analysis The result is a rich candidate profile that goes far beyond a single score of passed test cases, helping hiring teams identify engineers who can succeed in modern, AI-assisted development environments. Key Features Voice-First AI Technical Assessment Candidates engage in natural, conversational technical interviews rather than typing answers into a coding assessment. Talkode evaluates how candidates communicate ideas, explain tradeoffs, and reason through complex engineering problems in real time. Custom AI-Generated Codebases Hiring teams can upload job descriptions, technical requirements, and company context. Talkode automatically generates realistic codebases and project scenarios tailored to the role being hired for. Rich Assessment Reports for Hiring Team Hiring teams receive detailed candidate profiles containing interview transcripts, reasoning summaries, technical strengths and weaknesses, solution approaches, and AI-generated evaluation insights. How We Built It Our team used React/Next.js for the Frontend, Python FastAPI for the Backend, and Supabase as the database to store and fetch relevant information. We used three main Sponsor Technologies: Deepgram, The Token Company, and Redis. Deepgram powered our main voice agent, which is the heart of the project. We used Deepgram's text-to-speech and speech-to-text technologies to give voice to Talkode's AI voice agent and understand candidate speech, respectively. Deepgram was used extensively to conduct full 30-minute assessments as dry runs, resulting in low latency throughout. The Token Company's token compression tool was a key technology that helped compress the thousands of tokens that had to be continuously fed as context over long time periods, ranging from 20-60 minutes. The technology helped us extract the key thinking from the candidates, making it fair for candidates who have trouble using many filler words. Redis served as an AI memory layer to maintain short-term context during interviews, storing recent transcript chunks, candidate responses, and tool outputs for fast retrieval. This allowed the AI interviewer to "remember" what had just been said without repeatedly querying slower persistent storage or rebuilding context from scratch. By keeping this working memory in Redis with TTL-based expiration, each session stayed both coherent and cost-efficient while scaling to many concurrent interviews. The result was a more fluid, human-like conversation where the AI could reference prior moments in real time without losing state. Challenges The biggest challenge we faced was making the interview flow feel natural and smooth, especially in a voice-first, AI-driven environment where latency and context transitions can easily break the sense of conversation. We had to carefully design how the AI maintained memory, structured follow-ups, and transitioned between questions to preserve conversational continuity while still evaluating structured technical skills. Beyond the technical side, the harder problem was trust and credibility. How do you convince a hiring manager that a candidate coming out of the platform is actually strong? It's easy to list traits like problem decomposition, systems thinking, or tradeoff reasoning, but much harder to ground those in something concrete and auditable, like actual moments in a transcript that justify a score. We ended up rewriting the evaluation rubric multiple times, working with mentors and engineers we met along the way, to build a baseline that is explainable by default and can still be customized by each company. What we are proud of Built a working voice-first technical interview system end-to-end in a short time frame Designed an interview flow that feels natural and conversational, even under real-time AI constraints Successfully reduced awkward pauses and context loss, making interactions feel much more human Developed an evaluation approach that ties scores back to actual transcript evidence, improving transparency and trust Iterated on the rubric with input from mentors and engineers to make it more grounded and explainable Turned an initial concept into a usable product experience that hiring teams can actually explore and test

### What's next

? Anti-cheating + interview integrity layer Our next biggest step is building robust anti-cheating systems to ensure interview authenticity. Since this was a hackathon project, we didn’t have time to fully implement safeguards like behavioral anomaly detection, environment monitoring, or AI-assisted answer validation. However, we want to continue working on this project and hope to implement anti-cheat measures in the near future. Richer codebase generation Expand support for more languages, frameworks, and real-world engineering environments so companies can simulate the exact tech stack they hire for (e.g., React + Node, distributed systems, data pipelines, etc.). Deeper assessment customization Allow companies to fully customize the interview experience, including the AI interviewer’s personality, tone, difficulty level, and evaluation focus areas. Enterprise readiness + integrations Integrate with ATS platforms (like Greenhouse or Ashby) and support enterprise-grade compliance, analytics, and candidate tracking.

## README (from the GitHub repository)

# Talkode

AI-guided pre-OA technical screening for recruiter and hiring manager workflows.

## Local Setup

Install dependencies:

```bash
npm ci
```

Create `.env.local`:

```bash
NEXT_PUBLIC_SUPABASE_URL=YOUR_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=YOUR_SUPABASE_PUBLISHABLE_KEY
NEXT_PUBLIC_SITE_URL=http://localhost:3000
```

Apply the Supabase migration in `supabase/migrations` before using auth. It creates recruiter-only profile tables, row level security, and an auth trigger that accepts only `recruiter` and `manager` roles from signup metadata.

Run the app:

```bash
npm run dev
```

Open `http://localhost:3000/auth`.


## Detected evidence (automated analysis)

Indexed codebase: 104 recognized source files, 560 KB.
- Anthropic (technology) — detected in the code
- CSS (language) — detected in the code
- FastAPI (technology) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Redis (technology) — detected in the code
- SQL (language) — detected in the code
- Supabase (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- AI coding agent: Claude Code — evidence: config files committed to the repository; commit authorship or trailers
- AI coding agent: Codex — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (114 of 114)

```
.gitignore
AGENTS.md
app/assessment/actions.ts
app/assessment/CandidateAssessmentFlow.tsx
app/assessment/CodeEditor.tsx
app/assessment/InterviewWorkspace.tsx
app/assessment/page.tsx
app/assessment/results/page.tsx
app/assessment/useInterviewSession.ts
app/auth/actions.ts
app/auth/auth-form.tsx
app/auth/form-state.ts
app/auth/page.tsx
app/book-demo/page.tsx
app/dashboard/actions.ts
app/dashboard/assessments/[id]/EditAssessmentForm.tsx
app/dashboard/assessments/[id]/page.tsx
app/dashboard/assessments/new/CreateAssessmentForm.tsx
app/dashboard/assessments/new/page.tsx
app/dashboard/assessments/page.tsx
app/dashboard/candidates/[id]/page.tsx
app/dashboard/candidates/page.tsx
app/dashboard/data.ts
app/dashboard/layout.tsx
app/dashboard/page.tsx
app/globals.css
app/landing/LandingPage.tsx
app/layout.tsx
app/page.tsx
backend/data/leetcode_problems.json
backend/main.py
backend/models/schemas.py
backend/requirements.txt
backend/routers/challenge.py
backend/routers/codebase.py
backend/routers/dashboard.py
backend/routers/interview.py
backend/routers/rubric.py
backend/routers/session_end.py
backend/routers/session.py
backend/routers/snapshot.py
backend/routers/video.py
backend/services/agent.py
backend/services/challenge_picker.py
backend/services/codebase_generator.py
backend/services/detector.py
backend/services/insight_extractor.py
backend/services/merger.py
backend/services/pipeline.py
backend/services/redis_client.py
backend/services/storage.py
backend/services/test_generator.py
backend/services/test_runner.py
backend/services/tts.py
CLAUDE.md
components/auth/AuthForm.tsx
components/dashboard/CandidateDetail.tsx
components/dashboard/CandidatesExplorer.tsx
components/dashboard/CodebaseFilesModal.tsx
components/dashboard/DashboardShell.tsx
components/dashboard/InvitePanel.tsx
components/dashboard/RubricBar.tsx
deno.lock
eslint.config.mjs
lib/auth/roles.ts
lib/database.types.ts
lib/email.ts
lib/supabase/client.ts
lib/supabase/config.ts
lib/supabase/proxy.ts
lib/supabase/server.ts
lib/voiceAgent.ts
mock-codebases/employee-directory-dashboard/backend/app.py
mock-codebases/employee-directory-dashboard/backend/data/employees.py
mock-codebases/employee-directory-dashboard/backend/requirements.txt
mock-codebases/employee-directory-dashboard/README.md
mock-codebases/employee-directory-dashboard/rubric.md
mock-codebases/employee-directory-dashboard/src/api.js
mock-codebases/employee-directory-dashboard/src/components/EmployeeCard.jsx
mock-codebases/employee-directory-dashboard/src/components/SearchBar.jsx
mock-codebases/employee-directory-dashboard/src/components/StatsPanel.jsx
mock-codebases/employee-directory-dashboard/src/EmployeeDashboard.jsx
mock-codebases/employee-directory-dashboard/src/hooks/useEmployees.js
mock-codebases/employee-directory-dashboard/src/utils/employeeUtils.js
netlify.toml
next.config.ts
package.json
plan-mds/end_to_end_flow.md
plan-mds/hr_dashboard_spec.md
plan-mds/project_brief_with_agent.md
postcss.config.mjs
proxy.ts
README.md
rubrics/employee-directory.md
supabase/migrations/20260522193000_recruiter_auth.sql
supabase/migrations/20260620120000_assessments_candidates.sql
supabase/migrations/20260620133000_assessment_creation_codebases.sql
supabase/migrations/20260620143000_assessment_codes_and_multiselect_technologies.sql
supabase/migrations/20260620150000_employee_directory_backend_files.sql
supabase/migrations/20260620160000_candidate_assessment_access.sql
supabase/migrations/20260620170000_rubric_public_read.sql
supabase/migrations/20260621100000_fix_candidate_assessment_clock.sql
supabase/migrations/20260629090000_return_rubric_text_on_register.sql
supabase/migrations/20260630010000_backfill_assessment_rubric_text.sql
supabase/migrations/20260630020000_add_rubric_topics.sql
supabase/migrations/20260630030000_assessment_update_policy.sql
supabase/migrations/20260630040000_assessment_update_more_fields.sql
supabase/migrations/20260630050000_add_codebase_generation.sql
supabase/migrations/20260630060000_grant_codebase_insert.sql
supabase/migrations/20260630070000_fix_files_insert_rls.sql
supabase/migrations/20260630080000_assessment_invites.sql
supabase/migrations/20260701000000_candidate_completion.sql
supabase/migrations/20260708120000_trim_mock_rubric_to_25min.sql
tsconfig.json
```

### Dependencies

- backend/requirements.txt: anthropic@==0.40.0, deepgram-sdk@==3.7.7, fastapi@==0.115.5, httpx@==0.27.2, openai@==1.58.1, pydantic@==2.10.3, python-dotenv@==1.0.1, python-multipart@==0.0.20, redis@==5.2.1, sse-starlette@==2.1.3, the-token-company@==0.3.2, uvicorn[standard]@==0.32.1, websockets@==13.1
- mock-codebases/employee-directory-dashboard/backend/requirements.txt: fastapi@==0.115.6, uvicorn@==0.34.0
- package.json: @supabase/ssr@^0.10.3, @supabase/supabase-js@^2.106.1, @tailwindcss/postcss@^4, @types/node@^20, @types/nodemailer@^8.0.1, @types/prismjs@^1.26.6, @types/react@^19, @types/react-dom@^19, eslint@^9, eslint-config-next@16.2.6, lucide-react@^1.16.0, marked@^18.0.5, next@16.2.6, nodemailer@^9.0.3, prismjs@^1.30.0, react@19.2.4, react-dom@19.2.4, resend@^6.16.0, tailwindcss@^4, typescript@^5

### Recent commits (newest first)

- Make coding challenge framing specific to the actual conversation
- Fix agent topic repetition: stage only advances on affirmed answers
- Fix agent echo loop: mic grace period, dedup, and echo detection
- Fix results page score display: correct color/label thresholds and show overall out of category count
- Fix interview quality: harness hardening, interrupt, nudging, grading calibration, 25-min mock
- Add code execution for coding challenges, mute button, and UI polish
- Fix agent ending interview on mid-task "done" phrases
- Add public demo assessment flow, results page, and same-name candidate fix
- Switch email sending from Resend to Gmail/Nodemailer
- Fix InvitePanel showing name twice instead of email as subtitle
- Add per-candidate invite system, fix interview completion tracking, and clickable candidates
- fixed scrolling animation bugs
- Merge branch 'feature/agent-driven-coding-challenge'
- Add per-assessment codebase generation, fix React tech label, and fix post-challenge resumption
- Merge pull request #4 from srimans573/landing-page
- added private beta notifs
- Add hiring-manager edit capability for assessments
- Merge pull request #3 from srimans573/landing-page
- Fix missing rubric scorecard by deploying rubric_text RPC field and categorizing rubric topics once at creation
- Open with the rubric's first question and gate the coding-challenge pause on demonstrated understanding

## Key source files (fetched from GitHub, selected and truncated for size)

### CLAUDE.md

```markdown
@AGENTS.md

```

### AGENTS.md

```markdown
<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->

```

### package.json

```
{
  "name": "talkode",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint"
  },
  "dependencies": {
    "@supabase/ssr": "^0.10.3",
    "@supabase/supabase-js": "^2.106.1",
    "@types/nodemailer": "^8.0.1",
    "lucide-react": "^1.16.0",
    "marked": "^18.0.5",
    "next": "16.2.6",
    "nodemailer": "^9.0.3",
    "prismjs": "^1.30.0",
    "react": "19.2.4",
    "react-dom": "19.2.4",
    "resend": "^6.16.0"
  },
  "devDependencies": {
    "@tailwindcss/postcss": "^4",
    "@types/node": "^20",
    "@types/prismjs": "^1.26.6",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "eslint": "^9",
    "eslint-config-next": "16.2.6",
    "tailwindcss": "^4",
    "typescript": "^5"
  }
}

```

### backend/requirements.txt

```
fastapi==0.115.5
uvicorn[standard]==0.32.1
websockets==13.1
deepgram-sdk==3.7.7
anthropic==0.40.0
redis==5.2.1
python-dotenv==1.0.1
sse-starlette==2.1.3
httpx==0.27.2
pydantic==2.10.3
python-multipart==0.0.20
openai==1.58.1
the-token-company==0.3.2

```

### mock-codebases/employee-directory-dashboard/backend/requirements.txt

```
fastapi==0.115.6
uvicorn==0.34.0

```

### app/page.tsx

```typescript
import LandingPage from './landing/LandingPage'

export default function Home() {
  return <LandingPage />
}

```

### app/layout.tsx

```typescript
import type { Metadata } from "next";
import { Plus_Jakarta_Sans } from "next/font/google";
import "./globals.css";

const plusJakartaSans = Plus_Jakarta_Sans({
  variable: "--font-plus-jakarta",
  subsets: ["latin"],
  display: "swap",
});

export const metadata: Metadata = {
  title: "Talkode",
  description: "Recruiter access for AI-guided technical screening.",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html
      lang="en"
      className={`${plusJakartaSans.variable} h-full antialiased`}
    >
      <body className="min-h-full flex flex-col">{children}</body>
    </html>
  );
}

```

### backend/main.py

```python
import os
from contextlib import asynccontextmanager

from dotenv import load_dotenv
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

load_dotenv()

from services.redis_client import ping
from routers import session, interview, snapshot, session_end, dashboard, video, challenge, rubric, codebase


@asynccontextmanager
async def lifespan(app: FastAPI):
    if not await ping():
        raise RuntimeError("Redis connection failed on startup")
    print("Redis connected")
    yield


app = FastAPI(title="Talkode Voice Agent API", lifespan=lifespan)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
)


app.include_router(session.router)
app.include_router(interview.router)
app.include_router(snapshot.router)
app.include_router(session_end.router)
app.include_router(dashboard.router)
app.include_router(video.router)
app.include_router(challenge.router)
app.include_router(rubric.router)
app.include_router(codebase.router)


@app.get("/health")
async def health():
    redis_ok = await ping()
    return {"status": "ok", "redis": redis_ok}

```

### app/book-demo/page.tsx

```typescript
import { redirect } from "next/navigation";

export default function BookDemoPage() {
  redirect("/auth");
}

```

### app/dashboard/layout.tsx

```typescript
import type { ReactNode } from "react";
import { DashboardShell } from "@/components/dashboard/DashboardShell";

export default function DashboardLayout({ children }: { children: ReactNode }) {
  return <DashboardShell>{children}</DashboardShell>;
}

```

[93 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]