Skip to content
Open
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Build a production-style voice agent with a Next.js web client and Python FastAP
- [Bun](https://bun.sh/)
- [Agora CLI](https://github.com/AgoraIO/cli)

On Windows, install Python on `PATH` as `python` or use the Python launcher (`py -3`). The root `bun run ...` scripts create and use `server/venv` without requiring `bash`, `python3`, or POSIX `source`.

## Run It

Install the CLI (skip if already installed), scaffold the Python quickstart, install dependencies, and run.
Expand Down
2 changes: 1 addition & 1 deletion docs/ai/L0_repo_card.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
| Language | Python 3.10+ (FastAPI + uvicorn) backend + Next.js 16 / React 19 web |
| Deploy Target | `web/` as Next.js app, `server/` as a reachable FastAPI service |
| Owner | Agora Conversational AI DevEx |
| Last Reviewed | 2026-06-11 |
| Last Reviewed | 2026-08-12 |
| Recipe Role | `base` |
| Recipe Version | `1.0.0` |
| Recipe Status | `experimental` |
Expand Down
16 changes: 9 additions & 7 deletions docs/ai/L1/01_setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

- **Python** ≥ 3.10 (README + `server/README.md`).
- **bun** as the JS toolchain (root `package.json` scripts and root `bun.lock`).
- **pip** + `venv` for Python dependencies. No `pyproject.toml` is present.
- **pip** + `venv` for Python dependencies. No `pyproject.toml` is present. Root scripts use `python3`/`python` on Unix and `python`/`py -3` on Windows.
- Agora project with App ID + App Certificate.

## Install

```bash
bun install # JS deps for the workspace, including web/
cd server
python3 -m venv venv # canonical name; matches package.json scripts
python3 -m venv venv # Unix; use python -m venv venv on Windows
source venv/bin/activate
pip install -r requirements.txt
```
Expand All @@ -28,6 +28,8 @@ bun run setup

`setup:env` copies `server/.env.example` → `server/.env.local` if missing. `setup:backend` recreates `server/venv`, upgrades pip, and installs `requirements.txt`. `setup:frontend` runs `bun install`. `setup:deps` exists for `bun run dev:check`, not for `bun run setup`.

Root `package.json` delegates filesystem, venv, Python, env-var injection, and cleanup steps to `scripts/run.mjs` so the same commands work in POSIX shells and Windows PowerShell/cmd.

> The package.json scripts use `server/venv/` (no leading dot). `bun run dev:backend` activates `server/venv` and runs `python src/server.py` from inside `server/`. If you create the venv under a different name you'll need to adjust the scripts or symlink.

## Environment Variables
Expand Down Expand Up @@ -75,10 +77,10 @@ The SDK is lower-bounded at v2 — add an upper bound or exact pin if you need r

```bash
bun run dev # setup:env → setup:deps → concurrently {backend, frontend}
bun run dev:backend # python3 server/src/server.py
bun run dev:frontend # cd web && AGENT_BACKEND_URL=http://localhost:8000 bun run dev
bun run dev:backend # creates/reuses server/venv and runs server/src/server.py
bun run dev:frontend # starts web with AGENT_BACKEND_URL=http://localhost:8000
bun run doctor # bun + node_modules sanity
bun run doctor:local # adds python3 + .env.local + AGORA_* presence
bun run doctor:local # adds Python + .env.local + AGORA_* presence
bun run build # bun --filter web build
bun run verify # doctor + verify:web:api + verify:web:build
bun run verify:local # doctor:local + verify:backend + verify:local:fastapi + verify:web:proxy + verify:web:build
Expand All @@ -96,7 +98,7 @@ bun run clean # remove backend venv, node_modules, .next, web/d
| Command | Live Agora? | Notes |
| ----------------------------- | ----------- | ---------------------------------------------------- |
| `bun run doctor` | No | bun + node_modules sanity |
| `bun run doctor:local` | No | Adds python3 + env presence |
| `bun run doctor:local` | No | Adds Python + env presence |
| `bun run verify:web:api` | No | Contract harness with mocked SDK |
| `bun run verify:web:proxy` | No | Static fake-server smoke |
| `bun run verify:local:fastapi`| No | Boots `server/scripts/run_fake_server.py` |
Expand All @@ -106,7 +108,7 @@ bun run clean # remove backend venv, node_modules, .next, web/d

## Common Setup Failures

- `bun run doctor:local` fails on **"python3 not found"** → install Python ≥ 3.10.
- `bun run doctor:local` fails on **"Python 3.10+ was not found"** → install Python ≥ 3.10 or set `PYTHON` to its executable path.
- Doctor fails on missing `server/.env.local` → run `bun run setup:env` or copy from `server/.env.example`.
- `cd web && bun run doctor` rejects empty/invalid `AGENT_BACKEND_URL` → ensure the URL is `http://` or `https://`.
- `verify:web:api` fails on a new route → extend `web/scripts/verify-api-contracts.ts` to cover it.
Expand Down
3 changes: 2 additions & 1 deletion docs/ai/L1/03_code_map.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ ARCHITECTURE.md # Top-level environment model
AGENTS.md # Contributor entry point
CLAUDE.md # Pointer to AGENTS.md
LICENSE
scripts/run.mjs # Cross-platform root command runner for setup/dev/doctor/clean

web/ # Next.js 16 app (workspace member)
app/
Expand Down Expand Up @@ -70,7 +71,7 @@ server/ # Python FastAPI backend

| File | Purpose |
| --------------------------------------------------- | ------------------------------------------------------------------------ |
| `package.json` (root) | `concurrently`-driven dev orchestration; every workflow script. |
| `package.json` (root) | `concurrently`-driven dev orchestration; delegates cross-platform workflow steps to `scripts/run.mjs`. |
| `web/next.config.ts` | Rewrites `/api/*` to `${AGENT_BACKEND_URL}/...` when env is set. |
| `web/src/services/api.ts` | Browser API client: `getConfig`, `startAgent`, `stopAgent`. |
| `web/src/components/LandingPage.tsx` | Session bootstrap, RTM login, renewal handler, provider wiring. |
Expand Down
5 changes: 3 additions & 2 deletions docs/ai/L1/04_conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
| -------------- | -------------------------------------------------------------------------------------- |
| Python format | None enforced in-repo. Match existing style; `ruff`/`black` are not configured. |
| Python verify | `py_compile` over `server/src/*.py` (`bun run verify:backend`). |
| Python deps | `pip install -r server/requirements.txt` inside `server/venv` (created by `bun run setup:backend`). |
| Python deps | `pip install -r server/requirements.txt` inside `server/venv` (created by `bun run setup:backend`; Windows uses `python` / `py -3`). |
| TypeScript | `strict: true` in `web/tsconfig.json`; path alias `@/* → ./src/*`. |
| Linter | Biome (`web/biome.json`); `noExplicitAny` off, `useExhaustiveDependencies` off. |
| Format | Biome (`bun run lint:fix` writes). |
| JS orchestration | bun (root `package.json` `concurrently`, `bun --filter web …`). |
| JS orchestration | bun (root `package.json` `concurrently`, `scripts/run.mjs`, `bun --filter web …`). |

There is **no ESLint config file** in `web/` — Biome is the only TS/JS linter.

Expand Down Expand Up @@ -68,6 +68,7 @@ There is **no ESLint config file** in `web/` — Biome is the only TS/JS linter.
- Components: PascalCase `.tsx` (e.g. `ConversationComponent.tsx`).
- UI primitives: lowercase under `ui/` (e.g. `ui/button.tsx`).
- Scripts: kebab-case (`verify-api-contracts.ts`, `verify-local-fastapi.ts`).
- Root orchestration scripts stay in `scripts/run.mjs` when they need filesystem, env-var, venv, or process-spawn behavior that must work on Windows and POSIX.
- Python modules: snake_case (`server.py`, `agent.py`, `run_fake_server.py`).

## Module Discipline
Expand Down
4 changes: 2 additions & 2 deletions docs/ai/L1/05_workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ bun run verify:local # full chain including backend + fastapi + proxy + b
```bash
bun run dev
# concurrently {
# dev:backend → python3 server/src/server.py
# dev:frontend → cd web && AGENT_BACKEND_URL=http://localhost:8000 bun run dev
# dev:backend → scripts/run.mjs creates/reuses server/venv and runs server/src/server.py
# dev:frontend → scripts/run.mjs starts web with AGENT_BACKEND_URL=http://localhost:8000
# }
```

Expand Down
4 changes: 4 additions & 0 deletions docs/ai/L1/07_gotchas.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

`bun run dev` always exports `AGENT_BACKEND_URL=http://localhost:8000`. Deploy hosts must set it manually.

## Root Scripts Are Cross-Platform

Root `package.json` scripts must not rely on POSIX-only commands such as `bash`, `test`, `source`, `rm -rf`, or `python3`. Put filesystem, venv, environment-variable, and process-spawn logic in `scripts/run.mjs` so `bun run dev`, setup, doctor, verify, and clean keep working on Windows PowerShell/cmd as well as POSIX shells.

## No `web/app/api/**/route.ts`

`web/scripts/verify-api-contracts.ts` asserts that no `app/api` route handlers exist. The web client must be rewrite-only. Adding a Next route handler would:
Expand Down
6 changes: 3 additions & 3 deletions docs/ai/L1/L2/verification_scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Purpose: exercise the **real FastAPI app** locally, with a `FakeAgent` substitut

What it does:

1. Spawns `python3 server/scripts/run_fake_server.py`, which:
1. Spawns `server/scripts/run_fake_server.py` with the `server/venv` Python (`bin/python` on Unix, `Scripts/python.exe` on Windows), which:
- Imports `server.src.server` so the `app` and `agent` module-level singleton exist.
- Replaces `server_module.agent` with a `FakeAgent` instance.
- Runs `uvicorn.run(app, ...)` on a known port.
Expand All @@ -62,7 +62,7 @@ This is the closest CI gets to a full integration test. It never makes outbound

## `py_compile` Verification

`bun run verify:backend` runs `python3 -m py_compile server/src/server.py server/src/agent.py`. It catches:
`bun run verify:backend` runs `scripts/run.mjs verify:backend`, which uses the venv Python when present or a system Python fallback to compile `server/src/server.py` and `server/src/agent.py`. It catches:

- Syntax errors.

Expand Down Expand Up @@ -90,7 +90,7 @@ It does **not** execute module imports, load env, or catch logic regressions. Pa
| `verify-api-contracts` fails on "app/api should not exist" | Someone added a Next route handler — remove it. |
| `verify-local-proxy` hangs on `fetch` | Fake server failed to start; check the script's stderr. |
| `verify-local-fastapi` errors on import | `Agent.__init__` failed (env missing or SDK import error). |
| `verify-backend` reports a syntax error | Run `python3 -m py_compile` directly on the offending file. |
| `verify-backend` reports a syntax error | Run `bun run verify:backend` or `python -m py_compile` directly on the offending file. |

## See Also

Expand Down
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,30 @@
"scripts": {
"dev": "bun run dev:check && concurrently -n backend,frontend -c blue,green \"bun run dev:backend\" \"bun run dev:frontend\"",
"dev:check": "bun run setup:env && bun run setup:deps",
"dev:backend": "cd server && bash -c '(venv/bin/python -m pip --version >/dev/null 2>&1 || (rm -rf venv && python3 -m venv venv)) && source venv/bin/activate && python -m pip install -q -r requirements.txt && python src/server.py'",
"dev:frontend": "cd web && AGENT_BACKEND_URL=http://localhost:8000 bun run dev",
"backend": "cd server && source venv/bin/activate && python src/server.py",
"frontend": "cd web && AGENT_BACKEND_URL=http://localhost:8000 bun run dev",
"dev:backend": "bun scripts/run.mjs dev:backend",
"dev:frontend": "bun scripts/run.mjs dev:frontend",
"backend": "bun scripts/run.mjs dev:backend",
"frontend": "bun scripts/run.mjs dev:frontend",
"setup": "bun run setup:env && bun run setup:backend && bun run setup:frontend && bun run setup:done",
"setup:env": "test -f server/.env.local || (cp server/.env.example server/.env.local && echo '\nCreated server/.env.local. Add Agora credentials before running the app.')",
"setup:deps": "test -d node_modules || (echo 'Installing workspace dependencies...' && bun install)",
"setup:backend": "cd server && rm -rf venv && python3 -m venv venv && source venv/bin/activate && python -m pip install --upgrade pip && PIP_INDEX_URL=https://pypi.org/simple python -m pip install -r requirements.txt",
"setup:env": "bun scripts/run.mjs setup:env",
"setup:deps": "bun scripts/run.mjs setup:deps",
"setup:backend": "bun scripts/run.mjs setup:backend",
"setup:frontend": "bun install",
"setup:done": "echo '\n✅ Setup complete! Next steps:' && echo ' 1. Run: agora project env write server/.env.local' && echo ' 2. Run: bun run dev\n'",
"doctor": "bash -c 'set -e; echo \"Checking shared repo prerequisites...\"; command -v bun >/dev/null && echo \"- bun available\" || { echo \"- bun not found\"; exit 1; }; test -d node_modules && echo \"- workspace dependencies installed\" || { echo \"- root node_modules missing; run bun install\"; exit 1; }'",
"doctor:local": "bash -c 'set -e; bun run doctor; command -v python3 >/dev/null && echo \"- python3 available\" || { echo \"- python3 not found\"; exit 1; }; test -f server/.env.local && echo \"- server/.env.local present\" || { echo \"- missing server/.env.local\"; exit 1; }; grep -Eq \"^AGORA_APP_ID=.+$\" server/.env.local && echo \"- AGORA_APP_ID configured\" || { echo \"- AGORA_APP_ID missing in server/.env.local\"; exit 1; }; grep -Eq \"^AGORA_APP_CERTIFICATE=.+$\" server/.env.local && echo \"- AGORA_APP_CERTIFICATE configured\" || { echo \"- AGORA_APP_CERTIFICATE missing in server/.env.local\"; exit 1; }'",
"setup:done": "bun scripts/run.mjs setup:done",
"doctor": "bun scripts/run.mjs doctor",
"doctor:local": "bun scripts/run.mjs doctor:local",
"build": "cd web && bun run build",
"verify": "bun run verify:web",
"verify:local": "bun run doctor:local && bun run verify:backend && bun run verify:local:fastapi && bun run verify:web:proxy && bun run verify:web:build",
"verify:local:fastapi": "cd web && bun run scripts/verify-local-fastapi.ts",
"verify:backend": "cd server && python3 -m py_compile src/server.py src/agent.py",
"verify:backend": "bun scripts/run.mjs verify:backend",
"verify:web": "bun run doctor && bun run verify:web:api && bun run verify:web:build",
"verify:web:api": "cd web && bun run scripts/verify-api-contracts.ts",
"verify:web:proxy": "cd web && bun run scripts/verify-local-proxy.ts",
"verify:web:build": "cd web && bun run build",
"clean": "bun run clean:backend && bun run clean:frontend",
"clean:backend": "rm -rf server/venv server/__pycache__ server/src/__pycache__",
"clean:frontend": "rm -rf node_modules web/node_modules web/.next web/dist"
"clean:backend": "bun scripts/run.mjs clean:backend",
"clean:frontend": "bun scripts/run.mjs clean:frontend"
},
"devDependencies": {
"concurrently": "^8.2.2"
Expand Down
Loading
Loading