cduss's picture
Upload folder using huggingface_hub
3389a05 verified
|
Raw
History Blame Contribute Delete
3.7 kB
---
title: Minimal Conversation JS Static
emoji: 🎙️
colorFrom: indigo
colorTo: purple
sdk: static
pinned: false
hf_oauth: true
short_description: Static port of the minimal JS voice chat (Reachy Mini).
tags:
- reachy_mini
- reachy_mini_js_app
---
# Minimal Conversation (JS) — static build
A **`sdk: static`** port of [`tfrere/minimal-conversation`](https://huggingface.co/spaces/tfrere/minimal-conversation)
(originally a `sdk: docker` Space). Same app, no container, no nginx, no
entrypoint script — just the Vite production build served as files.
This is an **investigation** Space: does the conversation app run as a
pure static Space with **no server-side proxy**? Conclusion: **yes.**
Three things the Docker variant used a server for turn out to be
unnecessary on a static Space:
1. **HF OAuth client ID.** The Docker variant patched
`__OAUTH_CLIENT_ID__` into `index.html` from a container env var at
start-up (`docker-entrypoint.d/10-inject-hf-vars.sh`). On a static
Space, HF injects `window.huggingface.variables` (incl.
`OAUTH_CLIENT_ID`) into the `<head>` automatically when
`hf_oauth: true` is set — the SDK host shell reads it directly.
2. **OpenAI ephemeral-key minting.** `src/ephemeral-key.ts` POSTs the
visitor's HF token to the Pollen website
(`…pollen-robotics-reachy-mini.hf.space/api/openai/ephemeral`)
straight from the browser. That endpoint's CORS is origin-reflecting,
so this origin is accepted with no allow-list change. The master
`OPENAI_API_KEY` stays in the website Space's secrets.
3. **OpenAI Realtime SDP call.** The Docker variant routed this through
an nginx `/openai/` reverse-proxy because OpenAI exposes no CORS for
personal `sk-` keys. But this app authenticates with short-lived
`ek_…` ephemeral keys, and OpenAI's `POST /v1/realtime/calls` returns
`Access-Control-Allow-Origin: *` for those — so the browser calls
`https://api.openai.com/v1/realtime/calls` directly. `src/openai-realtime.ts`
was changed from the `/openai/...` same-origin path to the direct URL
(overridable via `VITE_OPENAI_REALTIME_URL`).
So there is **no backend**. The browser talks to: Reachy Mini central
(robot signaling, via the SDK), the Pollen website (ephemeral key mint),
and OpenAI Realtime (SDP handshake + WebRTC voice tunnel).
> **Must be public.** A *private* static Space can't be loaded in the
> `huggingface.co` Spaces iframe wrapper: its `hf_jwt` auth cookie is
> SameSite-blocked in the cross-origin iframe, so assets come back as
> `401 text/plain` and the module is refused. Public has no such cookie
> requirement.
## How it's built
```bash
npm install
npm run build # → dist/ (this Space is the contents of dist/)
```
The source lives in the upstream `tfrere/minimal-conversation` repo
(plus the one-line `openai-realtime.ts` change above). This Space holds
only the built artifacts + this README. To update, rebuild and
re-upload `dist/`.
## Architecture (unchanged from upstream)
```
┌────────┐ robot mic ┌────────┐ input track ┌───────────┐
│ Reachy │ ────────────► │ Browser│ ──────────► │ OpenAI │
│ Mini │ │ (this │ │ Realtime │
│ daemon │ ◄──────────── │ app) │ ◄────────── │ API │
└────────┘ robot speaker └────────┘ output track └───────────┘
```
## License
MIT for the glue code (same as upstream). Underlying SDKs keep their own
licenses.