बनाने की गाइड
इस गाइड में
EchoPanel
Coordinated AI Interview Panel — an adaptive voice interview platform where multiple role-based AI interviewers (Technical, Product/Business, Behavioural, Customer, Hiring Manager) run a single live voice session, share candidate context, and challenge each other's conclusions the way a real human panel would.
Built for EchoSphere 2026 (Round II) — PS11: Coordinated AI Interview Panel.
New to this project? Read ARCHITECTURE.md first.
It walks through the whole system end to end — what problem it solves, how
one interview turn flows through every file, why the Context Graph exists,
and what's real vs. what still needs your Agora/OpenAI credentials. This
README is the quick-start; that document is the actual explanation.
How it fits together
This is one project with two halves that talk to each other over HTTP:
EchoPanel/
├── backend/ FastAPI service — the reasoning layer (Context Graph,
│ Turn Arbiter, personas, difficulty control, reports).
│ Also exposes the tool-calling hooks Agora's
│ Conversational AI Engine invokes mid-call.
├── android/ Kotlin + Jetpack Compose client — Clean Architecture,
│ Hilt DI. Runs the live voice call via Agora's SDK and
│ renders the transcript, AI-disclosure banner, and
│ final report.
├── Makefile One place to install, test, and run the backend.
└── setup.sh First-time setup for the backend virtualenv + .env.Agora's Conversational AI Engine is the third leg: it owns real-time
ASR, sub-second-latency audio, noise suppression, and native interruption
during the call. Our backend is the "brain" it calls into via tool-calling
hooks (POST /agora/turn, POST /agora/greeting) to decide what each
persona says next; our Android app is the client that joins the Agora
channel and displays what's happening.
Candidate (Android app, mic via Agora SDK)
│
▼
Agora Conversational AI Engine ──(ASR text)──► EchoPanel backend
│ │ Context Graph
│ │ Turn Arbiter
│ │ Persona (LLM)
▼ │ Difficulty Controller
Agora TTS ◄──────────(spoken_text)─────────────┘
│
▼
Candidate hears the next persona's questionQuick start
1. Backend
./setup.sh # creates .venv, installs deps, copies .env.example → .env
# edit backend/.env with your OPENAI_API_KEY and Agora credentials
make run # starts the API at http://localhost:8000
make test # runs the backend test suiteInteractive API docs once running: http://localhost:8000/docs
2. Android app
Open android/ in Android Studio — it builds with the included Gradle
wrapper, no local Gradle install needed.
- Emulator/device talking to a backend on your machine: the default
BACKEND_BASE_URL(http://10.0.2.2:8000/) already points at the emulator's host-loopback address. - Physical device: change
BACKEND_BASE_URLinandroid/app/build.gradle.ktsto your machine's LAN IP. - Add your
AGORA_APP_IDin the same file once you've created an app in the Agora console.
3. Try it end-to-end
make run(backend)- Run the Android app (emulator is fine for the UI/API flow; a real device is needed to test live mic audio through Agora)
- Start a session → accept the AI-disclosure consent dialog → the app joins the Agora channel and the panel begins
What's implemented vs. what needs your credentials
| Piece | Status |
|---|---|
| Context Graph, Turn Arbiter, difficulty control, contradiction/vagueness detection | ✅ implemented, unit-tested |
| 5 personas (Technical, Product/Business, Behavioural, Customer, Hiring Manager) | ✅ implemented |
| Evidence-linked final report | ✅ implemented |
| AI-disclosure banner + consent flow | ✅ implemented (Compose UI + backend consent logging) |
| Cheating/integrity detection (text signals + client-reported video/audio signals) | ✅ implemented, unit-tested — see services/cheating_detector.py |
| On-device face-count/gaze + app-background proctoring signals | ✅ implemented — android/.../data/proctoring/FaceProctoringAnalyzer.kt |
| Shared live script panel (AI-suggested + interviewer's own questions) | ✅ implemented — api/script.py + presentation/interview/ProctoringAndScriptComponents.kt |
| OpenAI-backed persona reasoning | ✅ implemented — needs your OPENAI_API_KEY |
| Live Agora voice call (ASR/TTS/interruption) | ✅ via the Agora Agents SDK (agora-agents) — needs AGORA_APP_ID + AGORA_APP_CERTIFICATE |
| Agora token server endpoint | ✅ implemented — POST /agora/token/{session_id} |
| Auth on backend endpoints | ⬜ not implemented — anyone with a session ID can call any endpoint; fine for a hackathon demo, not for production |
Cheating detection & the shared script panel
Two additions layer on top of the core panel without changing its shape:
- Cheating/integrity detection (
backend/app/services/cheating_detector.py) runs two kinds of check. Text signals (a sudden jump from halting to polished answers, copy-paste-style formatting, an answer that arrives implausibly fast for its length) are computed server-side on every turn, no client cooperation needed. Client signals (multiple faces on camera, no face visible, sustained gaze away from the screen, a second voice detected, app backgrounded, screen mirroring) are detected on-device by the Android app and reported as small structured signals — never raw audio or video — viaPOST /proctoring/{session_id}/signal. Signals accumulate into evidence-linkedCheatFlags: every flag traces back to the exact signals that raised it, the same evidence-linked philosophy as the final report'sVerdictItems. Both the interviewer's screen and the candidate's own screen poll the sameGET /proctoring/{session_id}/status, so nobody sees a different picture of what was flagged — consistent with the project's transparency-by-design stance. - Shared live script panel (
backend/app/api/script.py) is a running list of next-questions both interviewer and candidate see identically. Entries are either AI-suggested (grounded in the same Context Graph slice the personas already use, viagenerate_suggested_questions()) or typed live by the human interviewer — both land in the same shared list viaPOST /script/{session_id}/custom.
Repo map (details)
backend/app/models/schemas.py— Context Graph, claims, sessions, reportsbackend/app/services/turn_arbiter.py— who speaks next, including the PS11 example scenario (Product independently challenges an unchallenged Technical claim)backend/app/services/contradiction_detector.py— vagueness + contradiction flags, computed before scoringbackend/app/services/difficulty_controller.py— rolling competence → recall/applied/edge_casebackend/app/personas/— per-role system prompts + OpenAI callsbackend/app/api/agora_hooks.py— the endpoints Agora's engine calls mid-interviewbackend/tests/test_services.py— includes a dedicated test for the PS11 example scenarioandroid/app/src/main/java/com/echopanel/app/—domain/(pure Kotlin),data/(Retrofit + Agora SDK),presentation/(Compose screens + ViewModels),di/(Hilt)
# EchoPanel
**Coordinated AI Interview Panel** — an adaptive voice interview platform where
multiple role-based AI interviewers (Technical, Product/Business, Behavioural,
Customer, Hiring Manager) run a single live voice session, share candidate
context, and challenge each other's conclusions the way a real human panel
would.
Built for EchoSphere 2026 (Round II) — PS11: Coordinated AI Interview Panel.
**New to this project? Read [`ARCHITECTURE.md`](https://github.com/madhuri-sharma921/EchoPanel/blob/main/ARCHITECTURE.md) first.**
It walks through the whole system end to end — what problem it solves, how
one interview turn flows through every file, why the Context Graph exists,
and what's real vs. what still needs your Agora/OpenAI credentials. This
README is the quick-start; that document is the actual explanation.
## How it fits together
This is one project with two halves that talk to each other over HTTP:
```
EchoPanel/
├── backend/ FastAPI service — the reasoning layer (Context Graph,
│ Turn Arbiter, personas, difficulty control, reports).
│ Also exposes the tool-calling hooks Agora's
│ Conversational AI Engine invokes mid-call.
├── android/ Kotlin + Jetpack Compose client — Clean Architecture,
│ Hilt DI. Runs the live voice call via Agora's SDK and
│ renders the transcript, AI-disclosure banner, and
│ final report.
├── Makefile One place to install, test, and run the backend.
└── setup.sh First-time setup for the backend virtualenv + .env.
```
**Agora's Conversational AI Engine is the third leg**: it owns real-time
ASR, sub-second-latency audio, noise suppression, and native interruption
during the call. Our backend is the "brain" it calls into via tool-calling
hooks (`POST /agora/turn`, `POST /agora/greeting`) to decide what each
persona says next; our Android app is the client that joins the Agora
channel and displays what's happening.
```
Candidate (Android app, mic via Agora SDK)
│
▼
Agora Conversational AI Engine ──(ASR text)──► EchoPanel backend
│ │ Context Graph
│ │ Turn Arbiter
│ │ Persona (LLM)
▼ │ Difficulty Controller
Agora TTS ◄──────────(spoken_text)─────────────┘
│
▼
Candidate hears the next persona's question
```
## Quick start
### 1. Backend
```bash
./setup.sh # creates .venv, installs deps, copies .env.example → .env
# edit backend/.env with your OPENAI_API_KEY and Agora credentials
make run # starts the API at http://localhost:8000
make test # runs the backend test suite
```
Interactive API docs once running: http://localhost:8000/docs
### 2. Android app
Open `android/` in Android Studio — it builds with the included Gradle
wrapper, no local Gradle install needed.
- Emulator/device talking to a backend on your machine: the default
`BACKEND_BASE_URL` (`http://10.0.2.2:8000/`) already points at the
emulator's host-loopback address.
- Physical device: change `BACKEND_BASE_URL` in `android/app/build.gradle.kts`
to your machine's LAN IP.
- Add your `AGORA_APP_ID` in the same file once you've created an app in the
[Agora console](https://console.agora.io).
### 3. Try it end-to-end
1. `make run` (backend)
2. Run the Android app (emulator is fine for the UI/API flow; a real device
is needed to test live mic audio through Agora)
3. Start a session → accept the AI-disclosure consent dialog → the app joins
the Agora channel and the panel begins
## What's implemented vs. what needs your credentials
| Piece | Status |
|---|---|
| Context Graph, Turn Arbiter, difficulty control, contradiction/vagueness detection | ✅ implemented, unit-tested |
| 5 personas (Technical, Product/Business, Behavioural, Customer, Hiring Manager) | ✅ implemented |
| Evidence-linked final report | ✅ implemented |
| AI-disclosure banner + consent flow | ✅ implemented (Compose UI + backend consent logging) |
| Cheating/integrity detection (text signals + client-reported video/audio signals) | ✅ implemented, unit-tested — see `services/cheating_detector.py` |
| On-device face-count/gaze + app-background proctoring signals | ✅ implemented — `android/.../data/proctoring/FaceProctoringAnalyzer.kt` |
| Shared live script panel (AI-suggested + interviewer's own questions) | ✅ implemented — `api/script.py` + `presentation/interview/ProctoringAndScriptComponents.kt` |
| OpenAI-backed persona reasoning | ✅ implemented — needs your `OPENAI_API_KEY` |
| Live Agora voice call (ASR/TTS/interruption) | ✅ via the [Agora Agents SDK](https://github.com/AgoraIO/agora-agents-python) (`agora-agents`) — needs `AGORA_APP_ID` + `AGORA_APP_CERTIFICATE` |
| Agora token server endpoint | ✅ implemented — `POST /agora/token/{session_id}` |
| Auth on backend endpoints | ⬜ not implemented — anyone with a session ID can call any endpoint; fine for a hackathon demo, not for production |
## Cheating detection & the shared script panel
Two additions layer on top of the core panel without changing its shape:
- **Cheating/integrity detection** (`backend/app/services/cheating_detector.py`) runs two kinds of check. Text signals (a sudden jump from halting to polished answers, copy-paste-style formatting, an answer that arrives implausibly fast for its length) are computed server-side on every turn, no client cooperation needed. Client signals (multiple faces on camera, no face visible, sustained gaze away from the screen, a second voice detected, app backgrounded, screen mirroring) are detected **on-device** by the Android app and reported as small structured signals — never raw audio or video — via `POST /proctoring/{session_id}/signal`. Signals accumulate into evidence-linked `CheatFlag`s: every flag traces back to the exact signals that raised it, the same evidence-linked philosophy as the final report's `VerdictItem`s. Both the interviewer's screen and the candidate's own screen poll the same `GET /proctoring/{session_id}/status`, so nobody sees a different picture of what was flagged — consistent with the project's transparency-by-design stance.
- **Shared live script panel** (`backend/app/api/script.py`) is a running list of next-questions both interviewer and candidate see identically. Entries are either AI-suggested (grounded in the same Context Graph slice the personas already use, via `generate_suggested_questions()`) or typed live by the human interviewer — both land in the same shared list via `POST /script/{session_id}/custom`.
## Repo map (details)
- `backend/app/models/schemas.py` — Context Graph, claims, sessions, reports
- `backend/app/services/turn_arbiter.py` — who speaks next, including the
PS11 example scenario (Product independently challenges an unchallenged
Technical claim)
- `backend/app/services/contradiction_detector.py` — vagueness + contradiction flags, computed before scoring
- `backend/app/services/difficulty_controller.py` — rolling competence → recall/applied/edge_case
- `backend/app/personas/` — per-role system prompts + OpenAI calls
- `backend/app/api/agora_hooks.py` — the endpoints Agora's engine calls mid-interview
- `backend/tests/test_services.py` — includes a dedicated test for the PS11 example scenario
- `android/app/src/main/java/com/echopanel/app/` — `domain/` (pure Kotlin), `data/` (Retrofit + Agora SDK), `presentation/` (Compose screens + ViewModels), `di/` (Hilt)