docs(dev): explain the combined Vite and FastAPI launcher
This commit is contained in:
+80
-41
@@ -6,48 +6,84 @@ rendering and state, including the realtime WebSocket and audio integration.
|
||||
|
||||
## Run during development
|
||||
|
||||
Use Node.js 22.18 or later on the 22.x line, or Node.js 24+. Install dependencies
|
||||
with npm; the lockfile is committed.
|
||||
From the repository root, run `./start_ui.sh`. Open `http://localhost:8420`.
|
||||
Add `?debug=true` to access settings, tools, and custom RAG context. Existing
|
||||
`phoneNumber` and `episode_id` query parameters are supported.
|
||||
|
||||
1. Start the existing backend using `./start_ui.sh` from your configured S2S
|
||||
checkout, or reuse an already-running instance. It normally listens on port
|
||||
`8420` and continues serving the original static UI there. Its Python
|
||||
environment, `.env`, speech service, and upstream services must be configured
|
||||
as before.
|
||||
2. In a second terminal, start this frontend:
|
||||
The launcher requires Python 3 with venv support, Node.js 22.18 or later on the
|
||||
22.x line or Node.js 24+, npm, Bash 4.4+, `setsid` (util-linux), and `curl`.
|
||||
It creates `.venv` and installs missing Python dependencies. It runs
|
||||
`npm ci --include=dev` on first start and when either frontend package manifest
|
||||
changes. Subsequent restarts reuse the installed dependencies.
|
||||
|
||||
```sh
|
||||
cd frontend-s2s
|
||||
npm ci
|
||||
npm run dev
|
||||
```
|
||||
| Server | Default address | Purpose |
|
||||
| ------- | ---------------- | ---------------------------------------------- |
|
||||
| Vite | `0.0.0.0:8420` | Public React UI, backend proxy, and hot reload |
|
||||
| FastAPI | `127.0.0.1:8421` | Internal HTTP APIs and speech WebSocket relay |
|
||||
|
||||
3. Open `http://127.0.0.1:5173`. Add `?debug=true` to access settings, tools,
|
||||
and custom RAG context. Existing `phoneNumber` and `episode_id` query
|
||||
parameters are supported.
|
||||
`UI_PORT` preserves the existing public port override. `UI_HOST` defaults to
|
||||
`0.0.0.0`; `S2S_BACKEND_PORT` changes the loopback backend port. The two ports
|
||||
must differ. Occupied ports fail startup rather than silently selecting a new
|
||||
endpoint. The launcher waits for FastAPI before starting Vite, stops both
|
||||
process groups on Ctrl+C/SIGTERM, and exits with a failure if either server exits.
|
||||
Uvicorn watches only `s2s-client`, avoiding frontend and dependency directories.
|
||||
The Vite child explicitly uses `NODE_ENV=development`, including when a process
|
||||
manager sets `NODE_ENV=production`, so React Fast Refresh remains enabled.
|
||||
|
||||
Vite serves React and Tailwind with hot updates. It proxies `/api`,
|
||||
`/v1/realtime` (including WebSockets), OAuth, and backend documentation routes
|
||||
to FastAPI. The browser uses one origin on port `5173`, so there is no separate
|
||||
to FastAPI. The browser uses one origin on port `8420`, so there is no separate
|
||||
API origin or development CORS setup. The proxy preserves the incoming Host
|
||||
header because FastAPI uses it to construct the speech WebSocket URL.
|
||||
|
||||
For a different backend, copy `.env.example` to `.env.local` and set
|
||||
`S2S_BACKEND_URL`. This is a **Vite server** setting. Runtime UI flags, voices,
|
||||
reasoning mode, prompts, and the speech URL still come from FastAPI's
|
||||
Runtime UI flags, voices, reasoning mode, prompts, and the speech URL still come from FastAPI's
|
||||
`/api/config`. A backend explicitly configured with `SPEECH_TO_SPEECH_URL`
|
||||
continues to return that direct speech endpoint.
|
||||
|
||||
The Vite configuration reads only this project's environment files. Do not
|
||||
copy the repository's backend secrets into this directory or into `VITE_*`
|
||||
The launcher sources the root `.env`, retaining its precedence over shell
|
||||
variables. The Vite configuration reads this project's environment files and
|
||||
the inherited `S2S_*` settings. Do not copy the repository's backend secrets
|
||||
into this directory or into `VITE_*`
|
||||
variables, which are exposed to browser code.
|
||||
|
||||
For access through a development reverse proxy, set the exact hostname in
|
||||
`S2S_DEV_ALLOWED_HOSTS`. Use `npm run dev -- --host 0.0.0.0` only when Vite must
|
||||
listen beyond localhost. The browser needs HTTPS for microphone access outside
|
||||
localhost, and that proxy must forward WebSocket upgrades for both speech and
|
||||
Vite HMR. Wiring the staging entrypoint and launcher is a separate step:
|
||||
**this port does not change `start_ui.sh`.**
|
||||
## Staging with hot reload
|
||||
|
||||
PM2 can continue running the root `start_ui.sh` as its existing `s2s_ui` process.
|
||||
Ensure the Node/npm versions above are on PM2's PATH and deploy `frontend-s2s`
|
||||
alongside `s2s-client` and `docs`. The reverse proxy still targets port `8420`.
|
||||
|
||||
Set the exact public hostname in the root `.env`, without scheme or port:
|
||||
|
||||
```dotenv
|
||||
S2S_DEV_ALLOWED_HOSTS=voice-staging.example.com
|
||||
```
|
||||
|
||||
Replace the example with the existing staging hostname; use commas for multiple
|
||||
hosts. IP addresses and localhost are accepted without this setting.
|
||||
The HTTPS reverse proxy must preserve `Host`, `X-Forwarded-Host` and
|
||||
`X-Forwarded-Proto`, and forward WebSocket upgrades for `/v1/realtime` and
|
||||
`/__vite_hmr`. HMR uses the browser's public origin, including HTTPS/WSS, so no
|
||||
second public port is needed. The browser needs HTTPS for microphone access
|
||||
outside localhost. Restart `s2s_ui` after changing launcher or environment
|
||||
settings; source edits use the reloaders. The speech service remains separately
|
||||
managed.
|
||||
|
||||
## Run the servers separately
|
||||
|
||||
Start FastAPI on `127.0.0.1:8421` as described in the
|
||||
[client usage guide](../docs/client/usage.md), then run:
|
||||
|
||||
```sh
|
||||
cd frontend-s2s
|
||||
npm ci
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Standalone Vite binds `127.0.0.1:8420`; add `-- --host 0.0.0.0` for remote
|
||||
access. For a different backend, copy `.env.example` to `.env.local` and set
|
||||
`S2S_BACKEND_URL`. The combined launcher overrides that setting to point at the
|
||||
backend it starts. Do not start standalone Vite while the combined launcher
|
||||
already owns the public port.
|
||||
|
||||
Component and CSS changes use Fast Refresh. Editing the session controller or
|
||||
audio modules can require restarting a conversation or a page reload. Teardown
|
||||
@@ -60,26 +96,29 @@ The scripts and code style follow `frontend-admin` conventions, with Vite and
|
||||
React plugins replacing Next.js-specific tooling. Executable configuration
|
||||
files use TypeScript; TypeScript's own project settings use JSON.
|
||||
|
||||
| Command | Purpose |
|
||||
| -------------------- | ----------------------------------------------------------- |
|
||||
| `npm run dev` | Vite development server on port 5173, with a fixed port |
|
||||
| `npm run check` | Formatting, strict typed ESLint, type checking, and tests |
|
||||
| `npm run lint:fix` | Apply ESLint fixes |
|
||||
| `npm run format` | Format source and sort Tailwind classes |
|
||||
| `npm run typecheck` | Check application, tests, audio worklets, and configuration |
|
||||
| `npm test` | Run Vitest and React Testing Library regression tests |
|
||||
| `npm run test:watch` | Watch tests while editing |
|
||||
| `npm run build` | Typecheck and compile the app and worklets into `dist/` |
|
||||
| `npm run preview` | Inspect the compiled output locally |
|
||||
| Command | Purpose |
|
||||
| ----------------------- | ----------------------------------------------------------- |
|
||||
| `npm run dev` | Vite development server on port 8420, with a fixed port |
|
||||
| `npm run check` | Formatting, strict typed ESLint, type checking, and tests |
|
||||
| `npm run lint:fix` | Apply ESLint fixes |
|
||||
| `npm run format` | Format source and sort Tailwind classes |
|
||||
| `npm run typecheck` | Check application, tests, audio worklets, and configuration |
|
||||
| `npm test` | Run Vitest and React Testing Library regression tests |
|
||||
| `npm run test:watch` | Watch tests while editing |
|
||||
| `npm run test:launcher` | Test launcher supervision and signal handling on Linux |
|
||||
| `npm run build` | Typecheck and compile the app and worklets into `dist/` |
|
||||
| `npm run preview` | Inspect the compiled output locally |
|
||||
|
||||
No build step is needed before `npm run dev`. `dist/` is generated and ignored
|
||||
by Git. Build output is available for later serving integration; this change
|
||||
does not mount it in FastAPI or change the staging launch process.
|
||||
by Git. The launcher serves source through Vite; it does not use `dist/` or
|
||||
`vite preview`.
|
||||
|
||||
Tests cover session initialization, response sequencing, cumulative transcripts,
|
||||
interruptions, queue cancellation, microphone-permission cancellation, tool
|
||||
results, external reasoning and `LOG_ONLY`, late-response cleanup, the idle
|
||||
timeout, settings, RAG, profiles, and sanitized Markdown/export behavior.
|
||||
Launcher tests start temporary local children to check readiness, environment
|
||||
forwarding, failures, and shutdown of complete process groups.
|
||||
Vitest handles Node 26's experimental web storage behavior internally.
|
||||
|
||||
## Source layout
|
||||
|
||||
Reference in New Issue
Block a user