refactor(frontend): rename project to s2s-frontend
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
# Vocero React frontend
|
||||
|
||||
React 19, TypeScript, Tailwind CSS 4, and Vite 8 client for the existing
|
||||
`s2s-client` FastAPI backend. This is a client-side application with React-owned
|
||||
rendering and state, including the realtime WebSocket and audio integration.
|
||||
|
||||
## Run during development
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
| 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 |
|
||||
|
||||
`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 `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.
|
||||
|
||||
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 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.
|
||||
|
||||
## 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 `s2s-frontend`
|
||||
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 s2s-frontend
|
||||
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
|
||||
closes microphone tracks, worklets, sockets, queue tickets, timers, and pending
|
||||
requests on session stop or page exit.
|
||||
|
||||
## Checks and commands
|
||||
|
||||
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 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. 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
|
||||
|
||||
- `src/components/`: voice controls, chat, dialogs, profile, and account views.
|
||||
- `src/realtime/`: session lifecycle, observable application state, queue and
|
||||
budget handling, WebSocket protocol, tools, and external reasoning.
|
||||
- `src/audio/`: TypeScript capture/playback worklets, audio graph, PCM codec,
|
||||
and visualizer. Vite emits the worklets as separate JavaScript assets.
|
||||
- `src/lib/`: validated backend contracts, settings, prompt context, profile
|
||||
and report presentation, Markdown sanitization, and conversation exports.
|
||||
- `config/backend-proxy.ts`: the shared HTTP/WebSocket development proxy.
|
||||
- `src/styles.css`: Tailwind integration and React-specific layout adjustments.
|
||||
- `src/styles/legacy-theme.css`: the existing visual styles, retained for
|
||||
fidelity to both the white microphone and dark orb themes. The UI is ported
|
||||
to React; the full design has not been rewritten as Tailwind utilities.
|
||||
|
||||
The current Spanish interface, local preference keys, session-only RAG,
|
||||
Markdown replies, JSON/TXT exports, optional browser wake word, TALK/TALKFIRST
|
||||
startup modes, and optional backend features are retained. Camera controls and
|
||||
quick actions remain absent, matching their disabled state in the old UI.
|
||||
|
||||
Native speech stays at the current project's 16 kHz PCM rate. The backend
|
||||
continues to own VAD, transcription, model inference, synthesis, upstream
|
||||
credentials, and ApiPilot execution. Browser `SpeechSynthesis` is used only
|
||||
when the configured external reasoning service returns an answer instead of
|
||||
`log_only`.
|
||||
|
||||
## References
|
||||
|
||||
- [Vite getting started](https://vite.dev/guide/)
|
||||
- [Vite server and proxy options](https://vite.dev/config/server-options)
|
||||
- [Vite features and asset handling](https://vite.dev/guide/features)
|
||||
- [Tailwind's Vite integration](https://tailwindcss.com/docs/installation/using-vite)
|
||||
Reference in New Issue
Block a user