Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ jobs:
working-directory: frontend

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- uses: pnpm/action-setup@v4
- uses: pnpm/action-setup@v6
with:
version: latest

- uses: actions/setup-node@v4
- uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
Expand Down Expand Up @@ -50,7 +50,7 @@ jobs:
working-directory: backend

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- uses: actions/setup-python@v5
with:
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ docs/ — project proposal and reference documents
- **Backend:** see [backend/README.md](backend/README.md)
- **Frontend:** see [frontend/README.md](frontend/README.md)

## Git hooks

Pre-push hooks run lint, formatting, and type checks before any push reaches GitHub. Install them once after cloning:

```bash
cd frontend
pnpm install
```

## Stack

| Layer | Technology |
Expand Down
6 changes: 3 additions & 3 deletions backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ async def lifespan(app: FastAPI):
allow_headers=["*"],
)

app.include_router(speech_router, prefix="/speech", tags=["speech"])
app.include_router(emotion_router, prefix="/emotion", tags=["emotion"])
app.include_router(llm_router, prefix="/feedback", tags=["feedback"])
app.include_router(speech_router, prefix="/speech", tags=["speech"])
app.include_router(emotion_router, prefix="/emotion", tags=["emotion"])
app.include_router(llm_router, prefix="/feedback", tags=["feedback"])
app.include_router(text_analysis_router, prefix="/analysis", tags=["analysis"])


Expand Down
5 changes: 3 additions & 2 deletions backend/services/tone_delivery_analyzer/emotion_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ def forward(self, input_values):
return hidden_states, logits


def load_emotion_model(model_name="audeering/wav2vec2-large-robust-12-ft-emotion-msp-dim",
device="cpu"):
def load_emotion_model(
model_name="audeering/wav2vec2-large-robust-12-ft-emotion-msp-dim", device="cpu"
):
"""Load processor + model once, return (processor, model, device)."""
processor = Wav2Vec2Processor.from_pretrained(model_name)
model = EmotionModel.from_pretrained(model_name).to(device).eval()
Expand Down
23 changes: 13 additions & 10 deletions backend/services/tone_delivery_analyzer/run_emotion.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ def predict_adv(signal, processor, model, device):
input_values = inputs.input_values.to(device)
with torch.no_grad():
embedding, logits = model(input_values)
adv = logits.squeeze().cpu().numpy() # shape (3,)
emb = embedding.squeeze().cpu().numpy() # shape (1024,)
adv = logits.squeeze().cpu().numpy() # shape (3,)
emb = embedding.squeeze().cpu().numpy() # shape (1024,)
# clamp the "approximately 0..1" outputs into a clean range
adv = np.clip(adv, 0.0, 1.0)
return adv, emb
Expand All @@ -39,12 +39,12 @@ def predict_adv(signal, processor, model, device):
def nearest_emotion(arousal, dominance, valence):
"""Rough VAD-region heuristic. Coordinates are illustrative, not official."""
prototypes = {
"anger": (0.85, 0.80, 0.15),
"fear": (0.80, 0.25, 0.20),
"joy": (0.80, 0.65, 0.85),
"sadness": (0.25, 0.30, 0.20),
"calm": (0.25, 0.50, 0.75),
"neutral": (0.50, 0.50, 0.50),
"anger": (0.85, 0.80, 0.15),
"fear": (0.80, 0.25, 0.20),
"joy": (0.80, 0.65, 0.85),
"sadness": (0.25, 0.30, 0.20),
"calm": (0.25, 0.50, 0.75),
"neutral": (0.50, 0.50, 0.50),
}
point = np.array([arousal, dominance, valence])
best, best_d = None, 1e9
Expand All @@ -61,8 +61,11 @@ def main():
sys.exit(1)
path = sys.argv[1]

device = "cuda" if torch.cuda.is_available() else (
"mps" if torch.backends.mps.is_available() else "cpu")
device = (
"cuda"
if torch.cuda.is_available()
else ("mps" if torch.backends.mps.is_available() else "cpu")
)
print(f"Device: {device}")
print("Loading model (first run downloads ~1GB)...")
processor, model, device = load_emotion_model(device=device)
Expand Down
2 changes: 2 additions & 0 deletions frontend/AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<!-- 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 -->
44 changes: 19 additions & 25 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,30 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
# Interview Coach — Frontend

## Getting Started
Next.js frontend for the Interview Coach platform.

First, run the development server:
## Setup

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
pnpm install
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.

## Learn More
This also installs the pre-push git hooks (via lefthook). Hooks run ESLint, Prettier, and TypeScript checks before any push reaches GitHub.

To learn more about Next.js, take a look at the following resources:
## Development

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
```bash
pnpm dev
```

## Deploy on Vercel
Open [http://localhost:3000](http://localhost:3000) in your browser.

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
## Scripts

Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
| Command | Description |
| ------------------- | -------------------- |
| `pnpm dev` | Start dev server |
| `pnpm build` | Production build |
| `pnpm lint` | Run ESLint |
| `pnpm format` | Fix formatting |
| `pnpm format:check` | Check formatting |
| `pnpm typecheck` | Run TypeScript check |
5 changes: 1 addition & 4 deletions frontend/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html
lang="en"
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
>
<html lang="en" className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}>
<body className="min-h-full flex flex-col">{children}</body>
</html>
);
Expand Down
11 changes: 5 additions & 6 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"typecheck": "tsc --noEmit",
"lint": "eslint",
"format:check": "prettier --check .",
"format": "prettier --write ."
"format": "prettier --write .",
"prepare": "lefthook install"
},
"dependencies": {
"next": "16.2.6",
Expand All @@ -23,11 +24,9 @@
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.2.6",
"lefthook": "^2.1.8",
"prettier": "^3",
"tailwindcss": "^4",
"typescript": "^5",
"prettier": "^3"
},
"pnpm": {
"onlyBuiltDependencies": ["sharp", "unrs-resolver"]
"typescript": "^5"
}
}
100 changes: 100 additions & 0 deletions frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions frontend/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ignoredBuiltDependencies:
- sharp
- unrs-resolver
allowBuilds:
lefthook: true
sharp: true
unrs-resolver: true
17 changes: 17 additions & 0 deletions lefthook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
pre-push:
commands:
frontend-lint:
root: frontend/
run: pnpm lint
frontend-format:
root: frontend/
run: pnpm format:check
frontend-typecheck:
root: frontend/
run: pnpm typecheck
backend-lint:
root: backend/
run: ruff check .
backend-format:
root: backend/
run: ruff format --check .
Loading